Skip to content

Layout Layers

Song edited this page Aug 5, 2021 · 4 revisions

2021-08-04

by Song

  • Layer는 AutoLayout의 영향을 받지 않는다 (Contraints 적용이 불가능하다)
  • ViewController의 ViewDidLoad 호출 전 Layer 설정 시, AutoLayout 완성에 따른 변화 추적이 필요하다

Step 1 - viewDidLayoutSubviews

ViewController의 viewDidLayoutSubviews 호출 시 Layer 재설정해주기

  • Layout이 변경될 시 호출되는 viewDidLayoutSubviews 메소드를 통해 Custom View의 Layer 재설정
  • Text의 길이, 라인 수에 따라 사이즈 변화가 필요한 TextPresentView의 예시
// View Controller
override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    titleView.layoutSubviews(with: Text.title)
}
// CATextLayer를 통해 Text를 표시하는 TextPresentView 메소드
func layoutSubviews(with text: String) {
    super.layoutSubviews()
    resizeTextLayer(with: text)
}

private func resizeTextLayer(with text: String) {
    textLayer.fontSize = newFontSize(for: text)
    adjustTextLayerFrameToCenter(for: text)
}

-> viewDidLayoutSubviews가 너무 자주 불린다!

  • User interaction에 아주 민감하게 반응하여 숨쉬듯 호출된다.
  • Text를 전달인자로 받고 있기 때문에, viewDidLayoutSubviews 메소드의 Text와 다른 Text를 전달하고 싶은 경우 원하지 않는 결과를 얻게될 수 있다. -> 다른 메소드에서 Layer의 Text를 다른 것으로 변경하더라도 viewDidLayoutSubviews 호출로 인해 변경되지 않았다.
  • 상위 View의 크기 변화가 감지됐을 때만 Layer 사이즈를 변화시키는 것이 나을 것으로 판단

2021-08-05

by Song

Step 2 - superview의 bounds 변화 감지

RxCocoa 메소드 활용

  • Layer의 superview bounds 변화를 감지한다
  • 변화가 있을 때마다 layer의 위치를 재정렬한다
// viewDidLoad에서 set up
private func setInfoViewObserver() {
    infoView.rx.observe(CGRect.self, "bounds")
        .subscribe(onNext: { [unowned self ] _ in
            self.infoView.layoutSubviews(with: Text.shopReset)
        }).disposed(by: rx.disposeBag)
}

Clone this wiki locally