你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發基礎 >> 由一次裝那啥而引發的對AutoLayout探究

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

編輯:IOS開發基礎

1433993383388939.jpg

事情是這樣的.我下午六點左右的時候沒事干,去樓下閒逛,看見我的好基友chun同學在寫一個界面,大概是這樣的.

1.jpg

這個界面看起來很簡單對吧.黃色的是一個view,紅色的,是一個label.下面還有一個UIImageView.

但實際上這個界面搭配上他的業務需求就麻煩了.

因為這個界面所有的內容都是活的.

也就是說,你的button,紅色的label,黃色的view都有可能不存在.那麼,拉約束實際上就不是很好啦了.

但是當時我並不知道,我在問chun:"感覺這頁面不難啊,怎麼做了這麼久".然後chun同學問我覺得多久能做完?

我說:"不超過兩個小時,現在沒什麼界面能讓我兩個小時做不出來".其實我當時想說:不超過半個鐘頭的,但是覺得那麼說太裝b了.就說了兩個小時,事實證明,兩個小時救了我.

後來我聽了需求之後,頓時感覺SB了.不好做啊.

趕快谷歌一下,直到看到了stackoverflow上的這個回答.

2.jpg

我舉個例子來說明一下他的思路.

3.jpg

看這張圖,現在的棕色方塊的有一個約束是依賴與紅色方塊的,那麼如果紅色方塊這時候因為業務需求需要消失,如果我們直接hidden的話,約束依然存在,導致棕色方塊並不會到上面去.

而我們直接remove掉紅色方塊的話,棕色方塊又會因為缺少約束(因為如果你remove掉紅色方塊,那麼中間的那個vertical constraint也會被刪掉),整個布局直接亂套.

所以,stackoverflow的意思就是,既然刪掉紅色view會導致棕色方塊缺少一個約束,那我們直接給棕色方塊額外增加一個與父view之間的約束不就可以了?

4.jpg

這個思路是行得通的,只要把額外的那個約束的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
    }

上面的代碼是我用來測試的.我們看看效果.

5.jpg

注意第二個cell,我設置imageView與父view的vertical constraint的priority最高,降低了本來和紅色label的約束的priority.so,現在imageView選擇了與父view的約束.搞定!

我看了一下時間,7:59,哈哈.裝b成功.

我把代碼上傳到了這裡:https://github.com/zangqilong198812/TestConstraint

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved