Swift개발

[Swift] SnapKit, Autolayout기본적인 기능 사용하기

녹차맛고양이 개발강좌 및 IT리뷰 2022. 5. 20. 11:25

 

Storyboard에서 벗어나 코드기반 UI를 만들때

Constraints와 AutoLayout 설정을 간단하게 하기 위한 라이브러리 입니다.

 

이 정도로도 Autolayout이라고 이야기들 하긴 하지만

너무나도 기본적인 부분이라

이번에는 간단한 사용법만 진행하고

 

다음에 제대로된 autolayout에 대한 내용과 then과 같이 활용하는 방법의 글을 올리겠습니다.

 

CocoaPods을 이용하여 설치하면 되고

설치 방법은 아래의 링크를 참고 하시기 바랍니다.

(버전이 다를 수 있어서 링크로 대체합니다.)

https://github.com/SnapKit/SnapKit

 

GitHub - SnapKit/SnapKit: A Swift Autolayout DSL for iOS & OS X

A Swift Autolayout DSL for iOS & OS X. Contribute to SnapKit/SnapKit development by creating an account on GitHub.

github.com

SnapKit을 import해줍니다.

import UIKit
import SnapKit

 

아래의 요소들을 추가하여 간단하게 동작하는 날짜 선택 화면을 만들겠습니다.

    let datePicker = UIDatePicker()
    let dateLabel = UILabel()
    let dateReset = UIButton()
    var nowDate: Date?
    
    let dateFormat = DateFormatter()

 

사진과 같은 배치로 만들어 보겠습니다.

 

 

initUI()에서는 화면에 요소들을 추가 하는 동작만 수행을 하고

setUI()에서 요소들의 속성 또는 설정을 해줍니다.

그리고 마지막으로

initConstraints()에서 Snapkit을 이용한 Constraints를 설정 해줍니다.

 

부모뷰에 맞추고 싶은 경우에는 equalToSuperview()으로 하면 되고

특정 요소에 맞춘다면 equalTo()를 사용 하시면 됩니다.

//
make.top.equalToSuperview()
make.top.equalTo(datePicker.snp.bottom)

// 같은 요소를 대상으로 한다면 동시에 Constraints를 추가 할 수도 있습니다.
make.leading.trailing.equalToSuperview()
make.left.right.equalToSuperview()

 

그리고 Constraints에 값을 줘서 간격을 만들고 싶을때는

offset()으로 추가 하시면 됩니다. 

 

make.top.equalToSuperview().offset(80)
make.top.equalTo(datePicker.snp.bottom).offset(50)

 

