由一次装那啥而引发的对AutoLayout探究

jopen 9年前

由一次装那啥而引发的对AutoLayout探究

事情是这样的.我下午六点左右的时候没事干,去楼下闲逛,看见我的好基友chun同学在写一个界面,大概是这样的.

由一次装那啥而引发的对AutoLayout探究

这个界面看起来很简单对吧.黄色的是一个view,红色的,是一个label.下面还有一个UIImageView.

但实际上这个界面搭配上他的业务需求就麻烦了.

因为这个界面所有的内容都是活的.

也就是说,你的button,红色的label,黄色的view都有可能不存在.那么,拉约束实际上就不是很好啦了.

但是当时我并不知道,我在问chun:"感觉这页面不难啊,怎么做了这么久".然后chun同学问我觉得多久能做完?

我说:"不超过两个小时,现在没什么界面能让我两个小时做不出来".其实我当时想说:不超过半个钟头的,但是觉得那么说太装b了.就说了两个小时,事实证明,两个小时救了我.

后来我听了需求之后,顿时感觉SB了.不好做啊.

赶快谷歌一下,直到看到了stackoverflow上的这个回答.

由一次装那啥而引发的对AutoLayout探究

我举个例子来说明一下他的思路.

由一次装那啥而引发的对AutoLayout探究

看这张图,现在的棕色方块的有一个约束是依赖与红色方块的,那么如果红色方块这时候因为业务需求需要消失,如果我们直接hidden的话,约束依然存在,导致棕色方块并不会到上面去.

而我们直接remove掉红色方块的话,棕色方块又会因为缺少约束(因为如果你remove掉红色方块,那么中间的那个vertical constraint也会被删掉),整个布局直接乱套.

所以,stackoverflow的意思就是,既然删掉红色view会导致棕色方块缺少一个约束,那我们直接给棕色方块额外增加一个与父view之间的约束不就可以了?

由一次装那啥而引发的对AutoLayout探究

这个思路是行得通的,只要把额外的那个约束的priority改成low.那么在两个约束同时存在的话iOS会选择priority高的那个(也就是与红色关联的那个约束).

我确实这么做了.但我忘记了,cell是要reuse的.我remove了其中一个view之后,直接闪退了.因为当tableview 重用了我删掉了一个view的cell之后,崩溃了.

那么,要考虑另一种不删除就能解决的方法,其实很简单.就是hidden掉我们不想要的view的同时,更改priority的值.看下面一段代码.

import UIKit  class MyCustomTableViewCell: UITableViewCell {      @IBOutlet weak var imageToLabel: NSLayoutConstraint!      @IBOutlet weak var imageToSuperVertical: NSLayoutConstraint!      @IBOutlet weak var imageToProgressVertical: NSLayoutConstraint!      @IBOutlet weak var myImageView: UIImageView!      @IBOutlet weak var mylabel: UILabel!      @IBOutlet weak var mButton: UIButton!      @IBOutlet weak var progressView: UIView!      override func awakeFromNib() {          super.awakeFromNib()          // Initialization code      }      func setImageToProgress(){          mylabel.hidden = true          imageToLabel.priority =  750          imageToSuperVertical.priority = 750          if imageToProgressVertical.priority != 1000          {              imageToProgressVertical.priority = 1000          }      }      func setImageToSuper(){          mylabel.hidden = true          progressView.hidden = true          imageToLabel.priority =  750          imageToProgressVertical.priority = 750          if imageToSuperVertical.priority != 1000          {              imageToSuperVertical.priority = 1000          }      }      override func setSelected(selected: Bool, animated: Bool) {          super.setSelected(selected, animated: animated)          // Configure the view for the selected state      }  }

简单来说就是我们会给一个view同时拉多个同样的vertical约束,可能一个是跟父view的vertical约束,可能是跟另一个view的vertical约束,那么我们会根据server端返回的数据来决定使用哪个约束,hidden掉哪个view.完全满足了我们的需求.

  func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {          var customCell:MyCustomTableViewCell = tableView.dequeueReusableCellWithIdentifier("customCell") as! MyCustomTableViewCell          customCell.mylabel.text = "this is a test"          customCell.myImageView.image = UIImage(named: "niujiao.jpg")          if indexPath.row == 1{             // customCell.setImageToProgress()              customCell.setImageToSuper()          }          return customCell      }

上面的代码是我用来测试的.我们看看效果.

由一次装那啥而引发的对AutoLayout探究

注意第二个cell,我设置imageView与父view的vertical constraint的priority最高,降低了本来和红色label的约束的priority.so,现在imageView选择了与父view的约束.搞定!

我看了一下时间,7:59,哈哈.装b成功.

我把代码上传到了这里:https://github.com/zangqilong198812/TestConstraint

来源:叶孤城___的简书