[TIL] 계산기 앱: 버튼의 저주와 원형 복원기

Eden·2024년 11월 22일
2

TIL

목록 보기
49/92
post-thumbnail

배경

레벨 1에서 레벨 2로 넘어가는 과정에서 UIStackView를 이용해 버튼들을 그룹화하던 중, 버튼들이 예상한 정사각형이 아닌 타원형으로 나타나는 현상을 발견한다. 이로 인해 UI가 일관되지 않게 보이고, 디자인이 원하는 대로 구현되지 않는 개큰문제가 있었다.

발단


옹졸한 UI를 가진 계산기 전혀 눌러보고 싶지 않게 생겼다.




문제는 버튼들을 UIStackView에 추가하면서 발생하게 되었는데,,, 각 버튼의 widthheight를 고정값으로 설정했으나, UIStackViewdistribution 속성과 제약 조건이 충돌하면서 버튼들이 타원형으로 나타난다는 것을 알게 됐다. 특히, 스택 뷰의 spacing과 버튼 크기의 관계를 잘못 이해하여 의도하지 않은 레이아웃이 발생하게 되었다..

button.snp.makeConstraints { make in
    make.width.equalTo(80)
    make.height.equalTo(button.snp.width) // width와 height가 같도록 설정
}

위 코드에서 필수 조건을 구현하며 버튼의 너비와 높이를 같게 설정하려 했으나, 스택 뷰의 다른 제약 조건과 충돌하여 예상치 못한 결과가 나타난다.

전개

문제를 해결하기 위해 버튼의 크기와 스택 뷰의 제약 조건을 하나씩 재검토하게 되었다. 버튼의 widthheight를 각각 동일하게 설정하여 정사각형을 유지하려 했으나, 스택 뷰의 spacing과 버튼의 크기가 조화를 이루지 않아 여전히 버튼들이 타원형으로 보였다. 스택 뷰의 여러 속성도 조정해 보았지만, 문제는 해결되지 않았다.

stackView.axis = .horizontal
stackView.spacing = 10
stackView.distribution = .fillEqually

distribution.fillEqually로 설정했지만, 버튼들이 스택 뷰의 크기에 맞추어 세로로 늘어나면서 타원형이 되는 문제가 있었다.

위기

단순히 제약 조건을 변경하는 것만으로는 버튼 모양을 원하는 대로 만들 수 없다는 것을 깨닫는다. 특히, 스택 뷰 내부의 요소들이 부모 뷰의 크기에 따라 자동으로 크기가 조정되면서 버튼이 정사각형을 유지하지 못하는 문제가 있었다. 여러가지 코드가 꼬여 스파게티 코드가 되면서 손을 어디에 대야할지 인지조차 하지 못했다. 또한, cornerRadius 설정이 버튼의 높이와 너비의 불일치로 인해 원하는 대로 적용되지 않는 것도 문제였다.

button.layer.cornerRadius = 40 // 이렇게 해주었지만 버튼의 높이와 너비가 달라서 원형이 아닌 타원형으로 적용됨

cornerRadius가 버튼의 높이와 너비가 불일치할 때 올바르게 적용되지 않아, 버튼이 타원형으로 보이는 상황이 발생하게 된다.

절정

근본적인 해결을 위해 스택 뷰의 spacing을 적절히 조정하고, 버튼의 widthheight가 동일하게 유지되도록 제약 조건을 설정하게 된다. 또한, 버튼의 cornerRadius를 버튼의 너비의 절반으로 설정하여 항상 원형을 유지하도록 한다. 이를 위해 SnapKit을 사용하여 각 버튼에 명확한 제약 조건을 부여하고, 스택 뷰와 버튼 간의 간격을 조정하여 일관된 레이아웃을 만든다. 당시 코드에서 horizontalStackViewverticalStackView를 혼합 사용하여 버튼들이 스택 뷰 전체의 가로 또는 세로 공간을 균등하게 채우도록 설정했었고, 이로 인해 버튼의 크기가 스택 뷰와의 충돌로 타원형이 되는 문제가 발생했다. 예를 들어, 아래와 같은 코드가 문제가 되었다,,

private func setUpButtons() {
    var rowStackViews: [UIStackView] = []

    for row in calculatorButtonLabels {
        var rowButtons: [UIButton] = []
        for label in row {
            let button = makeButton(titleValue: label, action: nil, backgroundColor: isOperator(label) ? .orange : UIColor(red: 58/255, green: 58/255, blue: 58/255, alpha: 1.0))

            rowButtons.append(button)
            buttons.append(button)
        }
        // Horizontal Stack View 생성 및 버튼 추가
        let horizontalStackView = makeHorizontalStackView(rowButtons)
        rowStackViews.append(horizontalStackView)
    }

    // Vertical Stack View 생성 및 Horizontal Stack View 추가
    verticalStackView = UIStackView(arrangedSubviews: rowStackViews)
    verticalStackView.axis = .vertical
    verticalStackView.spacing = 10
    verticalStackView.distribution = .fillEqually

    view.addSubview(verticalStackView)
}

이 코드에서는 horizontalStackViewverticalStackView가 서로 간섭하여 버튼들이 타원형으로 보이게 되었던 것 같다.. 특히, horizontalStackView가 버튼을 가로로 정렬하면서 distribution 속성에 의해 버튼이 세로로 늘어나게 되어 정사각형을 유지하지 못하고 타원형으로 보이는 문제가 발생했다.

결말

최종적으로 버튼의 크기와 스택 뷰의 제약 조건을 재구성하여 모든 기기에서 일관된 레이아웃을 유지할 수 있도록 문제를 해결했다. 원래는 레벨 5에서 다루어야 할 문제였지만, 예상치 않게 레벨 2 단계에서 해결하게 되었다😵‍💫😵‍💫😵‍💫😵‍💫. 버튼의 크기를 스택 뷰의 크기에 맞춰 조정하면서 원형을 유지하도록 개선할 수 있었다. 이를 통해 버튼들이 타원형이 아닌 일관된 원형으로 보이도록 만들고, UI 역시 모든 기기에서 동일하게 유지될 수 있게 했다. 또한, NSLayoutConstraint 충돌 문제를 해결하기 위해 각 제약 조건을 명확히 정의하고, 스택 뷰와 버튼 간의 제약을 조정하여 자동 레이아웃 충돌을 방지하도록 했다.
어떻게든 만들어 지긴 한다 👍🏼

profile
Frontend🌐 and iOS

1개의 댓글

comment-user-thumbnail
2024년 11월 22일

옹졸한 버튼도 꽤나 기업은행

답글 달기