아래와 같이 만들어 주시면 됩니다.

 

    func initUI(){
        view.addSubview(datePicker)
        view.addSubview(dateLabel)
        view.addSubview(dateReset)
    }
    
    func setUI(){
        // 날짜 표시 형식
        dateFormat.dateFormat = "yyyy년 MM월 dd일"
        dateFormat.locale = Locale(identifier: "ko_KR")
        
        //DatePicker의 속성 및 이벤트 추가
        datePicker.datePickerMode = .date
        datePicker.preferredDatePickerStyle = .wheels
        datePicker.addTarget(self, action: #selector(datePickerValueDidChange), for: .valueChanged)
        
        //Label의 속성
        dateLabel.text = dateFormat.string(from: datePicker.date)
        dateLabel.textAlignment = .center
        
        //Button의 속성 및 이벤트 추가
        dateReset.setTitle("RESET", for: .normal)
        dateReset.backgroundColor = .lightGray
        dateReset.addTarget(self, action: #selector(dateResetAction), for: .touchUpInside)
    }
    
    func initConstraints(){
        datePicker.snp.makeConstraints{make in
            make.center.equalToSuperview()
        }
        dateLabel.snp.makeConstraints{make in
            make.top.equalToSuperview().offset(80)
            make.leading.trailing.equalToSuperview()
        }
        dateReset.snp.makeConstraints{make in
            make.top.equalTo(datePicker.snp.bottom).offset(50)
            make.left.right.equalToSuperview()
        }
    }

 

마지막으로 DatePicker와 Button에 추가할 이벤트를 만들어 줍니다.

 

    // 날짜 변경 시, Label에 선택한 날짜로 변경
    // 오늘이 아닌 경우에는 버튼 활성화
    @objc func datePickerValueDidChange(_ datepicker: UIDatePicker){
        DispatchQueue.main.async {
            let changeText : String = self.dateFormat.string(from: datepicker.date)
            
            self.dateLabel.text = changeText
            
            if(changeText == self.dateFormat.string(from: self.nowDate!)){
                self.dateReset.backgroundColor = .lightGray
            } else {
                self.dateReset.backgroundColor = .blue
            }
            
        }
    }
    // 오늘이 아닌 경우에 DatePicker의 날짜를 오늘로 변경
    @objc func dateResetAction(_ sender: UIButton){
        DispatchQueue.main.async {
            self.datePicker.date = self.nowDate ?? self.datePicker.date
            self.dateLabel.text = self.dateFormat.string(from: self.datePicker.date)
            self.dateReset.backgroundColor = .lightGray
        }
    }

 

 

2022년05년20일 기준으로 동작하는 모습입니다.

 

아래는 코드 전문 입니다.

 

import UIKit
import SnapKit

class ViewController: UIViewController {
    
    let datePicker = UIDatePicker()
    let dateLabel = UILabel()
    let dateReset = UIButton()
    var nowDate: Date?
    
    let dateFormat = DateFormatter()

    override func viewDidLoad() {
        super.viewDidLoad()

        nowDate = datePicker.date
        
        initUI()
        setUI()
        initConstraints()
    }
    
    
    func initUI(){
        view.addSubview(datePicker)
        view.addSubview(dateLabel)
        view.addSubview(dateReset)
    }
    
    func setUI(){
        dateFormat.dateFormat = "yyyy년 MM월 dd일"
        dateFormat.locale = Locale(identifier: "ko_KR")
        
        datePicker.datePickerMode = .date
        datePicker.preferredDatePickerStyle = .wheels
        datePicker.addTarget(self, action: #selector(datePickerValueDidChange), for: .valueChanged)
        
        dateLabel.text = dateFormat.string(from: datePicker.date)
        dateLabel.textAlignment = .center
        
        dateReset.setTitle("RESET", for: .normal)
        dateReset.backgroundColor = .lightGray
        dateReset.addTarget(self, action: #selector(dateResetAction), for: .touchUpInside)
    }
    
    func initConstraints(){
        datePicker.snp.makeConstraints{make in
            make.center.equalToSuperview()
        }
        dateLabel.snp.makeConstraints{make in
            make.top.equalToSuperview().offset(80)
            make.leading.trailing.equalToSuperview()
        }
        dateReset.snp.makeConstraints{make in
            make.top.equalTo(datePicker.snp.bottom).offset(50)
            make.left.right.equalToSuperview()
        }
    }
    
    
    @objc func datePickerValueDidChange(_ datepicker: UIDatePicker){
        DispatchQueue.main.async {
            let changeText : String = self.dateFormat.string(from: datepicker.date)
            
            self.dateLabel.text = changeText
            
            if(changeText == self.dateFormat.string(from: self.nowDate!)){
                self.dateReset.backgroundColor = .lightGray
            } else {
                self.dateReset.backgroundColor = .blue
            }
            
        }
    }
    
    @objc func dateResetAction(_ sender: UIButton){
        DispatchQueue.main.async {
            self.datePicker.date = self.nowDate ?? self.datePicker.date
            self.dateLabel.text = self.dateFormat.string(from: self.datePicker.date)
            self.dateReset.backgroundColor = .lightGray
        }
    }


}