원형 버튼을 만들려면 버튼을 만들고 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에 대해 다시 배우게 되어서 좋았다.