web-dev-qa-db-ja.com

プログラムで制約を追加するswift

FacebookのSDKログインボタンに制約を追加しようとしています。

スクロールビュー内にボタンがあり、スクロールビュー内にあるラベルに上部制約を追加しようとしています。実行時エラーなしで高さの制約を追加できましたが、実際の制約はボタンに適用されていないようです。

@IBOutlet weak var orLbl: UILabel!
@IBOutlet weak var scrollView: UIScrollView!

override func viewDidLoad() {
    super.viewDidLoad()
    var loginFBButton = FBSDKLoginButton()
    loginFBButton.readPermissions = ["public_profile", "email"]

    let heightConstraint = NSLayoutConstraint(
        item: loginFBButton,
        attribute: NSLayoutAttribute.Height,
        relatedBy: NSLayoutRelation.Equal,
        toItem: nil,
        attribute: NSLayoutAttribute.NotAnAttribute,
        multiplier: 1,
        constant: 41)
    let topConstraint = NSLayoutConstraint(
        item: loginFBButton,
        attribute: NSLayoutAttribute.TopMargin,
        relatedBy: NSLayoutRelation.Equal,
        toItem: self.orLbl,
        attribute: NSLayoutAttribute.BottomMargin,
        multiplier: 1,
        constant: 31)
    let leadingConstraint = NSLayoutConstraint(
        item: loginFBButton,
        attribute: NSLayoutAttribute.Leading,
        relatedBy: NSLayoutRelation.Equal,
        toItem: self.registerButton,
        attribute: NSLayoutAttribute.Left,
        multiplier: 1,
        constant: 0)
    let trailingConstraint = NSLayoutConstraint(
        item: loginFBButton,
        attribute: NSLayoutAttribute.Leading,
        relatedBy: NSLayoutRelation.Equal,
        toItem: self.registerButton,
        attribute: NSLayoutAttribute.Right,
        multiplier: 1,
        constant: 0)

    self.scrollView.addSubview(loginFBButton)
    //loginFBButton.center = self.scrollView.center

    loginFBButton.addConstraints([heightConstraint, topConstraint])

}

次に、トップ制約の追加を含めると、ランタイムエラーが発生します。

ビューに追加する場合、制約のアイテムはそのビュー(またはビュー自体)の子孫でなければなりません。ビュー階層を組み立てる前に制約を解決する必要がある場合、これはクラッシュします。

キャッチされない例外 'NSGenericException'によるアプリの終了、理由: 'ビューに制約をインストールできません。制約は、ビューのサブツリーの外側から何かを参照しますか?それは違法です。

ラベルとFacebookボタンの両方がスクロールビューにありますか? orLbl.superviewとloginFBButton.superviewを印刷し、両方のオプションのuiscrollviewを取得しています

13
user2363025

制約をアクティブ化する新しい(iOS8、OS 10.10)簡単な方法があり、どのビューに追加するかを把握する必要がありません。制約はすでにどのビューに属しているかを知っているため、まずビューがサブビューとして追加されていることを確認してから、activateConstraintsのクラスメソッドNSLayoutConstraintを呼び出してアクティブにします。

 NSLayoutConstraint.activateConstraints([heightConstraint, topConstraint])

プログラムでUI要素を作成する場合、iOSにフレームを制約にしないように指示する必要があります。それを行うには、loginFBButtonを作成した直後に:

Swift 1.2:の場合

loginFBButton.setTranslatesAutoresizingMaskIntoConstraints(false)

Swift 2.0&3.0:の場合

loginFBButton.translatesAutoresizingMaskIntoConstraints = false

最後に、より多くの制約が必要になります。 loginFBButtonの幅の制約を設定し、制約を追加してボタンを水平に配置することをお勧めします。

29
vacawama