在我的应用程序中,我有一个页面视图控制器,允许用户在应用程序的不同“部分”之间滑动,在导航栏的顶部我将标题文本更改为用户已刷到的新部分通过pageViewController:didFinishAnimating:previousViewControllers:transitionCompleted:
。当动画完成时,它当前正在立即更改标题文本。我希望通过一些动画改进这一点,一种微妙的淡入淡出效果。
我首先尝试实现[UIView animationWithDuration:...]
动画更改标题文字,但它不是动画,只是立即更新。
然后我想知道是否有可能更新导航栏标题的alpha,因为用户根据他们滚动的距离水平滚动,当下一部分即将出现在屏幕上时达到0 alpha,然后我可以在0时立即更改文本,然后快速淡入1 alpha。但是我没有在滚动位置更新时看到UIPageViewControllerDelegate
上的方法。
如果可能的话,我不仅可以淡入淡出,还可以在导航栏中移动标题文本位置,就像通过滑动手势从推送segue导航回来时发生的默认动画一样。当用户滚动并在另一侧提供下一部分标题时,我会将旧部分标题滑过,这样当转换完成时,前一部分标题不在屏幕上,新的标题完全居中,因此替换完成。但同样需要确切知道用户滚动页面视图控制器的程度。
是否可以实现任何所需的动画?
答案 0 :(得分:42)
如果要在不同的标题字符串之间设置动画,请使用以下命令:
CATransition *fadeTextAnimation = [CATransition animation];
fadeTextAnimation.duration = 0.5;
fadeTextAnimation.type = kCATransitionFade;
[self.navigationController.navigationBar.layer addAnimation: fadeTextAnimation forKey: @"fadeText"];
self.navigationItem.title = "My new title";
您可以调整持续时间并设置适合的计时功能。
还有其他类型的动画可能在不同情况下起作用(感谢@inorganik):
kCATransitionFade
kCATransitionMoveIn
kCATransitionPush
kCATransitionReveal
答案 1 :(得分:35)
为方便起见,Ashley Mills在Swift中的解决方案:
11/16/2016更新了Swift 3(感谢n13)
let fadeTextAnimation = CATransition()
fadeTextAnimation.duration = 0.5
fadeTextAnimation.type = kCATransitionFade
navigationController?.navigationBar.layer.add(fadeTextAnimation, forKey: "fadeText")
navigationItem.title = "test 123"
Swift 2.x
let fadeTextAnimation = CATransition()
fadeTextAnimation.duration = 0.5
fadeTextAnimation.type = kCATransitionFade
navigationController?.navigationBar.layer.addAnimation(fadeTextAnimation, forKey: "fadeText")
navigationItem.title = "test 123"
我向阿什利倾诉!
答案 2 :(得分:2)
解决方案是使用页面视图控制器的隐藏scrollView的委托方法创建自定义标题并为其位置设置动画。正如张所说,自定义标题只是self.navigationItem.titleView = customNavTitleLabel;
答案 3 :(得分:1)
如果您只需要为标题设置动画(不是整个导航栏)
开发自定义标题控件 example
的链接指定强>
let titleView = UIAnimatedTitleView(frame: CGRect(x: 0, y: 0, width: 200, height: 40))
titleView.text = "Hello"
<强>动画强>
var flag = true
@objc private func animateNavigationTitle() {
guard let titleView = navigationItem.titleView as? UIAnimatedTitleView else { return }
let fadeTextAnimation = CATransition()
fadeTextAnimation.duration = 0.5
fadeTextAnimation.type = kCATransitionPush
fadeTextAnimation.subtype = kCATransitionFromTop
titleView.layer.add(fadeTextAnimation, forKey: "pushText")
titleView.text = flag ? "Hello" : "Good buy"
flag = !flag
}
答案 4 :(得分:0)
找到最好的方法是这个类别:
@implementation UIViewController (ControllerNavigationEffects)
-(void) setNavigationTitleWithAnimation:(NSString *) title {
if ([self.navigationItem.title isEqualToString:title]) {
return;
}
@weakify(self);
float duration = 0.2;
[UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
@strongify(self);
self.navigationItem.titleView.alpha = 0;
} completion:^(BOOL finished) {}];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(duration * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
@strongify(self);
self.navigationItem.titleView = nil;
self.navigationItem.title = title;
[UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
self.navigationItem.titleView.alpha = 1;
} completion:nil];
});
}
-(void) setNavigationTitleViewWithAnimation:(UIView *) titleView {
if ([self.navigationItem.titleView isKindOfClass:[titleView class]]) {
return;
}
@weakify(self);
float duration = 0.2;
CATransition *fadeTextAnimation = [CATransition animation];
fadeTextAnimation.duration = duration;
fadeTextAnimation.type = kCATransitionFade;
[self.navigationController.navigationBar.layer addAnimation: fadeTextAnimation forKey: @"fadeText"];
self.navigationItem.title = @"";
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(duration * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
@strongify(self);
self.navigationItem.title = @"";
self.navigationItem.titleView = titleView;
[UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
self.navigationItem.titleView.alpha = 1;
} completion:nil];
});
}