VariableHeight TableHeaderView

sanghoon Ahn·2021년 6월 21일
0

Daily Issue

목록 보기
6/9

Daily Issue #6

안녕하세요 dvHuni입니다!

이전에 포스팅했던 UITableViewHeader, Footer View 한번에 만들기 글에 이어서 포스팅을 진행하려합니다.

조금 늦었지만...

그래도 빼먹지 않고 알아보고 포스팅 했다는거... 🥲

데일리 이슈의 여섯번째 포스트 !! 출발!!!🏃


무엇이 문제입니까?

이전에 포스팅에서는 Table HeaderView를 아래와 같이 Frame을 지정하고,

property를 할당했습니다.

tableHeaderView.frame = CGRect(x: 0, y: 0, width: view.bounds.width, height: 100)
tableView.tableHeaderView = tableHeaderView

그러나.. 이렇게 height를 지정해버리면..

내용이 넘쳐버릴때는 대응 하지 못하겠죠 ?

예를들어

위와같이 글자가 넘쳐버리는 상황이 발생한다면 ...??

headerView의 height을 변경해야 하는 상황이 필요합니다.

여러가지 방법을 시도해보았고, 실패로 이어졌지만 ... 검색을 통해 해답을 찾아냈습니다.

https://www.python2.net/questions-5066.html

결론은

변경될 height을 계산해서 직접 심어줘야 하는 것입니다. 😵

우선 실제 상황을 가정하고 시나리오를 작성해보겠습니다.

  1. height를 지정한 headerView가 노출
  2. API를 호출하여 headerView의 변경될 내용을 가져옴
  3. 변경된 내용을 적용하면, headerView의 height이 변경된다고 가정

1번은 headerView를 노출 시키는것으로 완료되었고,

2번은 API 로직을 만들기는 번거로우니 몇 초 뒤 변경된 내용을 가져왔다고 가정하고

마지막으로 3번은 변경된 height을 계산한 값만 지정해 주는 것으로 하겠습니다.

// 2번을 위한 코드
override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 3) { [weak self] in
        self?.updateHederViewHeight()
    }
}

// 3번을 위한 코드
@objc
private func updateHederViewHeight() {
		let calculatedHeight: CGFloat = 200 // #1
    tableHeaderView.frame = CGRect(x: 0, y: 0, width: view.bounds.width, height: 200) // #2

    tableView.tableHeaderView = tableHeaderView // #3
}

updateHeaderViewHeight메소드 안에서는

계산된 내용들의 height를 calculatedHeight로 지정하고(#1),

해당 height로 다시 headerView의 frame을 지정 한 후(#2),

tableView.tableHeaderView에 다시 headerView를 할당(#3)하는 코드입니다.

빌드해보면~

height이 잘 변경되네요!!

height를 200으로 가정하고 했지만 정확히 하려면 글자가 셋팅된 label의 height를 가져와야겠네요!

class HuniHeaderView: UIView {
  let label = UILabel()
  
  var contentHeight: CGFloat {
      label.bounds.height
  }
..
..
..
  func setText(_ text: String) {
      label.text = text
  }
}

텍스트를 셋팅하고, contentHeight를 불러오면~?

private func updateHederViewHeight() {
    let calculatedHeight: CGFloat = tableHeaderView.contentHeight
    tableHeaderView.frame = CGRect(x: 0, y: 0, width: view.bounds.width, height: calculatedHeight)
    
    tableView.tableHeaderView = tableHeaderView
}

updateHederViewHeight 메소드를 다음과 같이 수정 할 수 있겠네요!

마지막으로 빌드해보면?!

아 !! 그전에 로직을 조금 수정했습니다

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 3) { [weak self] in
        self?.updateContent()
    }
}

@objc
private func updateContent() {
    tableHeaderView.setText("""
            안녕하세요 ! dvHuni입니다.\n
            데일리 이슈 4번째 포스트!!\n
            UITableViewHeaderView&FooterView\n
            삽입하기 입니다!
            """)
    tableHeaderView.layoutIfNeeded()
    updateHederViewHeight()
}

private func updateHederViewHeight() {
    let calculatedHeight: CGFloat = tableHeaderView.contentHeight
    tableHeaderView.frame = CGRect(x: 0, y: 0, width: view.bounds.width, height: calculatedHeight)
    
    tableView.tableHeaderView = tableHeaderView
}

API를 통해 변경된 내용을 가져 온 후, updateContent를 실행한다고 가정했을때,

setText를 호출하여 변경된 내용을 셋팅하고 UI를 업데이트 해주어야 합니다!

따라서 tableHeaderView.layoutIfNeeded() 메소드를 호출 하고,

updateHederViewHeight를 호출했습니다!!

다시 실행영상을 보시면~

이전과는 다르게 height이 딱 맞아 떨어집니다 😋

이상으로 가변 height tableHeaderView를 시도해 보았습니다!

고민했던 부분을 해결했더니 조금 상쾌하네요~

아! FooterView도 동일한 로직일 것 같은데 코드를 빠른 시일내에 올려보도록 하겠습니다!!
빼먹지 않도록 메모도 꼭 해두겠습니다 😅

전체 코드는 깃허브에 있습니다!!


지적이나 질문은 저에게 큰 도움이 됩니다 🤓

오늘도 읽어주셔서 감사합니다 🙇🏻‍♂️

profile
hello, iOS

0개의 댓글