是时候了解一下UILayoutGuide了

作者: 没故事的卓同学 | 来源:发表于2017-01-03 01:28 被阅读5134次

    UILayoutGuide是 iOS 9 中增加的帮助开发者在使用auto layout布局时的一个虚拟占位对象。

    先来看一个在布局时可能碰到的一个场景:有两个等宽的按钮,这两个按钮中间的空隙与它们到左边、右边边缘的距离相等。这样用auto layout要怎么做呢?



    约束中有相等的约束,但是并没有margin相等的约束,显然我们无法直接通过配置约束达到需求。

    一种很常见的思路就是把边距转换为一个占位的View,这样就可以设置相等的属性了。但是这个View要设置成hidden,不应该被用户看到。这样一来我们就可以设置这三个虚拟的View宽度相等,再依次设置他们的leading、trailing约束就可以达到所要的结果了。

    也有一种情况:两个控件,需要两个成组后居中。这种情况下我们也会引入一个View,把这两个控件加入到这个容器View中,再设置容器View的居中。

    但是这样为了辅助布局的View有一个让人难受的地方:它在View的层级里,在事件路由的时候还是会收到消息。这就是UILayoutGuide想要解决的问题。UILayoutGuide可以被添加到View中,和View一样可以设置各种约束,参与布局。但是它不会被渲染出来,不会响应事件路由。也可以像box一样直接包含一些View。

    下面直接用代码演示一下如何把两个控件设置居中。使用的是Snapkit做约束,没有使用原生的蹩脚API。

    首先我们先初始化两个View和一个LayoutGuide。

            let label = UILabel()
            label.text = "UILabel"
            view.addSubview(label)
            
            let testView = UIView()
            testView.backgroundColor = UIColor.cyan
            view.addSubview(testView)
            
            let container = UILayoutGuide()
            view.addLayoutGuide(container)
    

    LayoutGuide被添加进View使用的是<code> addLayoutGuide </code>方法。
    接着我们设置label、testView和container的边缘相连接,并且它们之间有20的offset。

            label.snp.makeConstraints { (make) in
                make.left.equalTo(container)
                make.centerY.equalTo(container)
            }
            
            testView.snp.makeConstraints { (make) in
                make.left.equalTo(label.snp.right).offset(20)
                make.height.equalTo(40)
                make.width.equalTo(120)
                make.right.equalTo(container)
                make.centerY.equalTo(container)
            }
    

    这么一来,container的宽度就等于两个view的宽度加上20的offset。两个view的centerY和container一致。我们接着设置container的约束就可以了:

          container.snp.makeConstraints { (make) in
                make.height.equalTo(5)
                make.center.equalTo(view)
            }
    

    运行起来就能达到目的了:

    所有需要一个虚拟View帮助的事情都可以交给UILayoutGuide来做。它更轻量、更快速、更高效。UILayoutGuide并没有真正的创建一个View,只是创建了一个矩形空间,只在进行auto layout时参与进来计算。

    最后再提醒一遍,这是 iOS 9 的新特性。
    愿上帝保佑那些还要支持 iOS 7 的孩子。

    欢迎关注我的微博:@没故事的卓同学

    相关文章

      网友评论

      • 枫叶砂:这个也可以用stackView布局吧
      • waynett2016:代码为什么不直接设置距离呢?复杂了
      • seasonZhu:这个好像不支持OC吧,我在OC里使用Masonry不行。一会试试swift
        9313dbd1bf65:官方文档就是OC的
        没故事的卓同学:@叆叇云逝 没试过Masonry
      • BetrayalPromise:楼主好 equalTo函数接受的是ConstraintRelatableTarget类型参数 UILayoutGuide是继承NSObject类型 参数类型不匹配的 请问楼主这个是Snapkit的最新版本的改动 还是 其他的原因呢?
        没故事的卓同学:@BetrayalPromise 看我后天晚上直播。地址在最近一篇博客。
      • swiftCoder:snp.makeConstraints { (make) in
        make.height.equalTo(5)
        make.center.equalTo(view)
        } 这一段用的什么 我怎么敲不出来?
        没故事的卓同学:@woshishc snapkit
        swiftCoder:我说的那个snp.makeConstraints这里是不是什么第三方的东西?我也是swift3,敲不出来这两个方法啊
        没故事的卓同学:@woshishc swift 3
      • _光明未来_:文章不错,make 当作名字好奇怪啊
        _光明未来_:@康彪 大虫这个词有老虎的意思,但是你会用吗?没有人把make这么用
        六阿哥:make
        vt. 做; 制造; 被制造
        做出, 制定, 产生
        使, 使得
        获得, 挣得
        总计, 等于
        成为, 使成为
        到达
        准备; 整理
        认为; 估计
        vi. 开始; 试图
        行进, 趋向
        增长起来
        n. 制造, 样式, 牌子, 类型
        体格; 气质

        哪里奇怪了
      • 魔法猛男:sb equal width 可以设置以一个为基础的比例等分
      • _寒小文_: :wink: 最低也要iOS8了
      • songzhou:还要保佑支持 iOS 8 的孩子
      • HideOnBush:最后一句啥意思? :disappointed_relieved:
      • 西门吹雪秦:StoryBoard 里面用不了UILayoutGuide 么?
        西门吹雪秦:@没故事的卓同学 多谢。 :+1:
        没故事的卓同学:@旧轩 忘记说了,只能代码加。
      • zyg: :+1:

      本文标题:是时候了解一下UILayoutGuide了

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