LoginSignup
43
42

More than 5 years have passed since last update.

Swiftでボタンのレイアウト(配置)を試してみる その2

Last updated at Posted at 2014-06-23

Swiftコードで手書きの場合

Swiftでレイアウトをコーディングしていてハマったポイントをまず記述する

addSubviewの記述タイミング

self.view.addSubview(myButton)メソッドを、NSLayoutConstraint.constraintsWithVisualFormatメソッドのより後方に記述すると、下記エラーが生じる。

'Unable to parse constraint format: 
 Unable to interpret '|' character, 
 because the related view doesn't have a superview 
 H:|-[myButton]-| 
               ^'

これは当然であるが、ViewにmyButtonというオブジェクトが存在しないわけなので、addSubviewを最初にコールしておく。

NSDictionaryOfVariableBindingsマクロ定義の使用不可

Objective-CではNSDictionaryOfVariableBindingsはマクロ定義らしい。Swiftでは当然マクロ定義は使用できない。そもそもマクロ定義って何ですか?って感じですが w。
実際このObjective-Cマクロ内では、オブジェクト名とその変数をバインドするだけらしいので、

    var viewDictionary:NSDictionary = NSDictionaryOfVariableBindings(myButton)

とは記述せずに、下記のように記述する。

    var viewDictionary:Dictionary = ["myButton": myButton]

制約条件配列の追加方法

制約を格納する方法というより、そもそものArrayの追加方法の問題だが、

NSLayoutConstraint.constraintsWithVisualFormatは、配列AnyObject[]を返すので、constraints.addObjectsFromArrayを使用する。

    constraints.addObjectsFromArray(constraintFormat1)
    constraints.addObjectsFromArray(constraintFormat2)

それに対し、NSLayoutConstraintコンストラクタを格納する場合は、constraints.addObjectを使用する。

    constraints.addObject(constraintFormat1)
    constraints.addObject(constraintFormat2)

translatesAutoresizingMaskIntoConstraintsの設定

Objective-Cの場合は、下記のように記述するようだ。

    translatesAutoresizingMaskIntoConstraints = NO

Swiftでは、setterメソッドで下記のように記述する。
今回はボタン1つであるが、View上に存在する全てのオブジェクトに設定する。

    myButton.setTranslatesAutoresizingMaskIntoConstraints(false)

ちなみに、上記の設定をfalseとしないと下記エラーが発生する。

    Unable to simultaneously satisfy constraints.
    Probably at least one of the constraints in the following 
    list is one you don't want. 
    Try this: (1) look at each constraint and try to figure out 
    which you don't expect; 
    (2) find the code that added the unwanted constraint or 
    constraints and fix it. (Note: If you're seeing 
    NSAutoresizingMaskLayoutConstraints that you don't understand,
    refer to the documentation for the UIView property
    translatesAutoresizingMaskIntoConstraints) 

以下は、2通りのソースコードだが、厳密には使用方法が異なると思うが、コードでレイアウトを中央に配置する為の記述方法である。ご参考までに。

VisualFormatLanguage制約.swift
    override func viewDidLoad() {
        super.viewDidLoad()

        //ボタン生成
        myButton.setTitle("Button", 
                forState:UIControlState.Normal)
        myButton.setTitleColor(UIColor.blueColor(),
                forState:UIControlState.Normal)

        myButton.setTitle("Push", 
                forState:UIControlState.Highlighted)
        myButton.setTitleColor(UIColor.redColor(),
                forState:UIControlState.Highlighted)
        //falseを設定する
        myButton.setTranslatesAutoresizingMaskIntoConstraints(false)

        //NSLayoutConstraintを宣言する前にaddSubviewする
        self.view.addSubview(myButton)

        //Objective-Cではマクロ定義らしいのでSwiftでは使用できない
        //var viewDictionary:NSDictionary = NSDictionaryOfVariableBindings(myButton)
        var viewDictionary:Dictionary = ["myButton": myButton]

        var constraints:NSMutableArray = NSMutableArray()

        //NSLayoutConstraint.constraintsWithVisualFormatメソッド(X方向)
        var constraintFormat1:AnyObject[] =
        NSLayoutConstraint.constraintsWithVisualFormat(
                    "H:|-[myButton]-|",
                    options : NSLayoutFormatOptions(0),
                    metrics: nil,
                    views: viewDictionary)
        constraints.addObjectsFromArray(constraintFormat1)

        //NSLayoutConstraint.constraintsWithVisualFormatメソッド(Y方向)
        var constraintFormat2:AnyObject[] = 
        NSLayoutConstraint.constraintsWithVisualFormat(
                    "V:|-[myButton]-|",
                    options : NSLayoutFormatOptions(0),
                    metrics: nil,
                    views: viewDictionary)
        constraints.addObjectsFromArray(constraintFormat2)
        //制約の追加
        self.view.addConstraints(constraints)

    }

コンストラクタ制約.swift
    override func viewDidLoad() {
        super.viewDidLoad()

        myButton.setTitle("Button", 
                forState:UIControlState.Normal)
        myButton.setTitleColor(UIColor.blueColor(),
                forState:UIControlState.Normal)

        myButton.setTitle("Push", 
                forState:UIControlState.Highlighted)
        myButton.setTitleColor(UIColor.redColor(), 
                forState:UIControlState.Highlighted)
        //falseを設定する
        myButton.setTranslatesAutoresizingMaskIntoConstraints(false)

        //NSLayoutConstraintを宣言する前にaddSubviewする
        self.view.addSubview(myButton)

        //Objective-Cではマクロ定義らしいのでSwiftでは使用できない
        //var viewDictionary:NSDictionary = NSDictionaryOfVariableBindings(myButton)
        var viewDictionary:Dictionary = ["myButton": myButton]

        var constraints:NSMutableArray = NSMutableArray()

        //NSLayoutConstraintコンストラクタ(X)
        var constraintFormat1:NSLayoutConstraint = 
        NSLayoutConstraint(item: myButton,
                    attribute: NSLayoutAttribute.CenterX,
                    relatedBy: NSLayoutRelation.Equal,
                    toItem: self.view,
                    attribute: NSLayoutAttribute.CenterX,
                    multiplier: 1.0,
                    constant: 0)
        constraints.addObject(constraintFormat1)

        //NSLayoutConstraintコンストラクタ(Y)
        var constraintFormat2:NSLayoutConstraint =
        NSLayoutConstraint(item: myButton,
                    attribute: NSLayoutAttribute.CenterY,
                    relatedBy: NSLayoutRelation.Equal,
                    toItem: self.view,
                    attribute: NSLayoutAttribute.CenterY,
                    multiplier: 1.0,
                    constant: 0)
        constraints.addObject(constraintFormat2)
        //制約の追加
        self.view.addConstraints(constraints)

    }
43
42
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
43
42