web-dev-qa-db-ja.com

Interface Builderで自動レイアウト制約に識別子を追加する方法はありますか?

Interface Builderで視覚的なレイアウトを行った後、実行時にアクセスしたい制約をいくつか作成しました。後で検索できるように、Interface Builderで制約にラベルを付けたり識別したりする方法はありますか?

これを行う理由は、視覚的に指定された制約に基づいていくつかの計算を実行する必要があるためです。 Appleは Visual Format Language を提供しており、コントローラでプログラムで制約を指定できることを知っています。このアプローチを使用しないので、失うことはありませんIBの設計時フィードバック。

編集する

参照アウトレットを作成することはうまくいきましたが、問題はまだ残っています。

22

更新:

his answer でBartłomiejSemańczykが説明したように、 AttributesにIdentifierフィールドが表示されますInspector NSLayoutConstraintの場合、このフィールドを自分で公開する必要はありません。 Document Outline ビューまたはStoryboardビューで制約を選択し、右側の Attributes Inspector に識別子を追加するだけです。


以前の回答:

はい、できます。 NSLayoutConstraintにはidentifierというプロパティがあり、 Interface Builder で公開して割り当てることができます。これをデモするために、赤いボックスである単一のサブビューを持つ Single View Application を作成しました。このサブビューには4つの制約があります:幅、高さ、コンテナーの水平方向の中央、コンテナーの垂直方向の中央。次のようにして、幅の制約に識別子redBoxWidthを指定しました。

  1. Document Layout View で幅の制約をクリックします。次に、 Identity Inspector User Defined Runtime Attributesで、+Key Pathの下)。 keyPath identifier に変更し、Typeブール値文字列に設定し、ValueredBoxWidth

    naming a constraint

  2. 次に、ViewDidLoadで、名前で制約を見つけ、その値を変更することができます。

    class ViewController: UIViewController {
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            for subview in view.subviews as [UIView] {
                for constraint in subview.constraints() as [NSLayoutConstraint] {
                    if constraint.identifier == "redBoxWidth" {
                        constraint.constant = 300
                    }
                }
            }
        }
    }
    
33
vacawama
  1. Xcode 7以降、ストーリーボードで実行できます。

enter image description here

  1. ただし、コードで制約を設定する場合は、次のようにします。

    let constraint = NSLayoutConstraint() 
    constraint.identifier = "identifier"
    
  2. これらの制約については、ストーリーボードで設定しましたが、コードで識別子を設定する必要があります。

    for subview in view.subviews {
        for constraint in subview.constraints() {
            constraint.identifier = "identifier"
        }
    }
    

また、他のコンポーネントの場合と同様に、制約をコントローラーのプロパティにリンクできます。それをあなたのコードにドラッグするだけです:

enter image description here

そして、それはあなたのコントローラのコードでプロパティとしてアクセス可能になります:

@property (weak, nonatomic) IBOutlet NSLayoutConstraint *myConstraint;

そして、あなたはその値を例えば変更することができます:

self.myConstraint.constant=100.;
9
Volchik

@vacawamaの答えに追加するだけです。 UIViewカテゴリを記述して、制約を見つける必要のあるすべての場所でループをコピー/貼り付けるのではなく、単純な関数を使用して制約を引き出すことができます。

.hファイル:

#import <UIKit/UIKit.h>

@interface UIView (EasyAutolayout)

-(NSLayoutConstraint *)constraintForIdentifier:(NSString *)identifier;

@end

.mファイル:

#import "UIView+EasyAutolayout.h"

@implementation UIView (EasyAutolayout)

-(NSLayoutConstraint *)constraintForIdentifier:(NSString *)identifier {

    for (NSLayoutConstraint *constraint in self.constraints) {
        if ([constraint.identifier isEqualToString:identifier]) {
            return constraint;
        }
    }
    return nil;
}

@end
6
rebello95

自動レイアウト制約のIBOutletを取得します。

NSLayoutConstraintクラスにはconstantというプロパティが1つあります。

たとえば、IBから任意のビューの高さ制約のIBOutletを取得し、それをプログラムで高さを変更したい場合は、次の操作を行うだけです。

 constraint.constant = isMoreHeight ? height1 : height2;

これを実行した後、スーパービューのビュー階層内の他のすべてのビューを更新する必要があります。これを行うには、以下の行を記述する必要があります。

[self setLayoutIfNeeded];

ユーザーエクスペリエンスを向上させるには、この行をアニメーションブロック内に配置して、トランジションエフェクトをスムーズにし、

[UIView animateWithDuration:0.3f animations:^{
      [self.view layoutIfNeeded];
}];

お役に立てれば..

5
Henit Nathwani

これはどうですか:

if let myconstraint = self.view.constraints.filter( { $0.identifier == "myconstraintId" }).first {
    // TODO: your code here...
}
4
Carlos Carvalho

oSXの私の2セント(以前の答えはUIKitを扱います。)

oSXでも機能します。

final private func getConstraintForButton(){
    let constraints  = self.myButton.constraints
    for constraint in constraints  {
        if constraint.identifier == "redBoxWidth" {
            constraint.constant = 300
            break
        }
    }
}

注:カスタムNSViewでは機能していないようですが、代わりに...

0
ingconti