web-dev-qa-db-ja.com

カスタムUIView内で自動レイアウト制約コードを追加する場所

自動レイアウト制約がUIViewControllerに追加されるのをよく見ますが、レイアウトロジックの間違った場所のようです。

カスタムNSLayoutConstraint内にUIViewsを追加することは可能ですか?

UIViewのどこをプログラムで追加するのが適切でしょうか?

26
Bernd

カスタムUIView内にNSLayoutConstraintsを追加することは可能ですか?

はい、カスタムビュー内に制約を追加することは可能です。ここでは、特にカスタムビューの一部をアニメーション化する場合、組織が非常に重要です。

Appleの IViewリファレンスドキュメント からサブクラス化セクションを読む

制約:

requireConstraintBasedLayout-ビュークラスで制約が適切に機能する必要がある場合、このクラスメソッドを実装します。

updateConstraints-ビューでサブビュー間にカスタム制約を作成する必要がある場合、このメソッドを実装します。

alignmentRectForFrame:、frameForAlignmentRect:-これらのメソッドを実装して、ビューを他のビューに整列する方法をオーバーライドします。

それらをプログラムで追加するのに適切な場所はUIViewのどこですか?

カスタムクラスのスケルトンアウトラインは次のとおりです。重要な懸念は、制約を一元化することです。そうしないと、追加する制約が増えるほどクラスが非常に乱雑になります。また、updateConstraints()メソッドに他の設定を導入し、構成値を設定して制約を条件付きで追加または削除し、setNeedsUpdateConstraints()を呼び出すこともできます。

アニメーション化することを決定した制約は、最も軽くインスタンス変数にする必要があります。

お役に立てれば :)

class MyCustomView: UIView {

    private var didSetupConstraints = false
    private let myLabel = UILabel(frame: CGRectZero)

    // MARK: Lifecycle
    override init(frame: CGRect) {
        super.init(frame: CGRectZero)
        self.setup()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        self.setup()
    }


    // Mark: - Setup
    private func setup() {

        // 1. Setup the properties of the view it's self
        self.translatesAutoresizingMaskIntoConstraints = false
        backgroundColor = UIColor.orangeColor()
        clipsToBounds = true

        // 2. Setup your subviews
        setupMyLabel()

        // 3. Inform the contraints engine to update the constraints
        self.setNeedsUpdateConstraints()
    }


    private func setupMyLabel() {

        myLabel.translatesAutoresizingMaskIntoConstraints = false

    }


    override func updateConstraints() {

        if didSetupConstraints == false {
            addConstraintsForMyLabel()
        }

        super.updateConstraints() //Documentation note: Call [super updateConstraints] as the final step in your implementation.
    }

    private func addConstraintsForMyLabel() {

        // Add your constraints here
    }

}
33
Pete Hornsby

必要に応じて、ビューでAutoLayoutコードを設定するのが好きです。また、customViewの初期化の一部として、すべての制約を1か所に設定する方が簡単であることがわかりました。

import UIKit

class customView:UIView
{
    var customLabel:UILabel = UILabel()

    override init(frame: CGRect) {
        super.init(frame: frame)
        self.setupUI()
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    func setupUI()
    {
        // Setup UI
        self.customLabel.translatesAutoresizingMaskIntoConstraints = false
        self.addSubview(customLabel)

        // Setup Constraints
        self.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-10-[customLabel]|", options: NSLayoutFormatOptions.init(rawValue: 0), metrics: nil, views: ["customLabel":self.customLabel]))
        self.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-10-[customLabel]-10-|", options: NSLayoutFormatOptions.init(rawValue: 0), metrics: nil, views: ["customLabel":self.customLabel]))
    }
}
8
Joseph Afework