본문 바로가기

DEV

[iOS/Swift] UIKit 원형 버튼 만들기 (feat. viewDidLayoutSubviews)

반응형

원형 버튼을 만들려면 버튼을 만들고 cornerRadius의 값을 맞게 변경해 주면 된다.

아래와 같이 버튼의 크기값의 반을 layer.cornerRadius에 넣어주면 원형 버튼을 만들 수 있다.

button.layer.cornerRadius = button.frame.width / 2

 

하지만 해당 코드가 내 뷰에는 적용이 안된다.

button.frame.width를 print 해보니 0.0이라는 값이 뜬다.

결국 button.layer.cornerRadius = 20 처럼 직접 넣어줘야 했다.

왜 그럴까?

 

Grok한테 물어봤다.

 

현재 코드에선 SnapKit으로 해당 버튼의 width, height 값을 설정해 주었고, 그 코드들은 아래 configureLayout() 함수에 들어있다.

그래서 당연하게도 나중에 값을 지정하도록 되어있기에 0이 출력되는 것이었다.

 

그러면 해결하기 위해선 button의 width, height 값이 설정된 후에 cornerRadius를 button.frame.width / 2로 설정하면 된다.

아래처럼 뷰 설정 시 width, height 값을 준 후 설정해도 되지만, Auto Layout을 사용하여 구현하기 위해 넘어간다.

private lazy var seriesOrder: UIButton = {
    let button = UIButton()
    button.setTitle("1", for: .normal)
    button.titleLabel?.font = .systemFont(ofSize: 16)
    button.backgroundColor = .systemBlue
    button.layer.masksToBounds = true
    
    // frame으로 크기 설정
    button.frame = CGRect(x: 0, y: 0, width: 40, height: 40)
    button.layer.cornerRadius = button.frame.width / 2
    print("Button frame width: \(button.frame.width)") // 40 출력
    
    // Auto Layout 제약 조건을 무시하도록 설정 (기본값이 true)
    button.translatesAutoresizingMaskIntoConstraints = true
    return button
}()

 

button의 width, height 값이 설정된 후, 즉 버튼의 frame이 확정되는 시점은 뷰가 레이아웃을 완료한 후이다.

뷰가 모든 서브 뷰들의 레이아웃을 완료한 후 값을 설정하기 위해서는 viewDidLayoutSubviews를 이용하면 된다.

private lazy var seriesOrder: UIButton = {
    let button = UIButton()
    button.setTitle("1", for: .normal)
    button.titleLabel?.font = .systemFont(ofSize: 16)
    button.backgroundColor = .systemBlue
    button.layer.masksToBounds = true
    return button
}()

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    seriesOrder.layer.cornerRadius = seriesOrder.frame.width / 2
    print("Updated frame width: \(seriesOrder.frame.width)") // 40 출력
}

 

원하는대로 동작하였다.

 

근데 굳이 이렇게 할 필요 없이 기존처럼 button.layer.cornerRadius = 20를 직접 입력했던 것이 더 편해 보이기도 한다.

현재는 하드코딩 되어있는 값을 넣었지만, 변수로 넣는다고 생각하면 cornerRadius = 변수 / 2만 하면 되기 때문이다.

 

만약, 버튼 크기가 가변적이면 필요하겠다만 현재 프로젝트에서 버튼 크기는 변하지 않기에 여기서는 굳이 이렇게 코드를 안 짜도 되겠다고 생각한다.

그래도 이번에 viewDidLayoutSubviews에 대해 다시 배우게 되어서 좋았다.

반응형