2016-02-01 48 views
2

我注意到當我以編程方式更新自動佈局約束時,當旋轉屏幕時所有更改都會恢復。在設備旋轉時保持自動佈局約束處於活動狀態

重現問題:

  1. 寬度等於superview.width(乘數1)活性
  2. 寬度等於superview.width(乘數:

    用的UIView和2個約束
    • 基本故事板接口1/2)disabled

  • 創建並鏈接th ese 2 IBOutlet的限制

  • 以編程方式禁用第一個約束並啓用第二個約束。
  • 旋轉設備,第一個約束處於活動狀態,第二個約束處於禁用狀態。
  • 看起來像一個bug給我。

    您認爲如何?

    屏幕截圖:

    故事板: enter image description here

    約束#1:

    enter image description here

    約束#2:

    enter image description here

    +0

    你使用故事板嗎?它看起來像大小類行爲。 – kedzia

    +0

    是的,我使用故事板,但所有尺寸類別都啓用了約束。我沒有任何大小類特定的配置。 – Salah

    +0

    我會盡量設置他們,因爲你想他們是旋轉大小類 – kedzia

    回答

    5

    大小級

    安裝是指尺寸等級的安裝,不活性/非活動

    您必須以編程方式創建另一個約束,並激活/取消激活之一。這是因爲您無法更改約束的乘數(Can i change multiplier property for NSLayoutConstraint?),也無法修改大小類別(activateConstraints: and deactivateConstraints: not persisting after rotation for constraints created in IB)。

    有幾種方法可以做到這一點。在下面的示例中,我使用乘數或1/2創建約束的x1的副本。然後我在兩者之間切換:

    @IBOutlet var fullWidthConstraint: NSLayoutConstraint! 
    var halfWidthConstraint: NSLayoutConstraint! 
    
    override func viewDidLoad() { 
        super.viewDidLoad() 
        // Do any additional setup after loading the view, typically from a nib. 
        halfWidthConstraint = NSLayoutConstraint(item: fullWidthConstraint.firstItem, 
         attribute: fullWidthConstraint.firstAttribute, 
         relatedBy: fullWidthConstraint.relation, 
         toItem: fullWidthConstraint.secondItem, 
         attribute: fullWidthConstraint.secondAttribute, 
         multiplier: 0.5, 
         constant: fullWidthConstraint.constant) 
        halfWidthConstraint.priority = fullWidthConstraint.priority 
    } 
    
    @IBAction func changeConstraintAction(sender: UISwitch) { 
        if sender.on { 
         NSLayoutConstraint.deactivateConstraints([fullWidthConstraint]) 
         NSLayoutConstraint.activateConstraints([halfWidthConstraint]) 
        } else { 
         NSLayoutConstraint.deactivateConstraints([halfWidthConstraint]) 
         NSLayoutConstraint.activateConstraints([fullWidthConstraint]) 
        } 
    } 
    

    測試在的iOS 9+的Xcode 7+

    +0

    謝謝,我不知道「已安裝」僅適用於尺寸類別。 要明確一點,當我通過編程創建一個約束時,它被默認分配給所有大小類? – Salah

    +1

    以編程方式創建的約束應用於所有大小類。啓用/禁用它們需要額外的努力:http://stackoverflow.com/a/27289658/218152 – SwiftArchitect

    0

    您可以使用通過IB爲尺寸等級創建的約束進行必要的切換。訣竅是將摺疊狀態保持在變量中,並在您的按鈕事件上更新約束,同時也會在特徵集合更改事件上更新約束。

    var collapsed: Bool { 
        didSet { 
         view.setNeedsUpdateConstraints() 
        } 
    } 
    
    @IBAction func onButtonClick(sender: UISwitch) { 
        view.layoutIfNeeded() 
        collapsed = !collapsed   
        UIView.animate(withDuration: 0.3) { 
         view.layoutIfNeeded() 
        } 
    } 
    
    override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { 
        super.traitCollectionDidChange(previousTraitCollection) 
        view.setNeedsUpdateConstraints() 
    } 
    
    override func updateViewConstraints() { 
        constraint1.isActive = !collapsed 
        constraint2.isActive = collapsed 
        super.updateViewConstraints() 
    }