Files
ResearchKit/ResearchKitActiveTask/Front Facing Camera/ORKFrontFacingCameraStepContentView.m
Pariece McKinney b14e5cfcb0 Public Release 3.0
2024-03-28 19:39:04 -04:00

579 lines
25 KiB
Objective-C

/*
Copyright (c) 2020, Apple Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
3. Neither the name of the copyright holder(s) nor the names of any contributors
may be used to endorse or promote products derived from this software without
specific prior written permission. No license is granted to the trademarks of
the copyright holders even if such marks are included in this software.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#import "ORKFrontFacingCameraStepContentView.h"
#import "ORKUnitLabel.h"
#import "ORKHelpers_Internal.h"
#import "ORKSkin.h"
#import "ORKBorderedButton.h"
#import "ORKTitleLabel.h"
#import "ORKBodyLabel.h"
#import "ORKIconButton.h"
#import "ORKStepHeaderView_Internal.h"
#import <AVFoundation/AVFoundation.h>
@interface ORKFrontFacingCameraStepOptionsView : UIVisualEffectView
@property (nonatomic, strong) ORKIconButton *reviewVideoButton;
@property (nonatomic, strong) ORKIconButton *deleteAndRetryVideoButton;
@property (nonatomic, strong) UIButton *submitVideoButton;
@end
@implementation ORKFrontFacingCameraStepOptionsView {
NSMutableArray *_constraints;
ORKTitleLabel *_titleLabel;
}
- (instancetype)initWithEffect:(UIVisualEffect *)effect {
self = [super initWithEffect:effect];
if (self) {
[self setupSubviews];
[self setUpConstraints];
}
return self;
}
- (void)drawRect:(CGRect)rect {
self.layer.cornerRadius = 10.0;
self.layer.maskedCorners = kCALayerMinXMinYCorner | kCALayerMaxXMinYCorner;
self.clipsToBounds = YES;
}
- (void)setupSubviews {
_titleLabel = [ORKTitleLabel new];
_titleLabel.translatesAutoresizingMaskIntoConstraints = NO;
_titleLabel.textAlignment = NSTextAlignmentLeft;
_titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
[_titleLabel setTextColor:[UIColor whiteColor]];
_titleLabel.text = ORKLocalizedString(@"FRONT_FACING_CAMERA_REVIEW_OPTIONS_TITLE", nil);
[self.contentView addSubview:_titleLabel];
UIImage *reviewButtonIcon = [UIImage systemImageNamed:@"video.fill"];
_reviewVideoButton = [[ORKIconButton alloc] initWithButtonText:ORKLocalizedString(@"FRONT_FACING_CAMERA_REVIEW_VIDEO", nil) buttonIcon: reviewButtonIcon];
_reviewVideoButton.tag = 0;
_reviewVideoButton.translatesAutoresizingMaskIntoConstraints = NO;
[self.contentView addSubview:_reviewVideoButton];
UIImage *deleteAndRetryButtonIcon = [UIImage systemImageNamed:@"trash.fill"];
_deleteAndRetryVideoButton = [[ORKIconButton alloc] initWithButtonText:ORKLocalizedString(@"FRONT_FACING_CAMERA_RETRY_VIDEO", nil) buttonIcon: deleteAndRetryButtonIcon];
_deleteAndRetryVideoButton.tag = 1;
_deleteAndRetryVideoButton.translatesAutoresizingMaskIntoConstraints = NO;
[_deleteAndRetryVideoButton updateTextAndImageColor:[UIColor redColor]];
[self.contentView addSubview:_deleteAndRetryVideoButton];
_submitVideoButton = [UIButton new];
_submitVideoButton.tag = 2;
_submitVideoButton.translatesAutoresizingMaskIntoConstraints = NO;
_submitVideoButton.layer.cornerRadius = 10.0;
_submitVideoButton.clipsToBounds = YES;
_submitVideoButton.titleLabel.font = [UIFont systemFontOfSize:20.0];
[_submitVideoButton setTitleColor:UIColor.whiteColor forState:UIControlStateNormal];
[_submitVideoButton setBackgroundColor:[UIColor systemBlueColor]];
[_submitVideoButton setTitleEdgeInsets:UIEdgeInsetsMake(5.0, 8.0, 5.0, 8.0)];
[_submitVideoButton setTitle:ORKLocalizedString(@"FRONT_FACING_CAMERA_SUBMIT_VIDEO", nil) forState:UIControlStateNormal];
[self.contentView addSubview:_submitVideoButton];
}
- (void)setUpConstraints {
if (_constraints) {
[NSLayoutConstraint deactivateConstraints:_constraints];
}
_constraints = [NSMutableArray array];
[_constraints addObject: [_titleLabel.topAnchor constraintEqualToAnchor:self.contentView.topAnchor constant:25.0]];
[_constraints addObject: [_titleLabel.leadingAnchor constraintEqualToAnchor:self.contentView.leadingAnchor constant:20.0]];
[_constraints addObject: [_titleLabel.trailingAnchor constraintEqualToAnchor:self.contentView.trailingAnchor constant:-20.0]];
//reviewVideoButton constraints
[_constraints addObject:[_reviewVideoButton.topAnchor constraintEqualToAnchor:_titleLabel.bottomAnchor constant:40.0]];
[_constraints addObject:[_reviewVideoButton.leadingAnchor constraintEqualToAnchor:_titleLabel.leadingAnchor]];
[_constraints addObject:[_reviewVideoButton.trailingAnchor constraintEqualToAnchor:_titleLabel.trailingAnchor]];
[_constraints addObject:[_reviewVideoButton.heightAnchor constraintEqualToConstant:50.0]];
//deleteAndRetryButton constraints
[_constraints addObject:[_deleteAndRetryVideoButton.topAnchor constraintEqualToAnchor:_reviewVideoButton.bottomAnchor constant:15.0]];
[_constraints addObject:[_deleteAndRetryVideoButton.leadingAnchor constraintEqualToAnchor:_titleLabel.leadingAnchor]];
[_constraints addObject:[_deleteAndRetryVideoButton.trailingAnchor constraintEqualToAnchor:_titleLabel.trailingAnchor]];
[_constraints addObject:[_deleteAndRetryVideoButton.heightAnchor constraintEqualToConstant:50.0]];
//submitVideoButton constraints
[_constraints addObject:[_submitVideoButton.leadingAnchor constraintEqualToAnchor:_titleLabel.leadingAnchor]];
[_constraints addObject:[_submitVideoButton.trailingAnchor constraintEqualToAnchor:_titleLabel.trailingAnchor]];
[_constraints addObject:[_submitVideoButton.bottomAnchor constraintEqualToAnchor:self.contentView.safeAreaLayoutGuide.bottomAnchor constant:-20.0]];
[_constraints addObject:[_submitVideoButton.heightAnchor constraintEqualToConstant:50.0]];
[NSLayoutConstraint activateConstraints:_constraints];
}
@end
typedef NS_CLOSED_ENUM(NSInteger, ORKStartStopButtonState) {
ORKStartStopButtonStateStartRecording = 0,
ORKStartStopButtonStateStopRecording,
} ORK_ENUM_AVAILABLE;
@interface ORKBlurFooterView : UIVisualEffectView
- (instancetype)initWithTitleText:(nullable NSString *)titleText detailText:(nullable NSString *)detailText;
@property (nonatomic) UIButton *startStopButton;
@property (nonatomic) ORKStartStopButtonState startStopButtonState;
@property (nonatomic) UILabel *timerLabel;
@end
@implementation ORKBlurFooterView {
NSMutableArray<NSLayoutConstraint *> *_heightConstraints;
NSLayoutConstraint *_blurViewTopConstraint;
NSString *_titleText;
NSString *_detailText;
ORKTitleLabel *_titleLabel;
ORKBodyLabel *_detailTextLabel;
UIButton *_collapseButton;
BOOL _isTextCollapsed;
}
- (instancetype)initWithTitleText:(nullable NSString *)titleText detailText:(nullable NSString *)detailText {
self = [super initWithEffect:[UIBlurEffect effectWithStyle:UIBlurEffectStyleDark]];
if (self) {
_titleText = titleText;
_detailText = detailText;
_isTextCollapsed = NO;
_startStopButtonState = ORKStartStopButtonStateStartRecording;
[self setupSubviews];
[self setupConstraints];
[self setStartStopButtonState:ORKStartStopButtonStateStartRecording];
}
return self;
}
- (void)setupSubviews {
_startStopButton = [UIButton new];
_startStopButton.layer.cornerRadius = 14.0;
_startStopButton.clipsToBounds = YES;
_startStopButton.contentEdgeInsets = (UIEdgeInsets){.left = 6, .right = 6};
UIFontDescriptor *descriptorOne = [UIFontDescriptor preferredFontDescriptorWithTextStyle:UIFontTextStyleHeadline];
_startStopButton.titleLabel.font = [UIFont boldSystemFontOfSize:[[descriptorOne objectForKey: UIFontDescriptorSizeAttribute] doubleValue] + 1.0];
[self.contentView addSubview:_startStopButton];
_timerLabel = [UILabel new];
_timerLabel.font = [UIFont systemFontOfSize:15.0];
_timerLabel.adjustsFontSizeToFitWidth = YES;
[self.contentView addSubview:_timerLabel];
if (_titleText) {
_titleLabel = [ORKTitleLabel new];
_titleLabel.textAlignment = NSTextAlignmentLeft;
_titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
_titleLabel.numberOfLines = 0;
[_titleLabel setTextColor:[UIColor whiteColor]];
_titleLabel.text = _titleText;
[self.contentView addSubview:_titleLabel];
}
if (_detailText) {
_detailTextLabel = [ORKBodyLabel new];
_detailTextLabel.textAlignment = NSTextAlignmentLeft;
_detailTextLabel.lineBreakMode = NSLineBreakByWordWrapping;
_detailTextLabel.numberOfLines = 0;
[_detailTextLabel setTextColor:[UIColor whiteColor]];
_detailTextLabel.text = _detailText ? : @"";
[self.contentView addSubview:_detailTextLabel];
}
if (_titleText || _detailText) {
_collapseButton = [UIButton new];
_collapseButton.translatesAutoresizingMaskIntoConstraints = NO;
[_collapseButton setTintColor:[UIColor whiteColor]];
[_collapseButton setBackgroundImage:[UIImage systemImageNamed:@"chevron.down"] forState:UIControlStateNormal];
[_collapseButton addTarget:self
action:@selector(collapseButtonPressed)
forControlEvents:UIControlEventTouchUpInside];
[self.contentView addSubview:_collapseButton];
}
}
- (void)setupConstraints {
_startStopButton.translatesAutoresizingMaskIntoConstraints = NO;
_timerLabel.translatesAutoresizingMaskIntoConstraints = NO;
_detailTextLabel.translatesAutoresizingMaskIntoConstraints = NO;
_titleLabel.translatesAutoresizingMaskIntoConstraints = NO;
[[_startStopButton.leadingAnchor constraintEqualToAnchor:self.contentView.leadingAnchor constant:20.0] setActive:YES];
[[_startStopButton.trailingAnchor constraintEqualToAnchor:_timerLabel.leadingAnchor constant:-15.0] setActive:YES];
[[_startStopButton.bottomAnchor constraintEqualToAnchor:self.contentView.safeAreaLayoutGuide.bottomAnchor constant:-20.0] setActive:YES];
[[_startStopButton.heightAnchor constraintEqualToConstant:50.0] setActive:YES];
[[_timerLabel.trailingAnchor constraintEqualToAnchor:self.contentView.trailingAnchor constant:-20.0] setActive:YES];
[[_timerLabel.centerYAnchor constraintEqualToAnchor:_startStopButton.centerYAnchor] setActive:YES];
[[_timerLabel.widthAnchor constraintEqualToConstant:40.0] setActive:YES];
if (_titleLabel || _detailTextLabel) {
if (_detailTextLabel) {
[[_detailTextLabel.leadingAnchor constraintEqualToAnchor:_startStopButton.leadingAnchor] setActive:YES];
[[_detailTextLabel.trailingAnchor constraintEqualToAnchor:_timerLabel.trailingAnchor] setActive:YES];
[[_detailTextLabel.bottomAnchor constraintEqualToAnchor:_startStopButton.topAnchor constant:-20.0] setActive:YES];
}
if (_titleLabel) {
[[_titleLabel.leadingAnchor constraintEqualToAnchor:_startStopButton.leadingAnchor] setActive:YES];
[[_titleLabel.trailingAnchor constraintEqualToAnchor:_collapseButton.leadingAnchor constant: -10.0] setActive:YES];
[[_titleLabel.bottomAnchor constraintEqualToAnchor:_detailTextLabel ? _detailTextLabel.topAnchor : _startStopButton.topAnchor constant: -15.0] setActive:YES];
[[_collapseButton.topAnchor constraintEqualToAnchor:_titleLabel.topAnchor] setActive:YES];
_blurViewTopConstraint = [self.contentView.topAnchor constraintEqualToAnchor:_titleLabel.topAnchor constant:-20.0];
} else {
[[_collapseButton.bottomAnchor constraintEqualToAnchor:_detailTextLabel.topAnchor constant:-15.0] setActive:YES];
_blurViewTopConstraint = [self.contentView.topAnchor constraintEqualToAnchor:_collapseButton.topAnchor constant:-20.0];
}
[[_collapseButton.trailingAnchor constraintEqualToAnchor:_timerLabel.trailingAnchor] setActive:YES];
[[_collapseButton.heightAnchor constraintEqualToConstant:25.0] setActive:YES];
[[_collapseButton.widthAnchor constraintEqualToConstant:25.0] setActive:YES];
[_blurViewTopConstraint setActive:YES];
} else {
[[self.contentView.topAnchor constraintEqualToAnchor:_startStopButton.topAnchor constant:-20.0] setActive:YES];
}
}
- (void)setStartStopButtonState:(ORKStartStopButtonState)startStopButtonState
{
_startStopButtonState = startStopButtonState;
if (startStopButtonState == ORKStartStopButtonStateStartRecording)
{
[_startStopButton setTitle:ORKLocalizedString(@"FRONT_FACING_CAMERA_START_TITLE", nil) forState:UIControlStateNormal];
[_startStopButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[_startStopButton setBackgroundColor:self.tintColor];
[_timerLabel setText:ORKLocalizedString(@"FRONT_FACING_CAMERA_START_TIME", nil)];
[_timerLabel setTextColor:[UIColor darkGrayColor]];
}
else
{
[_startStopButton setTitle:ORKLocalizedString(@"FRONT_FACING_CAMERA_STOP_TITLE", nil) forState:UIControlStateNormal];
[_startStopButton setTitleColor:self.tintColor forState:UIControlStateNormal];
[_startStopButton setBackgroundColor:[UIColor systemGrayColor]];
[_timerLabel setTextColor:[UIColor whiteColor]];
}
}
- (void)collapseButtonPressed {
if (_isTextCollapsed) {
[_blurViewTopConstraint setActive:NO];
_blurViewTopConstraint = [self.contentView.topAnchor constraintEqualToAnchor:_titleLabel.topAnchor constant:-20.0];
[_blurViewTopConstraint setActive:YES];
[NSLayoutConstraint deactivateConstraints:_heightConstraints];
_heightConstraints = nil;
} else {
[_blurViewTopConstraint setActive:NO];
_blurViewTopConstraint = [self.contentView.topAnchor constraintEqualToAnchor:_collapseButton.topAnchor constant:-20.0];
[_blurViewTopConstraint setActive:YES];
_heightConstraints = [NSMutableArray new];
[_heightConstraints addObject:[_titleLabel.heightAnchor constraintEqualToConstant:0.0]];
[_heightConstraints addObject:[_detailTextLabel.heightAnchor constraintEqualToConstant:0.0]];
[NSLayoutConstraint activateConstraints:_heightConstraints];
}
UIImage *collapseButtonImage = _isTextCollapsed ? [UIImage systemImageNamed:@"chevron.down"] : [UIImage systemImageNamed:@"chevron.up"];
[_collapseButton setBackgroundImage:collapseButtonImage forState:UIControlStateNormal];
_isTextCollapsed = !_isTextCollapsed;
}
- (void)didMoveToWindow {
self.tintColor = ORKWindowTintcolor(self.window) ? : [UIColor systemBlueColor];
[self setStartStopButtonState:_startStopButtonState];
}
@end
@interface ORKFrontFacingCameraStepContentView ()
@property (nonatomic, copy, nullable) ORKFrontFacingCameraStepContentViewEventHandler viewEventhandler;
@end
@implementation ORKFrontFacingCameraStepContentView {
ORKStepHeaderView *_headerView;
UIView *_cameraView;
AVCaptureVideoPreviewLayer *_previewLayer;
ORKBlurFooterView *_blurFooterView;
NSTimer *_timer;
NSTimeInterval _maxRecordingTime;
CGFloat _recordingTime;
NSDateComponentsFormatter *_dateComponentsFormatter;
ORKFrontFacingCameraStepOptionsView *_optionsView;
NSString *_titleText;
NSString *_bodyText;
}
- (instancetype)initWithTitle:(nullable NSString *)title text:(NSString *)text {
self = [super initWithFrame:CGRectZero];
self.layoutMargins = ORKStandardFullScreenLayoutMarginsForView(self);
if (self) {
self.translatesAutoresizingMaskIntoConstraints = NO;
_titleText = title;
_bodyText = text;
[self setUpSubviews];
[self setUpConstraints];
}
return self;
}
- (void)setUpSubviews {
_cameraView = [UIView new];
_cameraView.alpha = 1.0;
[self addSubview:_cameraView];
_blurFooterView = [[ORKBlurFooterView alloc] initWithTitleText:_titleText detailText:_bodyText];
_blurFooterView.layer.cornerRadius = 10.0;
_blurFooterView.layer.maskedCorners = kCALayerMinXMinYCorner | kCALayerMaxXMinYCorner;
_blurFooterView.clipsToBounds = YES;
[_blurFooterView.startStopButton addTarget:self
action:@selector(startStopButtonPressed)
forControlEvents:UIControlEventTouchUpInside];
[self addSubview:_blurFooterView];
}
- (void)layoutSubviews {
if (_previewLayer && _previewLayer.frame.size.height == 0 && _cameraView.frame.size.height != 0) {
_previewLayer.position = CGPointMake(_cameraView.frame.size.width / 2, _cameraView.frame.size.height / 2);
_previewLayer.bounds = CGRectMake(0, 0, _cameraView.frame.size.width, _cameraView.frame.size.height);
}
}
- (void)setUpConstraints {
_cameraView.translatesAutoresizingMaskIntoConstraints = NO;
_blurFooterView.translatesAutoresizingMaskIntoConstraints = NO;
[[_cameraView.leadingAnchor constraintEqualToAnchor:self.leadingAnchor] setActive:YES];
[[_cameraView.trailingAnchor constraintEqualToAnchor:self.trailingAnchor] setActive:YES];
[[_cameraView.topAnchor constraintEqualToAnchor:self.topAnchor] setActive:YES];
[[_cameraView.bottomAnchor constraintEqualToAnchor:self.bottomAnchor] setActive:YES];
[[_blurFooterView.leadingAnchor constraintEqualToAnchor:_cameraView.leadingAnchor] setActive:YES];
[[_blurFooterView.trailingAnchor constraintEqualToAnchor:_cameraView.trailingAnchor] setActive:YES];
[[_blurFooterView.bottomAnchor constraintEqualToAnchor:_cameraView.bottomAnchor] setActive:YES];
}
- (void)setViewEventHandler:(ORKFrontFacingCameraStepContentViewEventHandler)handler
{
self.viewEventhandler = [handler copy];
}
- (void)invokeViewEventHandlerWithEvent:(ORKFrontFacingCameraStepContentViewEvent)event
{
if (self.viewEventhandler)
{
dispatch_async(dispatch_get_main_queue(), ^{
self.viewEventhandler(event);
});
}
}
- (void)setPreviewLayerWithSession:(AVCaptureSession *)session {
_previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:session];
_previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
_previewLayer.needsDisplayOnBoundsChange = YES;
_previewLayer.connection.videoOrientation = AVCaptureVideoOrientationPortrait;
[_cameraView.layer addSublayer:_previewLayer];
}
- (void)handleError:(NSError *)error
{
[_optionsView removeFromSuperview];
[_cameraView removeFromSuperview];
[_blurFooterView removeFromSuperview];
[_previewLayer removeFromSuperlayer];
_optionsView = nil;
_cameraView = nil;
_blurFooterView = nil;
_previewLayer = nil;
if (_headerView)
{
[_headerView removeFromSuperview];
_headerView = nil;
}
_headerView = [[ORKStepHeaderView alloc] init];
_headerView.instructionLabel.text = error.localizedDescription;
[_headerView setTranslatesAutoresizingMaskIntoConstraints:NO];
[self addSubview:_headerView];
[NSLayoutConstraint activateConstraints:@[
[_headerView.topAnchor constraintEqualToAnchor:self.safeAreaLayoutGuide.topAnchor],
[_headerView.leftAnchor constraintEqualToAnchor:self.safeAreaLayoutGuide.leftAnchor],
[_headerView.rightAnchor constraintEqualToAnchor:self.safeAreaLayoutGuide.rightAnchor],
]];
[self invokeViewEventHandlerWithEvent:ORKFrontFacingCameraStepContentViewEventError];
}
- (void)startStopButtonPressed
{
if (_blurFooterView.startStopButtonState == ORKStartStopButtonStateStartRecording)
{
[_blurFooterView setStartStopButtonState:ORKStartStopButtonStateStopRecording];
[self invokeViewEventHandlerWithEvent:ORKFrontFacingCameraStepContentViewEventStartRecording];
}
else
{
[_blurFooterView setStartStopButtonState:ORKStartStopButtonStateStartRecording];
[self invokeViewEventHandlerWithEvent:ORKFrontFacingCameraStepContentViewEventStopRecording];
[_timer invalidate];
_timer = nil;
}
}
- (void)startTimerWithMaximumRecordingLimit:(NSTimeInterval)maximumRecordingLimit
{
if (_timer) {
[_timer invalidate];
}
_maxRecordingTime = maximumRecordingLimit;
_recordingTime = 0.0;
_timer = [NSTimer scheduledTimerWithTimeInterval:1.0
target:self
selector:@selector(updateRecordingTime)
userInfo:nil
repeats:YES];
}
- (void)updateRecordingTime {
_recordingTime += _timer.timeInterval;
if (_recordingTime >= _maxRecordingTime) {
[_timer invalidate];
[_blurFooterView setStartStopButtonState:ORKStartStopButtonStateStartRecording];
[self invokeViewEventHandlerWithEvent:ORKFrontFacingCameraStepContentViewEventStopRecording];
} else {
_blurFooterView.timerLabel.text = [self formattedTimeFromSeconds:_recordingTime];
}
}
- (NSString *)formattedTimeFromSeconds:(CGFloat)seconds {
if (!_dateComponentsFormatter) {
_dateComponentsFormatter = [NSDateComponentsFormatter new];
_dateComponentsFormatter.zeroFormattingBehavior = NSDateComponentsFormatterZeroFormattingBehaviorPad;
_dateComponentsFormatter.allowedUnits = NSCalendarUnitMinute | NSCalendarUnitSecond | NSCalendarUnitNanosecond;
}
return [_dateComponentsFormatter stringFromTimeInterval:seconds];
}
- (void)presentReviewOptionsAllowingReview:(BOOL)allowReview allowRetry:(BOOL)allowRetry
{
if (allowRetry || allowReview)
{
[self presentOptionsView];
[_optionsView.reviewVideoButton setHidden:!allowReview];
[_optionsView.deleteAndRetryVideoButton setHidden:!allowRetry];
}
}
- (void)presentOptionsView
{
if (_optionsView)
{
[_optionsView removeFromSuperview];
_optionsView = nil;
}
_optionsView = [[ORKFrontFacingCameraStepOptionsView alloc] initWithEffect:[UIBlurEffect effectWithStyle:UIBlurEffectStyleDark]];
_optionsView.translatesAutoresizingMaskIntoConstraints = NO;
[_optionsView.reviewVideoButton addTarget:self
action:@selector(optionsViewButtonPressed:)
forControlEvents:UIControlEventTouchUpInside];
[_optionsView.deleteAndRetryVideoButton addTarget:self
action:@selector(optionsViewButtonPressed:)
forControlEvents:UIControlEventTouchUpInside];
[_optionsView.submitVideoButton addTarget:self
action:@selector(optionsViewButtonPressed:)
forControlEvents:UIControlEventTouchUpInside];
[self addSubview:_optionsView];
[self setupOptionsViewConstraints];
}
- (void)setupOptionsViewConstraints {
[[_optionsView.topAnchor constraintEqualToAnchor:self.topAnchor] setActive:YES];
[[_optionsView.trailingAnchor constraintEqualToAnchor:self.trailingAnchor] setActive:YES];
[[_optionsView.leadingAnchor constraintEqualToAnchor:self.leadingAnchor] setActive:YES];
[[_optionsView.bottomAnchor constraintEqualToAnchor:self.bottomAnchor] setActive:YES];
}
- (void)optionsViewButtonPressed:(UIButton *)button {
if (button) {
if (button.tag == 0) {
//review video
[self invokeViewEventHandlerWithEvent:ORKFrontFacingCameraStepContentViewEventReviewRecording];
} else if (button.tag == 1) {
//delete and redo recording
[self invokeViewEventHandlerWithEvent:ORKFrontFacingCameraStepContentViewEventRetryRecording];
[_optionsView removeFromSuperview];
_optionsView = nil;
} else if (button.tag == 2) {
//submit video
[self invokeViewEventHandlerWithEvent:ORKFrontFacingCameraStepContentViewEventSubmitRecording];
}
}
}
@end