我可以简单地淡化导航栏的alpha,但是为了允许用户点击新获得的区域(导航栏现在它已经淡出)并让它做某事,我必须做的不仅仅是更改alpha,因为导航栏在技术上仍然占据了区域.
所以我用[self.navigationController setNavigationBarHidden:YES animated:NO];隐藏了导航栏.我必须在动画块完成后执行此操作,否则它将在动画块中并作为块的一部分进行动画处理.所以我使用dispatch_after在动画完成后完成(0.35秒延迟).
然而,这导致了这样的问题:如果用户在0.35秒的时间段内任意时间点动画,并且等待完成,则会导致另一个块开始出现故障行为,即使它还在等待另一个块0.35秒完成.它会导致一些毛病行为并导致导航栏保持隐藏状态.毛.
发生的视频:http://cl.ly/2i3H0k0Q1T0V
这是我的代码,用于演示我正在做的事情:
- (void)hideControls:(BOOL)hidden { self.navigationController.view.backgroundColor = self.view.backgroundColor; int statusBarHeight = [UIApplication sharedApplication].statusBarFrame.size.height; [UIView animateWithDuration:0.35 animations:^{ [[UIApplication sharedApplication] setStatusBarHidden:hidden withAnimation:UIStatusBarAnimationFade]; if (hidden) { self.navigationController.navigationBar.alpha = 0.0; self.instructionsLabel.alpha = 0.0; self.backFiftyWordsButton.alpha = 0.0; self.forwardFiftyWordsButton.alpha = 0.0; self.WPMLabel.alpha = 0.0; self.timeRemainingLabel.alpha = 0.0; } else { self.navigationController.navigationBar.alpha = 1.0; self.instructionsLabel.alpha = 1.0; self.backFiftyWordsButton.alpha = 1.0; self.forwardFiftyWordsButton.alpha = 1.0; self.WPMLabel.alpha = 1.0; self.timeRemainingLabel.alpha = 1.0; } [self.view layoutIfNeeded]; }]; // Perform an "actual" hide (more than just alpha changes) after the animation finishes in order to regain that touch area if (hidden) { double delayInSeconds = 0.35; dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC)); dispatch_after(popTime, dispatch_get_main_queue(), ^(void) { [self.navigationController setNavigationBarHidden:YES animated:NO]; self.textToReadLabelPositionFromTopConstraint.constant = TEXT_LABEL_DISTANCE + self.navigationController.navigationBar.frame.size.height + statusBarHeight; }); } else { [self.navigationController setNavigationBarHidden:NO animated:NO]; self.textToReadLabelPositionFromTopConstraint.constant = TEXT_LABEL_DISTANCE; } }
我正在做的唯一另一件事是更改我的自动布局约束的常量,以考虑导航栏和状态栏,取决于它们是否在那里.
我不确定如何考虑双击可以真正解决整个屏幕过程这一事实.我怎么能这样做,如果他们在动画过程中点击它只会取消动画并按预期执行他们想要的动作?我可以更好地完成这个过程吗?
我认为您可以使用以下原则在不调整任何框架或约束的情况下执1)使窗口的背景颜色与视图相同
2)向窗口添加轻击手势识别器.这允许点击屏幕上的任何位置(当alpha不为0时状态栏除外)导航栏是否可见.这使您无需将导航栏设置为隐藏,这会导致视图调整大小.
3)使用hitTest:在tapper的动作方法中检查用户是否点击了导航栏,如果水龙头在那里则不淡出.
4)在动画块中使用UIViewAnimationOptionBeginFromCurrentState和UIViewAnimationOptionAllowUserInteraction,以便通过另一次触摸可以平滑地反转淡入或淡出.
5)将所有底部控件包含在一个清晰的UIView中,这样你就可以淡出UIView而不是所有单独的控件.
这是有效的代码:
- (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; self.view.window.backgroundColor = self.view.backgroundColor; UITapGestureRecognizer *tapper = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(fadeInFadeOut:)]; [self.view.window addGestureRecognizer:tapper]; } -(void)fadeInFadeOut:(UITapGestureRecognizer *)sender { static BOOL hide = YES; id hitView = [self.navigationController.view hitTest:[sender locationInView:self.navigationController.view] withEvent:nil]; if (! [hitView isKindOfClass:[UINavigationBar class]] && hide == YES) { hide = ! hide; [[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationFade]; [UIView animateWithDuration:.35 delay:0 options:UIViewAnimationOptionBeginFromCurrentState|UIViewAnimationOptionAllowUserInteraction animations:^{ self.navigationController.navigationBar.alpha = 0; self.bottomView.alpha = 0; } completion:nil]; }else if (hide == NO){ hide = ! hide; [[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationFade]; [UIView animateWithDuration:.35 delay:0 options:UIViewAnimationOptionBeginFromCurrentState|UIViewAnimationOptionAllowUserInteraction animations:^{ self.navigationController.navigationBar.alpha = 1; self.bottomView.alpha = 1; } completion:nil]; } }