iOS开发之基于AotoLayout的控件悬停
2015-07-07 本文已影响2753人
350fee9655f0
在很多的电商类的APP中我们经常会用到一种滑动悬停的效果,所以这次尝试着利用AutoLayout来实现这种效果。话不多说先上图
效果:
xt.gif效果上过了,还是理顺下思路上吧。从效果图上不难发现我们的程序是基于UIScrollerView
的。界面上的展示同样都是UIScrollView
的子控件。当然了难点也就是基于UIScrollerView的内部子控件
的布局以及AutoLayout约束
的修改。
我们看一下我们的需要的一些基本的控件布局:
Snip20150706_20.png好了,现在开始开始搭建新的项目了,首先在Storyboard上搭建最基本的布局,并将控件基本布局到相应的位置,以备我们更方便的添加约束。
Snip20150706_21.png到了这里就开始对我们的控件添加基本的约束了从上开始吧。上面的控件我们能确定是UIImageView
的heigth
以及top
、left
以及rihgt
。至于bottom
到了后面会着重设置的。
Snip20150706_22.png
然后继续来操作悬停的View。这个View因为处在两个view的中间所以我们要暂时确定height
以及left
和right
的约束就足够了了
Snip20150706_24.png
终于到最后一个UIImageView了,同样的能确定的是height
、right
、left
以及bottom
这四项。
Snip20150707_25.png
到了这里针对单个的控件的布局基本完成了,细心的你可能会发现以上的操作都没有进行关联以及没有对width
进行约束。那么下面我们就要开始进行三者的关联以及width
上的设置。
因为悬停的view处与两个imageView的中间,所以我们只需要对它进行处理就好了
Snip20150707_27.png其实这两个约束完全是可以在设置悬停view的时候的添加,之所以在这里添加是我们在后面的控制器会用到这两个约束,为了好辨认我们就给他们定义上别名:
Snip20150707_29.png然后我们按住command
选择我们的三个控件然后按住control
拖向scrollView
的父控件view
设置等width
。
Snip20150707_33.png
好了,到了这里我们的约束已经不会再报错了,然后在逻辑上也是基本是通顺的了,但是对于我们悬停的功能来说就少了关键的一个环节那么就是一旦悬停view悬停了,那么它与上下两个imageView的约束要怎么处理呢?所以我们还需要一个辅助的约束用来悬停之后的关联处理
Snip20150707_34.png添加之后我们给这个约束起个别名hidden悬停
,不过细心的你一定会发现添加之后会sb会提示出有冲突的约束,那么我们只需要对我们刚刚添加的约束进行一下操作就OK了
Snip20150707_36.png
好了,到了这里我们在AutoLayout上要做的事情就这些了,下面我们就可以安心的写代码了。
@interface ViewController ()
/**中间的View*/
@property (weak, nonatomic) IBOutlet UIView *centreView;
/**上面的ImageView*/
@property (weak, nonatomic) IBOutlet UIImageView *topImageView;
/**centreView的top约束*/
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *topConstraint;
/**centreView的bottom约束*/
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *bottomConstraint;
/**topImageView暂禁用的约束*/
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *hiddenConstraint;
@end
然后在scrollView的滑动代理方法中实现
- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
//获得top图片的高度
CGFloat imageH = self.topImageView.frame.size.height;
//获取偏移量
CGFloat offsetY = scrollView.contentOffset.y;
//centrView的frame
CGRect centreFrame = self.centreView.frame;
if (offsetY>=imageH) {
//将centreView的向上和向下的约束禁用
self.bottomConstraint.active = NO;
self.topConstraint.active = NO;
//将topImageView与bottomImageView的约束使用关联
self.hiddenConstraint.active = YES;
//悬停在位置
centreFrame.origin.y = 0;
self.centreView.frame = centreFrame;
//添加在scrollView的父控件
[self.view addSubview:self.centreView];
}else{
//添加在topIamgeView的下面
centreFrame.origin.y = imageH;
self.centreView.frame = centreFrame;
[scrollView addSubview:self.centreView];
//记住一定要先添加到scrollView上之后在修改约束的内容,不然添加的约束会不成,因为系统无法建立他们之间的联系。
self.hiddenConstraint.active = NO;
self.topConstraint.active = YES;
self.bottomConstraint.active = YES;
}
//等比例的伸缩
CGFloat scale= 1-(offsetY/60);
scale = (scale>=1)?scale :1;
self.topImageView.transform = CGAffineTransformMakeScale(scale, scale);
}
最后补充:
-
在子控件的尺寸
不能通过UIScrollView
来计算,可以通过以下方式计算- 设置
固定值
(width==100,height==300) - 相对于
UIScrollView以外的其他控件
来计算尺寸
- 设置
-
在UIScrollView里面布局子控件,sb里面默认是是需要
子控件的尺寸
以及子控件与UIScrollView之间的间距
来计算出scroller的conentSize
的。所以这就是上面的子控件要与父控件来等宽的原因了。 -
UIScrollView的
frame
应该通过子控件以外的其他控件
来计算