簡體   English   中英

視圖高度意外變化(Swift)

[英]View height changes unexpectedly (Swift)

我已經設置了約束,允許 UIView cv1根據屏幕尺寸動態改變高度,而cv2cv3的高度是固定的。

出於某種原因,當我如圖所示運行時, cv3的視圖高度變為 172。

在一個或另一個或兩者中使用原始的cv3.heightAnchor.constraint(equalToConstant: cv3Height) ,我遇到了與此處相同的問題(對cv2非常有效),附加效果是我用h3, (窄或寬)視圖僅在該方向跳轉到 172,但也給我沖突的約束消息。

我沒有運氣就刪除了所有其他約束。

這是另一個錯誤嗎? 如果是這樣,是否有解決方法?

下面是一個最小化的function,整個function如下:

func setConstraints() {
            
    cv3.translatesAutoresizingMaskIntoConstraints = false

    let g = view.safeAreaLayoutGuide
    
    let cv3Height: CGFloat = 125
    let h3 = cv3.heightAnchor.constraint(equalToConstant: cv3Height)
    h3.priority = .defaultHigh
    
    narrowConstraints = [
        // set cv3 height
        //cv3.heightAnchor.constraint(equalToConstant: cv3Height),
        h3, 

        // lock left, right and bottom to safe area
        cv3.leadingAnchor.constraint(equalTo: g.leadingAnchor),
        cv3(equalTo: g.trailingAnchor),
        cv3(equalTo: g.bottomAnchor),
    ]
    
    wideConstraints = [
        // set cv3 height
        //cv3.heightAnchor.constraint(equalToConstant: cv3Height),
        h3, 

        // lock bottom and right side of cv3 to safe area
        cv3(equalTo: g.trailingAnchor),
        cv3(equalTo: g.bottomAnchor),
        
        // make them all equal widths
        cv2.widthAnchor.constraint(equalTo: cv1.widthAnchor),
        cv3.widthAnchor.constraint(equalTo: cv2.widthAnchor),
    ]

    
    // activate the commonConstraints
    NSLayoutConstraint.activate(commonConstraints)
    
    if view.frame.width > view.frame.height {
        // wider than tall, so "landscape"
        NSLayoutConstraint.deactivate(narrowConstraints)
        NSLayoutConstraint.activate(wideConstraints)
    } else {
        // taller than wide
        NSLayoutConstraint.deactivate(wideConstraints)
        NSLayoutConstraint.activate(narrowConstraints)
    }
    
}

這是整個 function:

func setConstraints() {
    
    cv1.translatesAutoresizingMaskIntoConstraints = false
    cv2.translatesAutoresizingMaskIntoConstraints = false
    cv3.translatesAutoresizingMaskIntoConstraints = false
    
    let g = view.safeAreaLayoutGuide
    
    let cv2Height: CGFloat = 190
    let h2 = cv2.heightAnchor.constraint(equalToConstant: cv2Height)
    h2.priority = .defaultHigh
    
    let cv3Height: CGFloat = 125
    let h3 = cv3.heightAnchor.constraint(equalToConstant: cv3Height)
    h3.priority = .defaultHigh
    
    narrowConstraints = [
        
        // lock top, left and right to safe area
        cv1.topAnchor.constraint(equalTo: g.topAnchor),
        cv1.leadingAnchor.constraint(equalTo: g.leadingAnchor),
        cv1.trailingAnchor.constraint(equalTo: g.trailingAnchor),
        
        // set cv2 height
        //cv2.heightAnchor.constraint(equalToConstant: cv2Height),
        h2,

        // lock left and right to safe area
        cv2.leadingAnchor.constraint(equalTo: g.leadingAnchor),
        cv2.trailingAnchor.constraint(equalTo: g.trailingAnchor),
        
        // lock top of cv2 to bottom of cv1
        cv2.topAnchor.constraint(equalTo: cv1.bottomAnchor),
        // lock bottom of cv2 to top of cv3
        cv2.bottomAnchor.constraint(equalTo: cv3.topAnchor),
        
        // set cv3 height
        //cv3.heightAnchor.constraint(equalToConstant: cv3Height),
        h3, 

        // lock left, right and bottom to safe area
        cv3.leadingAnchor.constraint(equalTo: g.leadingAnchor),
        cv3(equalTo: g.trailingAnchor),
        cv3(equalTo: g.bottomAnchor),
    ]
    
    wideConstraints = [
        
        // lock top, bottom, and left to safe area
        cv1.topAnchor.constraint(equalTo: g.topAnchor),
        cv1.bottomAnchor.constraint(equalTo: g.bottomAnchor),
        cv1.leadingAnchor.constraint(equalTo: g.leadingAnchor),
        // lock right side of cv1 to left side of cv2
        cv1.trailingAnchor.constraint(equalTo: cv2.leadingAnchor),
        
        // lock right side of cv2 to safe area
        cv2.trailingAnchor.constraint(equalTo: g.trailingAnchor),
        // lock top of cv2 to safe area
        cv2.topAnchor.constraint(equalTo: g.topAnchor),
        // lock bottom of cv2 to top of cv3
        cv2.bottomAnchor.constraint(equalTo: cv3.topAnchor),
        
        // set cv3 height
        //cv3.heightAnchor.constraint(equalToConstant: cv3Height),
        h3, 

        // lock bottom and right side of cv3 to safe area
        cv3(equalTo: g.trailingAnchor),
        cv3(equalTo: g.bottomAnchor),
        
        // make them all equal widths
        cv2.widthAnchor.constraint(equalTo: cv1.widthAnchor),
        cv3.widthAnchor.constraint(equalTo: cv2.widthAnchor),
    ]

    
    // activate the commonConstraints
    NSLayoutConstraint.activate(commonConstraints)
    
    if view.frame.width > view.frame.height {
        // wider than tall, so "landscape"
        NSLayoutConstraint.deactivate(narrowConstraints)
        NSLayoutConstraint.activate(wideConstraints)
    } else {
        // taller than wide
        NSLayoutConstraint.deactivate(wideConstraints)
        NSLayoutConstraint.activate(narrowConstraints)
    }
    
}

我看起來問題是每次調用 function 時,您都會創建新的約束,但不會停用上次運行時的舊約束。

例如,第一次調用它時,它會創建一組寬和窄的約束並激活寬集。 下次調用它時,它將創建一組新的寬約束和窄約束,並激活第二組的窄約束,而不會停用第一組的寬約束。 您要求停用它的呼叫將在第二組上調用,這將生效。

我猜沖突約束消息顯示了第一組尚未停用的約束。


我要做的是將您的 function 分成兩個單獨的函數。

制作setupConstraints function 僅創建 arrays 約束並僅激活commonConstraints 重要的部分是確保這個 function 只被調用一次。

制作一個activateConstraintsForOrientation function,它只包含 function 底部的 if 語句。然后,只要您認為方向已更改,就可以調用此 function。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM