1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

UIScrollViewのAutolayoutをコードオンリーで実装してみた

Posted at

はじめに

どうも@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)

ここまで読んでいただきありがとうございます。
皆さんのお役に少しでも立てればなと思います。

1
0
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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?