[ swift ] 영화앱 4. 더보기 버튼 표시 여부

sonny·2024년 12월 19일
1

TIL

목록 보기
76/133

소개글이 짧은대도 불구하고 더보기 버튼이 나오는게 싫었던 팀원 B씨를 위해 수정했습니다

이름하야 더보기 버튼 글자 수에 따라 안보이게 하기이이-


'더보기' 버튼 접기 펴기 구현 과정

영화 상세 정보를 표시하는 앱에서 소개 글(overview)의 길이에 따라 '더보기' 버튼을 표시하거나 숨기는 기능이 필요했다.

글이 짧은 경우 '더보기' 버튼을 숨기고, 긴 경우 버튼을 통해 '더보기' 또는 '접기'를 전환하도록 했는데,

확실히 이런 기능 하나가 사용자 경험을 개선할 수 있다는 것 때문에 더 확실히 해두고 싶었다.

그렇게 긴 텍스트로 인해 화면이 과도하게 차지되는 문제를 방지하고자 시작을 해보았다.

텍스트 길이에 따른 버튼 표시 여부 결정

descriptionLabel의 텍스트 길이를 기준으로 toggleButton의 표시 여부를 제어했다.

  • 버튼이 표시되는 조건
    • 글자 수가 120자 이상인 경우 '더보기' 버튼이 나타난다.
  • 버튼이 숨겨지는 조건
    • 글자 수가 120자 미만인 경우 '더보기' 버튼은 숨겨진다.
   private func refreshToggle() {
       guard let text = descriptionLabel.text else {
           toggleButton.isHidden = true
           return
       }

       let minTextLength = 120
       toggleButton.isHidden = text.count <= minTextLength
   }

'더보기'와 '접기' 상태 전환

  • isExpanded라는 Boolean 속성을 이용해서 텍스트가 펼쳐진 상태인지 접힌 상태인지 확인할수 있었다.
  • '더보기' 상태에서는 descriptionLabel.numberOfLines를 제한해서 텍스트를 줄여 표시하고, 버튼 텍스트를 '더보기'로 설정했다.
  • '접기' 상태에서는 descriptionLabel.numberOfLines를 0으로 설정해 모든 텍스트를 표시하고, 버튼 텍스트를 '접기'로 변경했다.
   @objc private func toggleText() {
       isExpanded.toggle()

       if isExpanded {
           descriptionLabel.numberOfLines = 0
           toggleButton.setTitle("접기", for: .normal)
       } else {
           descriptionLabel.numberOfLines = 5
           toggleButton.setTitle("더보기", for: .normal)
       }

       refreshToggle()
   }

동적 데이터와의 연동

  • fetchMovieDetails 함수에서 API로부터 받아온 overview 텍스트의 글자 수를 확인하여 updateDescription 메서드로 전달했다.
  • 그리고 updateDescription 메서드는 텍스트를 descriptionLabel에 설정하고, refreshToggle을 호출하여 버튼의 상태를 업데이트하도록 했다.
   func updateDescription(with text: String) {
       descriptionLabel.text = text
       refreshToggle()
       setNeedsLayout()
       layoutIfNeeded()
   }

1. refreshToggle()

refreshToggle()은 별도의 메서드로, 상태를 갱신하거나 UI를 업데이트하는 추가적인 작업을 수행할 가능성이 크다.

예를 들어 특정 조건에 따라 버튼을 활성화하거나, 표시되는 데이터를 변경하는 작업을 수행할 수 있다.

2. setNeedsLayout()

이 메서드는 레이아웃이 변경되었음을 뷰 계층 구조에 알리고 실제로 레이아웃 업데이트는 다음 렌더링 사이클에서 이루어진다.

쉽게 말하자면 변경 사항이 즉시 적용되지 않고, 시스템이 적절한 시점에 적용한다는 뜻이다.

3. layoutIfNeeded()

이 메서드는 뷰가 지금 바로 레이아웃을 업데이트하도록 강제한다.

setNeedsLayout()은 "업데이트가 필요함"을 표시하는 반면,

layoutIfNeeded()는 즉시 레이아웃을 조정해 뷰의 변경 사항을 화면에 반영한다.

이 메서드는 뷰가 이미 업데이트되어야 하는 상태일 때 호출되는데,

setNeedsLayout()과 함께 사용하여 레이아웃 무결성을 유지할 수 있다.


트러블슈팅

'더보기' 버튼이 항상 보이는 문제

API에서 overview 텍스트를 받아왔을 때, 글자 수가 120자 미맘임에도 불구하고 '더보기' 버튼이 표시되는 문제가 있었다.

  • 원인
    • descriptionLabel.text가 설정되기 전에 refreshToggle이 호출되어 텍스트 길이를 정확히 인식하지 못한 것이 원인이었다.
  • 해결
    • updateDescription에서 descriptionLabel.text를 먼저 설정한 후 refreshToggle을 호출하도록 순서를 조정했는데 다행히 글자수가 120자 미만이면 더보기 버튼이 잘 사라지게 되었다.

레이아웃 갱신이 제대로 이루어지지 않는 문제

텍스트가 길어졌을 때, 레이블의 높이가 즉시 업데이트되지 않아 UI가 어색하게 보이는 문제가 있었다.

  • 해결
    • setNeedsLayoutlayoutIfNeeded를 호출하여 레이아웃 변경을 즉시 반영하도록 해봤다.
  1. 글자 수 로그 추가로 디버깅

    • 문제를 파악하기 위해 fetchMovieDetails에서 overview 텍스트의 글자 수를 출력하는 로그를 추가했다.
   let overviewText = detailData.overview
   print("오버뷰 텍스트 글자 수: \(overviewText.count)")

로그를 추가하면서 디버깅을 하는 과정이 꽤나 재미있었다.


결과

글자수 제한을 두어 짧은 글은 더보기가 나오지 않는 것을 확인할 수 있었다.

그리고 설명이 없는 영화의 경우 내용이 없음을 알려주었다.


음...

이 과정에서 동적 데이터 처리 시점레이아웃 갱신의 중요성을 알게 된 날이었다.

그 중에서 버튼 상태 업데이트 로직을 텍스트 설정 이후로 변경함으로써 문제를 해결할 수 있었는데, 여기서 추가적으로 API 데이터를 디버깅하기 위해 했던 로그 출력이 문제를 빠르게 파악하는데 큰 도움이 되었다.

로그 찍어보라고 했던 팀원분 감사합니다.

향후 비슷한 기능을 구현할 때는 다음 사항에 유의하려고 한다.

  • 데이터 변경과 UI 업데이트 간의 순서를 명확히 정리하기.
  • 동적인 UI 갱신이 필요한 경우 레이아웃 갱신 메서드를 적절히 활용하기.
  • 디버깅 로그를 통해 문제를 명확히 분석하고 기록을 남기기.... 꼭
profile
iOS 좋아. swift 좋아.

0개의 댓글

관련 채용 정보