动画特效三:搜索动画

本节我们看看搜索动画,,也就是点击所搜框,上面的导航或者标题栏会被“顶”上去。先看看效果图。

业务描述:

1. 点击搜索框,上面的标题栏会被“顶”上去,同时会显示遮罩效果。

2. 然后你点击遮罩层或者“Cancel”按钮,标题栏又被弹回来。

大家也许会感觉到奇怪,这个动画效果,用UIView的block动画,实现起来并不困难。但这并不是本节讲述的重要。我这里的UI布局,是基于autolayout的;所以这里的动画是对约束的操作,并不是对frame的操作。基于此动画,我也会延伸讲解一下autolayout实现的基本原理。

一、UI布局。

上面的UI元素全都是使用autolayout布局。而本节中的动画效果其实就是针对NavView执行的动画。它的约束列表如下:

观察动画效果:我们可以发现,此动画其实就是将NavView推出父View并且推动的距离就是NavView自己的高度。所以我们可以连线 "Top Space to: Superview"这个约束,然后对其进行动画操作。约束连线代码如下:

@property (weak, nonatomic) IBOutlet NSLayoutConstraint *navTop;

二、动画效果分析。

1. 先看看SearchBar部分的动画效果(注意到SearchBar获取焦点后,"Cancel" 按钮文字颜色变了,并且边框有了颜色)

边框颜色其实很简单,就是来回切换SearchBar的背景图片。

而“Cancel”按钮文字颜色则有点复杂,UISearchBar的文字颜色,你通过设置color等相关属性是不起作用的。其实它本身属于UIBarButtonItem范畴,所以我们可以通过改变appearance来达到目的。而且初始化的代码只需要执行一次,所以可以将代码放在initialize方法中,代码如下:

+ (void)initialize {UIBarButtonItem *item = [UIBarButtonItem appearance];NSMutableDictionary *attrs = [NSMutableDictionary dictionary];attrs[NSForegroundColorAttributeName] = [UIColor colorWithRed:77/255.0 green:179/255.0 blue:179/255.0 alpha:1];[item setTitleTextAttributes:attrs forState:UIControlStateNormal];NSMutableDictionary *attrsDisabled = [NSMutableDictionary dictionary];attrsDisabled[NSForegroundColorAttributeName] = [UIColor grayColor];[item setTitleTextAttributes:attrsDisabled forState:UIControlStateDisabled];}2. 标题栏往上“顶”的动画效果。

即应该实现SearchBar的代理方法,完成动画。

-(void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar {//[searchBar becomeFirstResponder];// 边框颜色searchBar.backgroundImage= [UIImage imageNamed:@"bg_login_textfield_hl"];// cancel 文字(它其实是UIBarButtonItem,所以要显示它,必须进行相印的设置(如字体颜色),在 + (void)initialize方法中)[searchBar setShowsCancelButton:YES animated:YES];self.navTop.constant = -62;[UIView animateWithDuration:0.25 animations:^{// 执行约束动画[self.view layoutIfNeeded];self.cover.alpha = 0.4;}];}观察约束动画与frame动画的不同点(frame动画是将最终动画结束的值放在UIView的block代码中,而约束动画是将约束最终改变的值事先赋值好,然后再执行动画)。

三、iOS中自动布局流程及相关方法

注意到:上面强制执行动画的代码是[self.view layoutIfNeeded].下面我就相关的几个方法及autolayout自动布局过程进行说明。

1、layoutSubviews在iOS5.1和之前的版本,此方法的缺省实现不会做任何事情(实现为空),iOS5.1之后(iOS6开始)的版本,此方法的缺省实现是使用你设置在此view上面的constraints(Autolayout)去决定subviews的position和size。 UIView的子类如果需要对其subviews进行更精确的布局,则可以重写此方法。只有在autoresizing和constraint-based behaviors of subviews不能提供我们想要的布局结果的时候,我们才应该重写此方法。可以在此方法中直接设置subviews的frame。 我们不应该直接调用此方法,而应当用下面两个方法。而关于layoutSubviews的使用,我在《UICollectionView详解五:瀑布流》中也介绍过,可以实现横屏与竖屏的切换来到达在不同情况下,显示的瀑布流的列数不一致。

2、setNeedsLayout此方法会将view当前的layout设置为无效的,并在下一个upadte cycle里去触发layout更新。

3、layoutIfNeeded使用此方法强制立即进行layout,从当前view开始,此方法会遍历整个view层次(包括superviews)请求layout。因此,调用此方法会强制整个view层次布局。基于约束的的方法:1、setNeedsUpdateConstraints当一个自定义view的某个属性发生改变,并且可能影响到constraint时,需要调用此方法去标记constraints需要在未来的某个点更新,系统然后调用updateConstraints.

2、needsUpdateConstraintsconstraint-based layout system使用此返回值去决定是否需要调用updateConstraints作为正常布局过程的一部分。

3、updateConstraintsIfNeeded立即触发约束更新,自动更新布局。

每一发奋美文努力的背后,必有加倍的赏赐。

动画特效三:搜索动画

相关文章:

你感兴趣的文章:

标签云: