转载

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

由一次装那啥而引发的对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

正文到此结束
Loading...