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


##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)
        
    }
```