2017-03-17 92 views
1

前言:我看了一眼this post,它並沒有解決我的問題。這是一個link to a repo,顯示我遇到的錯誤。隱藏嵌套UISTackviews的UIStackView

我有一個UIViewController垂直UIStackView包含嵌套水平UIStackViews

有兩個UIStackViews是切換。如果顯示UIStackViewNumber1,則UIStackViewNumber2隱藏&反之亦然。我最初設置的視圖顯示,但它太擁擠。

UIStackView 
    stackViewThatDoesntMove 
    stackViewNumber1 
    stackViewNumber2 
    stackViewThatDoesntMove 

如果我不隱藏任何東西,一切正常,沒有AutoLayout錯誤。在UIStackViews的每一個嵌套了包含按鈕,標籤,滑塊,等我發現的觀點是太擁擠stackViews,所以我想我會設置隱藏stackViews之一和動畫的變化,具體如下:

stackViewNumber2.isHidden = true 

UIView.animate(withDuration: 0.33, 
       options: [.curveEaseOut], 
       animations: { 
       self.stackViewNumber1.layoutIfNeeded() 
       self.stackViewNumber2.layoutIfNeeded() 
       self.view.layoutIfNeeded() 
        }, 
       completion: nil) 
} 

雖然我在Simulator和物理設備上獲得了期望的結果,但是當我隱藏其中一個UIStackViews時,我的控制檯填滿了AutoLayout錯誤。

我看了一下this post,我的問題看起來很簡單。我採用最少的「簿記」方法,並在UIView中包裝stackViewNumber2。我最終得到的是我原來沒有將stackViewNumber1包含在UIView中的一組錯誤。

我也看了Apple's documentation on UIStackView並試圖玩弄的arrangedSubviews()設置的限制isActive = false,如下:

for subview in stackViewNumber2.arrangedSubviews { 
    for constraint in subview.constraints { 
     constraint.isActive = false 
    } 
} 

stackViewNumber2.updateConstraints() 
// then run animation block to update view 

是否有隱藏嵌套UIStackViews而不用追加用於約束的IBOutlet更有效的方式,使確定它不弱,並且對isActive是否爲true/false做記錄?

我認爲我的問題與嵌套stackViews有關,但我無法弄清楚如何解決它。感謝您的閱讀,我歡迎有關如何隱藏包含嵌套UIStackViewsUIStackView的建議。

+0

更改動畫塊內的隱藏屬性是否有任何不同的效果。如果需要,離開佈局? – agibson007

+0

@ agibson007感謝您的閱讀。不,它沒有任何不同的效果。 – Adrian

+0

嵌套stackviews包含什麼?他們是否在評估內容大小,還是在設定內容?另外什麼是設置垂直持有水平。試圖描繪它,以及可能會有什麼阻礙。而不是取消激活約束,而不是隱藏內部堆棧視圖如果在動畫塊中隱藏這些堆棧視圖的子視圖會發生什麼情況。 – agibson007

回答

2

而不是隱藏我認爲它會更好地刪除堆棧視圖本身。

myStackView.removeArrangedSubview(playButton) 
playButton.removeFromSuperview() 

希望它有幫助。

+1

更清潔,沒有錯誤,沒有簿記!我將在下面發佈我的最終解決方案,主要基於您的解決方案。謝謝! – Adrian

1

我開始想要隱藏一個視圖並取消隱藏另一個視圖,但在Md. Ibrahim Hassan's suggestion處,我嘗試從超級視圖中移除stackViewNumber1,並用stackViewNumber2替換它。最終的結果是更爲乾淨具有最小記賬,沒有拖動bazillion @IBOutlets到的viewController用於更新約束等

parentStackView的意見被存儲在堆棧的在他們顯示在Main.storyboard順序arrangedSubviews()陣列英寸

enter image description here

在這個例子中,arrangedSubviews陣列看起來像這樣:

[topStackView, stackViewNumber1, stackViewNumber2, stopButton]

我只需要知道parentStackViewstackViewNumber1,並stackViewNumber2,所以我拖着3口到故事板如下:

// StackViews the viewController needs to know about... 
@IBOutlet weak var parentStackView: UIStackView! 
// note weak is removed from the following 2 stackViews 
@IBOutlet var stackViewNumber1: UIStackView! 
@IBOutlet var stackViewNumber2: UIStackView! 

Fr OM那裏,如果我想刪除stackViewNumber2,下面的代碼刪除它:

parentStackView.removeArrangedSubview(stackViewNumber2) 
// parentStackView.arrangedSubviews() = [topStackView, stackViewNumber1, stopButton] 
stackViewNumber2.removeFromSuperview() 
parentStackView.insertArrangedSubview(stackViewNumber1, at: 1) 
// parentStackView.arrangedSubviews() = [topStackView, stackViewNumber1, stopButton] 

現在,讓我們說,我要拿出stackViewNumber1,並取代它與stackViewNumber2

parentStackView.removeArrangedSubview(stackViewNumber1) 
// parentStackView.arrangedSubviews() = [topStackView, stopButton] 
stackViewNumber2.removeFromSuperview() 
parentStackView.insertArrangedSubview(stackViewNumber2, at: 1) 
// parentStackView.arrangedSubviews() = [topStackView, stackViewNumber2, stopButton] 

召回stackViewNumber1stackViewNumber2不是weak。原因是我想讓他們周圍,所以我可以交換他們進出。我沒有看到由於將網點更改爲weak而對內存使用造成任何不利影響。

最終結果:我用最初的方法遇到的一系列AutoLayout錯誤沒有了大量的簿記工作。

更新:

隨着多一點修修補補,我有動畫的工作了。代碼如下:

UIView.animate(withDuration: 0.25, 
        delay: 0, 
        usingSpringWithDamping: 2.0, 
        initialSpringVelocity: 10.0, 
        options: [.curveEaseOut], 
        animations: { 
        self.view.layoutIfNeeded() 
    }, 
        completion: nil)