티스토리 뷰

SnapKit을 이용해서 코드로 오토레이아웃을 설정해보겠습니다.

이 글은 baechukim.tistory.com/23 를 같이 보시면 좋습니다.

 

완성된 화면입니다.

SnapKit에서는  translatesAutoresizingMaskIntoConstraints = false 를 해주지 않아도 됩니다.

 

오토레이아웃 설정하기

   private func createUI() {
        self.navigationItem.title = "SnapKit"
        view.addSubview(tableView)
        tableView.snp.makeConstraints { maker in
            maker.edges.equalTo(view)
        }
    }

스냅킷을 사용하지 않는다면 아래와 같이 작성해야합니다.

    private func createUI() {
        
        self.navigationItem.title = "UIKit"
        view.addSubview(tableView)
        
        tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 0).isActive = true
        tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: 0).isActive = true
        tableView.topAnchor.constraint(equalTo: view.topAnchor, constant: 0).isActive = true
        tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: 0).isActive = true
    }

 

테이블뷰의 엣지를 view의 엣지와 같게해라! 라는 직관적인 코드로 쉽게 제약을 만들 수 있습니다.

 tableView.snp.makeConstraints { maker in
    maker.edges.equalTo(view)
}

 

헤더뷰 푸터뷰 만들기

스냅킷을 사용하지 않는다면 아래와 같이 작성해야합니다.

label.translatesAutoresizingMaskIntoConstraints = false
label.leadingAnchor.constraint(equalTo: headerView.leadingAnchor, constant: 20).isActive = true
label.centerYAnchor.constraint(equalTo: headerView.centerYAnchor, constant: 0).isActive = true

 

leading이 왼쪽을 뜻하는게 아니라 글쓰기 방향을 말하는데요.

한글이나 영어는 왼쪽에서 오른쪽으로 쓰지만, 아랍어는 오른쪽에서 왼쪽으로 씁니다.

그래서 leading으로 하면 아랍권앱에서는 좌우가 반전됩니다.

 

스냅킷에서 left를 썼습니다. (leading도 사용가능)

헤더뷰의 왼쪽에 offset을 20주는건 위에서 constant와 같습니다.

만약에 right(trailing)라면 -20을 줘야합니다.

 label.snp.makeConstraints { make in
    make.left.equalTo(headerView.snp.left).offset(20)
    make.centerY.equalTo(headerView)
}

 

스냅킷을 사용하지 않는다면 아래와 같이 작성해야합니다.

lineView.translatesAutoresizingMaskIntoConstraints = false
lineView.backgroundColor = .lightGray
lineView.leadingAnchor.constraint(equalTo: footerView.leadingAnchor, constant: 20).isActive = true
lineView.trailingAnchor.constraint(equalTo: footerView.trailingAnchor, constant: -20).isActive = true
lineView.heightAnchor.constraint(equalToConstant: 1).isActive = true
lineView.centerYAnchor.constraint(equalTo: footerView.centerYAnchor, constant: 0).isActive = true

스냅킷은 위, 왼쪽, 아래, 오른쪽의 제약을 한 번에 설정해줄 수 있습니다.

여기서는 offset대신 inset을 줬는데요.

inset을 사용하면 -20처럼 안써도 되고 4방향의 제약을 한번에 보기 좋게 작성할 수 있습니다.

 lineView.snp.makeConstraints { make in
    make.left.right.equalTo(footerView).inset(UIEdgeInsets(top: 0, left: 20, bottom: 0, right: 20))
    make.height.equalTo(1)
    make.centerY.equalTo(footerView)
}

셀 오토레이아웃

스냅킷을 사용하지 않는다면 아래와 같이 작성해야합니다.

pinButton.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 20).isActive = true
pinButton.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 10).isActive = true
pinButton.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -20).isActive = true
        
stackView.leadingAnchor.constraint(equalTo: pinButton.trailingAnchor, constant: 20).isActive = true
stackView.centerYAnchor.constraint(equalTo: pinButton.centerYAnchor).isActive = true

 

스냅킷을 사용하면 하나의 오브젝트에 관련된 제약들을 { } 안에 작성해서 더 보기 깔끔하고 중복을 줄일 수 있습니다.

pinButton.snp.makeConstraints { make in
    make.top.left.bottom.equalTo(contentView).inset(UIEdgeInsets(top: 10, left: 20, bottom: 20, right: 0))
}
        
stackView.snp.makeConstraints { make in
    make.left.equalTo(pinButton.snp.right).offset(20)
    make.centerY.equalTo(pinButton)
}

 

Then

 Then 라이브러리를 사용하시면 더 깔끔한 코드를 작성할 수 있습니다.

 

일반:

let label: UILabel = {
  let label = UILabel()
  label.textAlignment = .center
  label.textColor = .black
  label.text = "Hello, World!"
  return label
}()

Then:

let label = UILabel().then {
  $0.textAlignment = .center
  $0.textColor = .black
  $0.text = "Hello, World!"
}

 

TableViewCell SnapKit 예시

   let pinButton: UIButton = {
        let button = UIButton()
        button.setImage(UIImage(systemName: "pin"), for: .normal)
        button.tintColor = .darkGray
        
        return button
    }()
    
    let boardTitleLabel: UILabel = {
        let label = UILabel()
        label.font = .systemFont(ofSize: 17)
        
        return label
    }()
    
    let boardSubTitleLabel: UILabel = {
        let label = UILabel()
        label.font = .systemFont(ofSize: 14)
        label.textColor = .darkGray
        
        return label
    }()
    
    lazy var stackView: UIStackView = {
        let stackView = UIStackView(arrangedSubviews: [boardTitleLabel, boardSubTitleLabel])
        stackView.axis = .vertical
        stackView.spacing = 0
        
        return stackView
    }()

Then+SnapKit 예시

    let pinButton = UIButton().then {
        $0.setImage(UIImage(systemName: "pin"), for: .normal)
        $0.tintColor = .darkGray
    }
    
    let boardTitleLabel = UILabel().then {
        $0.font = .systemFont(ofSize: 17)
    }
    
    let boardSubTitleLabel = UILabel().then {
        $0.font = .systemFont(ofSize: 14)
        $0.textColor = .darkGray
    }
    
    lazy var stackView = UIStackView(arrangedSubviews: [boardTitleLabel, boardSubTitleLabel]).then {
        $0.axis = .vertical
        $0.spacing = 0
    }

 

 

댓글
공지사항