簡體   English   中英

從 Xib 加載的 UIView 未正確應用 AutoLayout

[英]UIView loaded from Xib does not apply AutoLayout correctly

我試圖將我的視圖控制器內容分解為我從 xib 加載的更小的單個視圖塊。 我這樣做是通過將占位符UIView對象放入我的 Storyboard 視圖控制器中並使用它們來添加我在 xib 文件中作為子視圖在構建時布局的實際UIView子類。

該過程非常簡單, 之前討論

然而,問題是在添加視圖時,在 xib 文件中定義的 AutoLayout 約束不起作用。

為了說明這個問題,我創建了一個示例項目:一個ViewController有一個類型為CustomColorViewUIView子類)的colorView ,它將被添加到一個普通的UIView占位符中。 CustomColorView類然后有一個coloredView屬性,它應該填滿整個空間(由 xib 文件中每一邊的 AutoLayout 約束定義)。

視圖控制器

在此處輸入圖片說明

NibLoadable協議:

public protocol NibLoadable {
    static var nibName: String { get }
}

public extension NibLoadable where Self: UIView {

    public static var nibName: String {
        return String(describing: Self.self)
    }

    public static var nib: UINib {
        let bundle = Bundle(for: Self.self)
        return UINib(nibName: Self.nibName, bundle: bundle)
    }

    func setupFromNib() {
        guard let loadedView = Self.nib.instantiate(withOwner: self, options: nil).first as? UIView else { fatalError("Error loading \(self) from nib") }
        loadedView.frame = bounds

        addSubview(loadedView)
        loadedView.translatesAutoresizingMaskIntoConstraints = false
        loadedView.leadingAnchor.constraint(equalTo: self.safeAreaLayoutGuide.leadingAnchor, constant: 0).isActive = true
        loadedView.topAnchor.constraint(equalTo: self.safeAreaLayoutGuide.topAnchor, constant: 0).isActive = true
        loadedView.trailingAnchor.constraint(equalTo: self.safeAreaLayoutGuide.trailingAnchor, constant: 0).isActive = true
        loadedView.bottomAnchor.constraint(equalTo: self.safeAreaLayoutGuide.bottomAnchor, constant: 0).isActive = true
    }
}

當我將我的自定義視圖添加到普通UIView ,我會假設它應用了 nib 文件中所有定義的約束,但它沒有。 兩個視圖的print結果應該相同,但它們不同( coloredView仍然具有來自 xib 文件的大小)。

關於可能出什么問題的任何想法? 謝謝你的幫助!

整個項目都在 GitHub 上: XibAutoLayoutExample

您的視圖高度是否正確,請添加layer.borderColorlayer.borderWidth並檢查它

func setup() {
    print("CustomColorView bounds: \(bounds)")
    print("coloredView subview bounds: \(coloredView.bounds)")
    self.coloredView.layer.borderColor = UIColor.red.cgColor
    self.coloredView.layer.borderWidth = 1
}

此外,如果您在viewDidAppear調用setup()將顯示正確的值,這是因為viewDidAppearviewDidLayoutSubviews之后執行,因此當您的 viewController 正確結束其布局時,您的日志會顯示正確的值

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    colorView.setup()
}

日志

CustomColorView bounds: (0.0, 0.0, 320.0, 227.0)
coloredView subview bounds: (0.0, 0.0, 320.0, 227.0)

暫無
暫無

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

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