iOS开发之基于AotoLayout的控件悬停

在很多的电商类的APP中我们经常会用到一种滑动悬停的效果,所以这次尝试着利用AutoLayout来实现这种效果。话不多说先上图

效果:

xt.gif

效果上过了,还是理顺下思路上吧。从效果图上不难发现我们的程序是基于UIScrollerView的。界面上的展示同样都是UIScrollView的子控件。当然了难点也就是基于UIScrollerView的内部子控件的布局以及AutoLayout约束的修改。

我们看一下我们的需要的一些基本的控件布局:

iOS开发之基于AotoLayout的控件悬停_第1张图片
Snip20150706_20.png

好了,现在开始开始搭建新的项目了,首先在Storyboard上搭建最基本的布局,并将控件基本布局到相应的位置,以备我们更方便的添加约束。

iOS开发之基于AotoLayout的控件悬停_第2张图片
Snip20150706_21.png

到了这里就开始对我们的控件添加基本的约束了从上开始吧。上面的控件我们能确定是UIImageViewheigth以及topleft以及rihgt。至于bottom到了后面会着重设置的。

iOS开发之基于AotoLayout的控件悬停_第3张图片
Snip20150706_22.png

然后继续来操作悬停的View。这个View因为处在两个view的中间所以我们要暂时确定height以及leftright的约束就足够了了

iOS开发之基于AotoLayout的控件悬停_第4张图片
Snip20150706_24.png

终于到最后一个UIImageView了,同样的能确定的是heightrightleft以及bottom这四项。

iOS开发之基于AotoLayout的控件悬停_第5张图片
Snip20150707_25.png
到了这里针对单个的控件的布局基本完成了,细心的你可能会发现以上的操作都没有进行关联以及没有对width进行约束。那么下面我们就要开始进行三者的关联以及width上的设置。
因为悬停的view处与两个imageView的中间,所以我们只需要对它进行处理就好了
iOS开发之基于AotoLayout的控件悬停_第6张图片
Snip20150707_27.png

其实这两个约束完全是可以在设置悬停view的时候的添加,之所以在这里添加是我们在后面的控制器会用到这两个约束,为了好辨认我们就给他们定义上别名:

Snip20150707_29.png

然后我们按住command选择我们的三个控件然后按住control拖向scrollView的父控件view设置等width

iOS开发之基于AotoLayout的控件悬停_第7张图片
Snip20150707_33.png

好了,到了这里我们的约束已经不会再报错了,然后在逻辑上也是基本是通顺的了,但是对于我们悬停的功能来说就少了关键的一个环节那么就是一旦悬停view悬停了,那么它与上下两个imageView的约束要怎么处理呢?所以我们还需要一个辅助的约束用来悬停之后的关联处理

iOS开发之基于AotoLayout的控件悬停_第8张图片
Snip20150707_34.png

添加之后我们给这个约束起个别名hidden悬停,不过细心的你一定会发现添加之后会sb会提示出有冲突的约束,那么我们只需要对我们刚刚添加的约束进行一下操作就OK了

iOS开发之基于AotoLayout的控件悬停_第9张图片
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应该通过子控件以外的其他控件来计算

你可能感兴趣的:(iOS开发之基于AotoLayout的控件悬停)