はじめに
どうも@kaneko77です。
今回はコードオンリーでUIを実装するとき
割と苦労するUIScrollViewのAutolayoutを共有していきたいと思います。
ちゃんと制約を組まないとスクロールできないとかありますよね。
今回の記事を見てなんとなーく分かるようになると思います。
コード
まずはコードを貼り付けます。
コピペすれば動きます。
import UIKit
class TestViewController: UIViewController {
var mainView: TestView!
override func loadView() {
super.loadView()
self.mainView = TestView(frame: .zero)
self.view = self.mainView
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
}
class TestView: UIView {
let scroll = UIScrollView()
let outline = UIView()
let testButton: UIButton = {
let button = UIButton()
button.backgroundColor = .red
button.setTitleColor(.white, for: .normal)
button.setTitle("テストテストテスト", for: .normal)
return button
}()
let testText: UILabel = {
let text = UILabel()
text.text = "隣の柿はよく柿食う客だ隣の柿はよく柿食う客だ隣の柿はよく柿食う客だ隣の柿はよく柿食う客だ"
text.textColor = .white
text.numberOfLines = 0
return text
}()
override init(frame: CGRect) {
super.init(frame: frame)
self.backgroundColor = .systemGray
setComponent()
scrollConstraint()
setConstraint()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func setComponent(){
[scroll, outline, testButton, testText].forEach{
$0.translatesAutoresizingMaskIntoConstraints = false
}
addSubview(scroll)
scroll.addSubview(outline)
[testButton, testText].forEach{
outline.addSubview($0)
}
}
private func scrollConstraint(){
NSLayoutConstraint.activate([
scroll.topAnchor.constraint(equalTo: self.safeAreaLayoutGuide.topAnchor),
scroll.bottomAnchor.constraint(equalTo: self.safeAreaLayoutGuide.bottomAnchor),
scroll.leadingAnchor.constraint(equalTo: self.safeAreaLayoutGuide.leadingAnchor),
scroll.trailingAnchor.constraint(equalTo: self.safeAreaLayoutGuide.trailingAnchor),
outline.topAnchor.constraint(equalTo: self.scroll.topAnchor),
outline.bottomAnchor.constraint(equalTo: self.scroll.bottomAnchor),
outline.widthAnchor.constraint(equalTo: self.scroll.widthAnchor),
outline.leadingAnchor.constraint(equalTo: self.scroll.leadingAnchor),
outline.trailingAnchor.constraint(equalTo: self.scroll.trailingAnchor),
])
}
private func setConstraint(){
NSLayoutConstraint.activate([
testButton.topAnchor.constraint(equalTo: self.outline.topAnchor, constant: 50),
testButton.leadingAnchor.constraint(equalTo: self.outline.leadingAnchor, constant: 20),
testButton.trailingAnchor.constraint(equalTo: self.outline.trailingAnchor, constant: -20),
testButton.heightAnchor.constraint(equalToConstant: 40),
testText.topAnchor.constraint(equalTo: self.testButton.bottomAnchor, constant: 400),
testText.bottomAnchor.constraint(equalTo: self.outline.bottomAnchor, constant: -50),
testText.leadingAnchor.constraint(equalTo: self.outline.leadingAnchor, constant: 20),
testText.trailingAnchor.constraint(equalTo: self.outline.trailingAnchor, constant: -20),
])
}
}
説明
今回のメインディッシュはこちらですね。
まずUIScrollView(変数名はscroll)
は全方位に制約をかけます。
UIView(変数名はoutline)
は同じく全方位に制約をかけます。
今回は仮の縦画面のみスクロール画面を作ると定義してプラスして、横幅を固定値にします。
private func scrollConstraint(){
NSLayoutConstraint.activate([
scroll.topAnchor.constraint(equalTo: self.safeAreaLayoutGuide.topAnchor),
scroll.bottomAnchor.constraint(equalTo: self.safeAreaLayoutGuide.bottomAnchor),
scroll.leadingAnchor.constraint(equalTo: self.safeAreaLayoutGuide.leadingAnchor),
scroll.trailingAnchor.constraint(equalTo: self.safeAreaLayoutGuide.trailingAnchor),
outline.topAnchor.constraint(equalTo: self.scroll.topAnchor),
outline.bottomAnchor.constraint(equalTo: self.scroll.bottomAnchor),
outline.widthAnchor.constraint(equalTo: self.scroll.widthAnchor),
outline.leadingAnchor.constraint(equalTo: self.scroll.leadingAnchor),
outline.trailingAnchor.constraint(equalTo: self.scroll.trailingAnchor),
])
}
ヒエラルキー上だとこういう風になっています。
ViewControllerのViewを消したバージョンです。
終わりに
そんな共有することはなかったなと思いますが、
しかしコードオンリーで実装すると
インターフェースビルダーで実装しているより
想像しずらく難しいなと感じる方もいらっしゃると思います。
今回のコードをコピぺしてコンテンツ中をいじる倒すのも良いと思います。
横もスクロールしたい場合はoutline
の横幅の固定値(以下コード)を消すことで実現できます。
outline.widthAnchor.constraint(equalTo: self.scroll.widthAnchor)
ここまで読んでいただきありがとうございます。
皆さんのお役に少しでも立てればなと思います。