Skip to content

[Feature] UISegmentControl UI 제작 및 로직구현 #1

@Parkjju

Description

@Parkjju
2023-10-22.12.45.57.mov

해결과정

  1. UISegmentControl 클래스를 상속받는 커스텀 UnderlineSegmentControl 정의
  2. didMoveToSuperView 라이프사이클에서 기본적인 언더라인 세그먼트 구현을 위한 기본설정 (setBackgroundImage & 서브뷰 추가)
  3. 언더라인 뷰의 초기 너비값은 segmentControl 너비값을 전체 아이템 갯수로 나눈 값

1. 세그먼트 탭 이후

  1. titleTextAttributes 함수를 통해 텍스트의 intrinsicSize 너비값을 구한다
  2. 세그먼트 컨트롤 너비는 상위 뷰의 오토레이아웃 설정 과정에서 고정되므로 아이템 갯수만큼 나눈 이후의 너비값도 고정된다
  3. 공평하게 나뉜 너비값에서 아이템별 텍스트 고유 사이즈를 빼주고 이를 2로 나누면 언더라인 뷰의 origin x값의 위치가 결정된다
  4. UIView animate 클로저에서 위치를 지정
 func moveUnderlineView() {
    let fontAttributes = titleTextAttributes(for: .normal)
    guard let title = titleForSegment(at: self.selectedSegmentIndex) else { return }
    let size = title.size(withAttributes: fontAttributes)
    
    let perSegmentWidth = self.bounds.width / CGFloat(self.numberOfSegments) // 세그먼트 별 길이
    let underlineFinalXPosition = (perSegmentWidth * CGFloat(self.selectedSegmentIndex)) + (perSegmentWidth - size.width) / 2
    
    self.underlineView.frame.origin.x = previousXPosition
    
    UIView.animate(
        withDuration: 0.1,
        animations: {
            self.previousXPosition = underlineFinalXPosition
            self.underlineView.frame.origin.x = underlineFinalXPosition
        }
    )
}

세그먼트 탭은 상위 뷰에서 rx 컨트롤 이벤트를 통해 drive하여 함수 호출

2. 언더라인 너비 업데이트

  1. 초기 언더라인 너비값은 고정이지만 텍스트 고유 사이즈에 따라 너비를 업데이트 해줘야 함
  2. 예컨대 포즈피드는 네글자, 포즈톡&북마크&포즈픽은 세 글자이므로 고유 사이즈가 다름
  3. 심지어 자음별 크기에 따라 너비값이 다르게 산정되는 경우도 있을 수 있다
  4. moveUnderlineView 함수에서 사용한 것과 동일하게 텍스트 고유 사이즈를 얻고 UIView.animate 클로저에서 너비를 업데이트해준다
  5. 언더라인뷰는 UnderlineSegmentControl 클래스의 서브 뷰이므로, self.layoutIfNeeded()를 클로저에서 호출해주면 레이아웃이 자동으로 업데이트된다.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions