过渡导航栏标题

时间:2014-04-08 15:05:19

标签: ios objective-c animation uinavigationbar transition

在名为“Luvocracy”的应用程序中,当用户在屏幕上向上滑动时,导航栏的标题会发生变化。旧标题被推高,而新标题已经过渡了。我现在没有它的视频,但这里有一些屏幕截图:

https://www.dropbox.com/s/sns0bsxkdv7pw3l/Photo%20Apr%2008%2C%2011%2001%2005%20AM.png

https://www.dropbox.com/s/ys9a49u3dyxrlcm/Photo%20Apr%2008%2C%2011%2001%2009%20AM.png

https://www.dropbox.com/s/dlcfvfvqqov3ag7/Photo%20Apr%2008%2C%2011%2001%2013%20AM.png

如何动画或转换新的导航栏标题如图所示?

修改:应用程序商店中的应用程序不再可用,因此我无法上传此操作的视频。

4 个答案:

答案 0 :(得分:25)

您可以使用CATransition为标题更改设置动画...但是,由于标题本身是导航栏上的私有属性,因此您需要先创建自定义标签并将其附加到导航项。

设置标题标签(这将覆盖默认导航栏的标题):

UILabel *titleLabelView = [[UILabel alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 100.0f, 44.0f) /* auto-sized anyway */];
titleLabelView.backgroundColor = [UIColor clearColor];
titleLabelView.textAlignment = NSTextAlignmentCenter;
titleLabelView.textColor = [UIColor blackColor];
titleLabelView.font = [UIFont systemFontOfSize:16.0f];
titleLabelView.adjustsFontSizeToFitWidth = YES;
titleLabelView.text = @"@cracy123";
self.navigationItem.titleView = titleLabelView;

然后,只要您想要更改标题的动画(假设在滚动视图委托操作中),添加CAAnimation图层并预先设置:

CATransition *animation = [CATransition animation];
animation.duration = 1.0;
animation.type = kCATransitionPush;
animation.subtype = kCATransitionFromTop;
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
[self.navigationItem.titleView.layer addAnimation:animation forKey:@"changeTitle"];

((UILabel*)self.navigationItem.titleView).text = @"JACOB K";

显然,您可以更改CATransition动画属性以获得您之后的效果,但这些属性会为您提供“俯卧撑”功能。效果。

enter image description here

答案 1 :(得分:4)

仅仅因为缺少Swift的答案,这就是Swav对Gavin的回答:

设置自定义标题标签:

let titleLabelView = UILabel.init(frame: CGRect(x: 0, y: 0, width: 0, height: 44))
titleLabelView.backgroundColor = UIColor.clearColor()
titleLabelView.textAlignment = .Center
// this next line picks up the UINavBar tint color instead of fixing it to a particular one as in Gavin's solution
titleLabelView.textColor = UINavigationBar.appearance().tintColor
titleLabelView.font = UIFont.boldSystemFontOfSize(16.0)
titleLabelView.text = "Old Title"
self.navigationItem.titleView = titleLabelView

这是标题动画代码:

let titleAnimation = CATransition()
titleAnimation.duration = 0.5
titleAnimation.type = kCATransitionPush
titleAnimation.subtype = kCATransitionFromTop
titleAnimation.timingFunction = CAMediaTimingFunction.init(name: kCAMediaTimingFunctionEaseInEaseOut)

navigationItem.titleView!.layer.addAnimation(titleAnimation, forKey: "changeTitle")
(navigationItem.titleView as! UILabel).text = "New Title"

// I added this to autosize the title after setting new text
(navigationItem.titleView as! UILabel).sizeToFit()

答案 2 :(得分:3)

这是一个很好的答案,但我做了一些调整才能做到正确。

所以一般的想法是你在scrollView的中间有一个文本,当用户向上滚动该文本时,你希望它成为新的标题。此外,当您向下滚动时,您希望它更改回默认标题。

enter image description here

enter image description here

所以,使用Gix发布的代码,现在转换为Swift 3,这就是你完成它的方法。

将这些变量添加到viewController的顶部

var didChangeTitle = false
let defaultTitle = "Default Title"
let animateUp: CATransition = {
    let animation = CATransition()
    animation.duration = 0.5
    animation.type = kCATransitionPush
    animation.subtype = kCATransitionFromTop
    animation.timingFunction = CAMediaTimingFunction.init(name: kCAMediaTimingFunctionEaseInEaseOut)
    return animation
}()
let animateDown: CATransition = {
    let animation = CATransition()
    animation.duration = 0.5
    animation.type = kCATransitionPush
    animation.subtype = kCATransitionFromBottom
    animation.timingFunction = CAMediaTimingFunction.init(name: kCAMediaTimingFunctionEaseInEaseOut)
    return animation
}()

在viewDidLoad中,添加此代码以设置默认标题。

let titleLabelView = UILabel.init(frame: CGRect(x: 0, y: 0, width: 200, height: 44))
titleLabelView.backgroundColor = .clear
titleLabelView.textAlignment = .center
titleLabelView.textColor = UINavigationBar.appearance().tintColor
titleLabelView.font = UIFont.boldSystemFont(ofSize: 16)
titleLabelView.text = defaultTitle
self.navigationItem.titleView = titleLabelView

现在,您将一些代码添加到scrollView委托函数中:

extension MyViewController: UIScrollViewDelegate {
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        if scrollView.contentOffset.y >= (labelName.frame.origin.y + labelName.frame.height) && !didChangeTitle {
            if let label = navigationItem.titleView as? UILabel {
                label.layer.add(animateUp, forKey: "changeTitle")
                label.text = labelName.text
            }
            didChangeTitle = true
        } else if scrollView.contentOffset.y < labelName.frame.origin.y && didChangeTitle {
            if let label = navigationItem.titleView as? UILabel {
                label.layer.add(animateDown, forKey: "changeTitle")
                label.text = defaultTitle
            }
            didChangeTitle = false
        }
    }
}

“labelName”var是滚动视图中包含未来标题的标签。

答案 3 :(得分:2)

这是一个例子:

UILabel *titleLabelView = [[UILabel alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 100.0f, 100.0f) /* auto-sized anyway */];
titleLabelView.backgroundColor = [UIColor clearColor];
titleLabelView.textAlignment = NSTextAlignmentCenter;

(和其他应用程序)

self.navigationItem.titleView = LabelView;

我不太清楚你的问题!