Storyboardでしか書いたことなかったけど、データが動的な場合はコードの方が楽なのでメモ。
import UIKit
class MainViewController : UIViewController {
let listView = ListView()
override func viewDidLoad() {
self.view.addSubview(listView)
listView.translatesAutoresizingMaskIntoConstraints = false
listView.widthAnchor.constraint(equalToConstant: 300).isActive = true
listView.heightAnchor.constraint(equalToConstant: 100).isActive = true
listView.centerYAnchor.constraint(equalTo: self.view.centerYAnchor, constant: 0).isActive = true
listView.centerXAnchor.constraint(equalTo: self.view.centerXAnchor, constant: 0).isActive = true
let item1 = Item()
let item2 = Item()
let item3 = Item()
stackView.addArrangedSubview(item1)
stackView.addArrangedSubview(item2)
stackView.addArrangedSubview(item3)
}
}
class StackView : UIView {
let stackView = UIStackView()
override init(frame: CGRect) {
super.init(frame: frame)
self.setup()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.setup()
}
func setup(){
self.backgroundColor = UIColor.white
self.addSubview(stackView)
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.distribution = .fillEqually
stackView.alignment = .fill
stackView.spacing = 10.0
stackView.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 0).isActive = true
stackView.rightAnchor.constraint(equalTo: self.rightAnchor, constant: 0).isActive = true
stackView.topAnchor.constraint(equalTo: self.topAnchor, constant: 0).isActive = true
stackView.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: 0).isActive = true
}
}
class Item : UIView {
let imageView = UIImageView()
let name = UILabel()
override init(frame: CGRect) {
super.init(frame: frame)
self.setup()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func setup(){
self.addSubview(imageView)
imageView.backgroundColor = UIColor.gray
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 0).isActive = true
imageView.rightAnchor.constraint(equalTo: self.rightAnchor, constant: 0).isActive = true
imageView.topAnchor.constraint(equalTo: self.topAnchor, constant: 0).isActive = true
self.addSubview(name)
name.text = "TEST"
name.translatesAutoresizingMaskIntoConstraints = false
name.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 0).isActive = true
name.rightAnchor.constraint(equalTo: self.rightAnchor, constant:0).isActive = true
name.topAnchor.constraint(equalTo: imageView.bottomAnchor, constant: 5).isActive = true
name.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: 0).isActive = true
}
}
メモ
- stackViewにはwidth,heightの指定が必須。指定しないとサイズが0になる
- Item(StackViewに追加するView)は
addSubView
じゃなくてaddArrangedSubview
で追加する - Itemのサイズは指定しないと最小になる。サイズを持つ要素(UILabelとか)の場合はテキスト分のサイズに。ただ
distribution
とalignment
で拡大のルールは決められる。 - Webでいうflexboxと考え方は一緒。
思ったよりAutoLayoutをコードで書くのがめんどくさくないので今後はコードで書いていきたい。isActive = true
はよく忘れる。