IOS 自定义布局当中的坑

OlaCarbone 8年前
   <p>蛮久没有写文章了,最近在公司也是在赶项目,本周已经接近尾声了,终于可以把在开发项目遇到的坑和积累的经验写一下啦,也算是年后的第一篇文章啦。</p>    <p>小编在项目正式开发的过成当中用到一些视图为了方便使用还是会比较多的使用xib + autolayout来自定义一些控件或者布局。</p>    <p>简单的自动布局小编就不说了,google一下。大把文章教你自定义布局,小编讲一下自定义布局当中的坑。</p>    <p>首先简单的一个项目入手,例如小编想要一个View里的控件实现如下图的布局。这种应该是开发当中比较多用到的一种基本布局</p>    <p><img src="https://simg.open-open.com/show/a8115bceed7fad7415870e55716e6aac.png"></p>    <p>实现某SuperView里有一个子View。子View要距离父View顶部100,左右各20,底部100,子View的高度自适应。</p>    <p>okay,看到约束这么明显,是不是开始窃喜了。。上手就做。上下左右约束添加完毕后,添加高的约束。完成约束后。然后代码设置子View的高度,然而发现并没有什么卵用。</p>    <pre>  <code class="language-objectivec">#import "ViewController.h"  #import "UIView+GFExtension.h"    @interface ViewController ()  @property (weak, nonatomic) IBOutlet UIView *redView;  @property (weak, nonatomic) IBOutlet UITextView *textView;    @end    @implementation ViewController    - (void)viewDidLoad {      [super viewDidLoad];      // Do any additional setup after loading the view, typically from a nib.      self.redView.height = 10.0;//然并卵的一句话  }    @end</code></pre>    <p>对自动布局稍微了解一些的会添加子View的height的约束。然后关联到ViewController.如图</p>    <p><img src="https://simg.open-open.com/show/92627f16e36822c43d6ca39e10c6938b.png"></p>    <p>这时候代码如下,</p>    <pre>  <code class="language-objectivec">@interface ViewController ()  @property (weak, nonatomic) IBOutlet UIView *redView;  @property (weak, nonatomic) IBOutlet UITextView *textView;  @property (weak, nonatomic) IBOutlet NSLayoutConstraint *redViewHeight;    @end    @implementation ViewController    - (void)viewDidLoad {      [super viewDidLoad];      // Do any additional setup after loading the view, typically from a nib.      self.redViewHeight.constant = 10.0;  }    @end</code></pre>    <p>这时候运行项目,看到非但没有解决问题,反倒在控制台多出了一些警告信息。</p>    <pre>  <code>imultaneously satisfy constraints.   Probably at least one of the constraints in the following list is one you don't want.    Try this:     (1) look at each constraint and try to figure out which you don't expect;     (2) find the code that added the unwanted constraint or constraints and fix it.   (      "<NSLayoutConstraint:0x7fc6d9c167e0 V:[UIView:0x7fc6d9c17190(10)]>",      "<NSLayoutConstraint:0x7fc6d9c20950 V:[_UILayoutGuide:0x7fc6d9c1f4b0]-(100)-[UIView:0x7fc6d9c17190]>",      "<NSLayoutConstraint:0x7fc6d9c209f0 V:[_UILayoutGuide:0x7fc6d9c1f4b0]-(286)-[UITextView:0x7fc6db808c00'Lorem ipsum dolor sit er ...']>",      "<NSLayoutConstraint:0x7fc6d9c20a90 V:[UIView:0x7fc6d9c17190]-(108)-[UITextView:0x7fc6db808c00'Lorem ipsum dolor sit er ...']>"  )    Will attempt to recover by breaking constraint   <NSLayoutConstraint:0x7fc6d9c167e0 V:[UIView:0x7fc6d9c17190(10)]>    Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.  The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.</code></pre>    <p>其实透过警告信息,我们可以看到约束冲突,什么问题呢。问题就是你设置了上下左右的约束之后,然后又增大了子View的高度,这不是扯淡嘛。那到底怎么改变redView的高度呢。</p>    <p>在ios自动布局当中其实可以设置autolayout的优先级的。可能大家较多人都没注意到这个选项,如图</p>    <p><img src="https://simg.open-open.com/show/7974ec3474b7a14d3129e7e64f3b220c.png"></p>    <p>一共分为三个优先级,1000,750,250。那 C ontent Hugging Priority & content Compression Resistance Priority 又是什么呢。简单解释一下</p>    <p>contentHugging: 抱住使其在“内容大小”的基础上不能继续变大 </p>    <p>contentCompression: 撑住使其在在其“内容大小”的基础上不能继续变小<br> 这两个属性分别可以设置水平方向和垂直方向上的,而且一个默认优先级是250, 一个默认优先级是750. 因为这两个很有可能与其他Constraint冲突,所以优先级较低。<br> 解决方法</p>    <p>既然知道了优先级这个问题,那我们开始看一下哪几个约束冲突了,我们需要动态设置高度,所以竖直方向上约束冲突,然后我们查看一下竖直方向上的约束信息。</p>    <p>距离顶部100 优先级1000</p>    <p>距离底部100 优先级1000</p>    <p>高度78 优先级1000</p>    <p><img src="https://simg.open-open.com/show/371af7788d0c0e5e3fd377934ccffd9a.png"></p>    <p>因为我们需要动态设置高度。所以高度的优先级应该相对其他两个应该高一些。设置1000.距离底部优先级设置成750.运行代码。效果如下图</p>    <p><img src="https://simg.open-open.com/show/a3aa3a44e1ee979486c19aa7c04f8358.png"></p>    <p>左边为storyBoard。右边为模拟器。所以高度为10设置完成。当更改了底部的优先级之后,可以观察到距离底部的实线变成虚线。</p>    <p>应用:</p>    <p>讲了上面的小demo,下面就是应用了。简单说一下应用场景,当我们在一个textView想显示文本的时候,文本内容不确定,这时候就需要动态设置textView的高度了。</p>    <p>方法跟刚刚一样。代码如下</p>    <pre>  <code class="language-objectivec">//  //  ViewController.m  //  autoLayout01  //  //  Created by goofygao on 5/7/16.  //  Copyright © 2016 goofyy. All rights reserved.  //    #import "ViewController.h"  #import "UIView+GFExtension.h"  #import <UIKit/UIKit.h>    @interface ViewController ()  @property (weak, nonatomic) IBOutlet UIView *redView;  @property (weak, nonatomic) IBOutlet UITextView *textView;  @property (weak, nonatomic) IBOutlet NSLayoutConstraint *redViewHeight;  @property (weak, nonatomic) IBOutlet NSLayoutConstraint *textViewHeight;    @end    @implementation ViewController    - (void)viewDidLoad {      [super viewDidLoad];      // Do any additional setup after loading the view, typically from a nib.      self.redViewHeight.constant = 10.0;      self.textView.text = @"床前明月光,疑是地上霜,举头望明月,低头思故乡";      CGSize sizeToTextViewFitSize = [self.textView sizeThatFits:CGSizeMake(self.textView.width, self.textView.height)];      self.textViewHeight.constant = sizeToTextViewFitSize.height;  }    @end</code></pre>    <p>出来效果如图。根据模拟器Color Blended Layer看效果图如下</p>    <p><img src="https://simg.open-open.com/show/ba8aa6119d0c8ea933821af23716696c.png"></p>    <p>代码地址:https://github.com/mgoofyy/BlogSource</p>    <p>来自: http://www.goofyy.com/blog/ios-autolayout高级01/</p>