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

作者: 350fee9655f0 | 来源:发表于2015-07-07 01:18 被阅读2753次

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

效果:

xt.gif

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

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

Snip20150706_20.png

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

Snip20150706_21.png

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

Snip20150706_22.png

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

Snip20150706_24.png

终于到最后一个UIImageView了,同样的能确定的是heightrightleft以及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应该通过子控件以外的其他控件来计算

相关文章

网友评论

  • 87e912b47ff4:最后一步那个辅助约束没看懂,求解释
  • 加斯加的猿:个人认为这样的方法并不可取:
    //添加在scrollView的父控件
    [self.view addSubview:self.centreView];
    这个方法会被调用多次,我觉得应该有更简单的实现。
    讲一个思路:可以通过获取偏移量来计算需要悬的 view 的 topCons
    //获取偏移量
    CGFloat offsetY = scrollView.contentOffset.y;
    if (offsetY>=imageH) {
    self.topConstraint.constant = offsetY - imageH;
    }else{
    self.topConstraint.constant = 0;
    }
    FlyTheKite:@加斯加的猿 好
  • 叫你一声女神你敢不敢应:向上拉的时候中间的view消失了,不知道哪里适配有问题_(:зゝ∠)_
    FlyTheKite:@叫你一声女神你敢不敢应 我也是
  • XX同学://悬停在位置
    centreFrame.origin.y = 0;
    怎么这个改成什么都没用呢?求指教
  • 5e324af757a8:我是新手,反复倒腾了一天,结果都是不行,真是晕了。
  • 1111e57bf6c6:亲测,可以使用,我觉得你把hidden悬停的canstant的值,设置为需要悬停的view的高度会更完美。
  • 1111e57bf6c6:亲测。并没有用。运行一团糟
  • 5e5e8fcdf42d: :+1: 学习,学习!楼主可不可以再写一篇用masonry布局的呢,下面有多个TableView时要怎样实现这种悬停效果呢?
  • ljhblue:这么牛逼 强
  • CoderAO:才发现原来我第一条评论打错了,我想说的是我的方法比较耗,打成比较好了,汗...
  • CoderAO:@小沐的写字台 scrollviewDidScroll方法调用太频繁,悬停控件约束只能remake不能update,总觉得太消耗了,昨天一直想怎么比较省,没想出来,哈哈
  • 350fee9655f0:@CoderAO 只有一个的话这种方式还可以,如果有多个的话应该还是用masonry方便些
  • CoderAO:很好,我是用masonry重新布局了一下,感觉比较好,这种方法好像好点
  • 我是乔忘记疯狂:玩的不错!😀

本文标题:iOS开发之基于AotoLayout的控件悬停

本文链接:https://www.haomeiwen.com/subject/xybyqttx.html