環境
Xcode8.2
Swift3
やりたいこと
横並びにあるオブジェクトを表示非表示を切り替え、非表示にしたオブジェクトを詰めて表示したい。
参考文献:よくわかるAutoLayout本
例えば上記スクリーンショットにある HogeButton
を非表示にすると、下記スクリーンショットのように HogeButton
を非表示にし、UIButtonがあった空間を詰めて表示したい。
失敗例
Hiddenをfalseにするだけだとオブジェクトは非表示にはなりますが空間が残りました。
UIButton.isHidden = true
制約を追加する
Intrinsic sizeで決まる横幅を0にする制約を追加します
横幅を0にする制約を定義しておいたうえで、非表示にするタイミングでこの制約を追加。表示するタイミングで制約を削除します。
// ボタンの横幅を0にする制約
let buttonWidthConstraint = NSLayoutConstraint(
item: self.button
, attribute: NSLayoutAttribute.width
, relatedBy: NSLayoutRelation.equal
, toItem: nil
, attribute: NSLayoutAttribute.width
, multiplier: 1.0
, constant: 0)
オブジェクト間の幅制約をIBOutletで接続
Storyboardから制約をドラッグしてファイルに追加します。
IBOutletで接続できると下記のようにファイルにコードが生成されます。名前は buttonLeadingConstraint
にしました
表示非表示のタイミングで制約を変更する
if button.isHidden {
// IBOutletで接続した制約
buttonLeadingConstraint.constant = 8
// 制約を削除する
NSLayoutConstraint.deactivate([buttonWidthConstraint])
button.isHidden = false
}
else {
buttonLeadingConstraint.constant = 0
// 制約を追加する
NSLayoutConstraint.activate([buttonWidthConstraint])
button.isHidden = true
}
}
まとめ
非表示、表示のタイミングで制約を変更することで期待通りの動作が実装できました。
こうした方が良い方法があればご教示下さいmm
//
// ViewController.swift
// IntrinsicTorutsumeSample
//
// Created by { Kazunori } on 2017/02/02.
// Copyright © 2017年 Yamamoto Kazunori. All rights reserved.
//
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var button: UIButton!
@IBOutlet weak var label: UILabel!
@IBOutlet weak var switchButton: UISwitch!
@IBOutlet weak var buttonLeadingConstraint: NSLayoutConstraint!
@IBOutlet weak var labelLeadingConstraint: NSLayoutConstraint!
@IBOutlet weak var switchLeadingConstraint: NSLayoutConstraint!
@IBOutlet weak var switchWidthConstraint: NSLayoutConstraint!
var buttonWidthConstraint: NSLayoutConstraint!
override func viewDidLoad() {
// ボタンの横幅を0にする制約
buttonWidthConstraint = NSLayoutConstraint(
item: self.button
, attribute: NSLayoutAttribute.width
, relatedBy: NSLayoutRelation.equal
, toItem: nil
, attribute: NSLayoutAttribute.width
, multiplier: 1.0
, constant: 0)
}
@IBAction func pressToolbarLabel(_ sender: Any) {
if label.text == nil {
label.text = "HogeGehoString"
labelLeadingConstraint.constant = 8
}
else {
label.isHighlighted = true
label.text = nil
labelLeadingConstraint.constant = 0
}
}
@IBAction func pressToolbarButton(_ sender: Any) {
if button.isHidden {
buttonLeadingConstraint.constant = 8
NSLayoutConstraint.deactivate([buttonWidthConstraint])
button.isHidden = false
}
else {
buttonLeadingConstraint.constant = 0
NSLayoutConstraint.activate([buttonWidthConstraint])
button.isHidden = true
}
}
@IBAction func pressToolbarSwitch(_ sender: Any) {
if switchButton.isHidden {
switchLeadingConstraint.constant = 8
switchWidthConstraint.constant = 49
switchButton.isHidden = false
}
else {
switchLeadingConstraint.constant = 0
switchWidthConstraint.constant = 0
switchButton.isHidden = true
}
}
}
スクリーンショット内の他のオブジェクト表示、非表示を行うサンプルを作成しました。