由一次裝那啥而引發的對AutoLayout探究

jopen 9年前發布 | 10K 次閱讀 iOS開發 移動開發 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

來源:葉孤城___的簡書

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!