Starbucks Caramel Frappuccino
본문 바로가기
  • 그래 그렇게 조금씩
UIKit/AutoLayout

18 - Changing Constraints 제약 변경

by Toughie 2023. 4. 4.

https://developer.apple.com/library/archive/documentation/UserExperience/Conceptual/AutolayoutPG/ModifyingConstraints.html

 

Auto Layout Guide: Changing Constraints

 

developer.apple.com

제약을 변경하는 방법은?

(키보드가 올라올 때 뷰를 위로 쓱 올려서 가려지지 않게 하는 등..)

 

- 제약 활성화 / 비활성화

- 제약의 상수 변경

- 제약의 우선도 변경

- 뷰 계층에서 제약 삭제

 

제약을 변경하면 레이아웃 엔진이 뷰프레임에 바로 업데이트 하는 것이 아니라 잠깐 뒤에 업데이트 한다.

(너무 순식간이라 사실 사람 눈에는.. 안보인다. 뷰 업데이트 주기가 1/60초, 1/120초 이러니)

 

제약은 multiplier 조절 불가능.. 상수로 변경 가능하다.

그리고 지우는 것보다 활성/비활성화 방식이 좋음.

 

기존 self-sizing 프로젝트에서 셀을 터치했을 때 글자가 잘 표시되도록 셀이 아래로 늘어나도록 해보자.

-1
//먼저 해당 레이블(* postLabel)의 높이변경을 위한 변수를 만들어 준다.
//"안녕하세요 터피입니다. "안녕하세요 터피입니다. ..."

private var postHeight = NSLayoutConstraint!


-2
awakeFromNib() { 
...

postHeight = postLabel.heightAnchor.constraint(lessThanOrEqualToConstant: 50)
// 50보다는 커지지 않게 높이 할당

}

-3
postHeight을 활성화 해준다.

NSLayoutConstraint.activate( [
...

postHeight
])

-4
postLabel을 탭했을 때 postHeight이 활성/비활성화 되기 때문에
레이블에 제스처를 추가해줘야 한다.

마찬가지로 awakeFromNimb() 안에..

let tapGesture = UITapGestureRecognizer(target: self, action: #selector(togglePost)

//포스트레이블에 제스처를 붙여준다.
postLabel.addGestureRecognizer(tapGesture)
//유저가 실제로 탭할 수 있도록 설정해 준다.
postLabel.isUserInteractionEnabled = true

//selector
@objc private func togglePost() {
	guard let height = postHeight else { return }
    //height.isActive = !height.isActive
    height.isActive.toggle()
    //bool값 스위칭 하니까 .toggle()을 쓰면 편함
}

근데 여기까지만 하면 제대로 안 됨 ㅎㅎㅎㅎ
셀의 높이가 변한다는 것을 tableView가 모르기 때문임.

-5
그래서 알림센터를 통해 셀의 높이가 변했음을 알리자.

@objc private func togglePost() {
	guard let height = postHeight else { return }

    height.isActive.toggle()
    
    NotificationCenter.default.post(
    name: NSNotification.Name("layoutcell"), object: nil
    )
}

-6
그리고 뷰컨트롤러로 가서 해당 노티를 받을 수 있도록 코드를 추가해 주자.

viewDidLoad로 가서 옵저버를 추가해 준다.

override func viewDidLoad() {
    super.viewDidload()
    
    NotificationCenter.default.addObserver(forName: NSNotification.Name("layoutCell"),
                                           object: nil,
                                           queue: OperationQueue.main) { noti in
        //뷰컨에서노티를 받으면 테이블뷰가 refresh 하도록
        self.tableView.beginUPdates()
        self.tableView.endUPdates()
    	}
	}

 

 

셀 높이 제약 변경

셀에 제스처 추가

업데이트를 위한 노티피케이션 센터

델리게이트 패턴으로 인한 뷰컨트롤러 설정 등..

 

생각보다 작성해야 하는 코드가 많아서 꽤 복잡하게 느껴진다.

 

[학습 소스]

공식문서, 야곰 오토레이아웃 정복하기 강의

https://developer.apple.com/library/archive/documentation/UserExperience/Conceptual/AutolayoutPG/index.html

https://yagom.net/courses/autolayout/https://yagom.net/courses/autolayout/