samsung-ga / woody-iOS-tip

🐶 iOS에 대한 소소한 팁들과 개발하다 마주친 버그 해결기, 그리고 오늘 배운 것들을 모아둔 레포
19 stars 0 forks source link

[TIL] iOS 기본 버튼 커스텀 해보기 #22

Open samsung-ga opened 2 years ago

samsung-ga commented 2 years ago

버튼의 타입과 스타일, 그리고 일반적인 버튼에서 어느정도까지 커스텀이 될까에 대해 알아보고자 작성한 글이다. 먼저 버튼의 프로퍼티에는 무엇이 있는 지 알아보자.

Button type

총 7가지의 타입이 있다.

아래 타입부터는 이미지가 타입마다 각각 추가된다.


image


헷갈릴 수 있는 부분 🤯

👉🏻 System 타입과 Custom 타입의 차이는 아래 gif와 같다. 시스템 스타일을 채택하고 있는 시스템 타입과 아무 스타일이 없는 커스텀 타입이다. 눌렀을 때, title의 색상의 차이를 볼 수 있다.

👉🏻 System 타입과 Custom 타입을 코드로 구현하면 위와 같은 차이점이 있지만 스토리보드로 만들었더니 이상하게 동작되는 버그가 있다. 예제 파일에 있지만, 이것은 버그가 확실한 것 같다. 웬만해서 코드로 구현하도록 하자.



👉🏻 위 Detail Disclosure ~ Close 네가지 타입들로 생성할 경우 title과 image의 inset이 먹지 않는다. 왜 그럴까? 시스템 내에서 생성해주는 것이므로 내부 코드를 모르기 때문에 일단, 그렇구나!라고 생각하고 넘어가자. 아래 사진에서 불편하게 아이콘과 타이틀의 사이 간격이 붙어 있는 것을 볼 수 있다.


스크린샷 2022-07-08 오전 12 39 51


👉🏻 위의 추측대는 한가지 이유로는 title과 image의 inset 조절해주는 imageEdgeInsets titleEdgeInsets 이 두가지 프로퍼티는 iOS 15.0에서 deprecated 된다. 그러므로, 이를 생각해서 configuration을 애용하자.

스크린샷 2022-07-08 오전 1 27 08

참고 - Button.Type 문서

Button Style

4가지 버튼 스타일이 있다. 이 버튼들은 모두 button configuration을 이용하여 생성할 수 있으며, 사이즈를 변경하고 싶다면 아래 Inspector에서 가능하다. 대신 contentInset, imageEdgeInsets등 inset을 조절하는 프로퍼티는 먹히지 않는다. (deprecated)

스크린샷 2022-07-08 오전 12 48 33

아래 두개는 정의가 비슷해보여서 일단 생략. 문서를 보고서 해석하자.

참고 - UIButton.Configuration 문서

헷갈릴 수 있는 부분 🤯

👉🏻 cornerRadius 주는 방법의 차이 기존엔 layer에 cornerRadius를 주었다면 configuration으로 생성한 버튼은 configuration을 이용해야 한다.

👉🏻 font 주는 방법의 차이 기존엔 titleLabel의 font를 바꾸었다면 configuration으로 생성한 버튼은 configuration의 attribute를 바꿔야 한다. AttributedString()도 추후 알아보자.

👉🏻 추가적으로 configuration을 이용하여 할 수 있는 것들이 굉장히 많아졌다. 이 블로그 - Configuration의 프로퍼티들를 참고하자.

// ✅ configuration을 이용하여
private lazy var button4: UIButton = {
    $0.translatesAutoresizingMaskIntoConstraints = false
    $0.configuration?.cornerStyle = .dynamic
    $0.configuration?.background.cornerRadius = 16
    $0.configuration?.title = "버튼4"
    $0.configuration?.image = UIImage(systemName: "paperplane")
    $0.configuration?.imagePlacement = .trailing

    var container = AttributeContainer()
    container.font = UIFont.boldSystemFont(ofSize: 25)

    $0.configuration?.attributedTitle = AttributedString("버튼4", attributes: container)

    return $0
}(UIButton(configuration: .filled()))

👉🏻 물론 configuration말고 primaryAction을 이용해서도 버튼을 생성할 수 있다. addTarget도 가능!

private lazy var button5: UIButton = {
    ...
    return $0
}(UIButton(configuration: .filled(), primaryAction: UIAction(handler: { action in
    print("button5 눌림")
})))
samsung-ga commented 2 years ago

커스텀 버튼 이미지 부분의 color를 바꿔야할 경우

let view = UIView()

let image = UIImage(named: "arrow_white")
let imageView = UIImageView(image: image)
imageView.bounds.size = CGSize(width: 16, height: 16)
view.addSubview(imageView)
view.frame = .init(x: 0, y: 0, width: 40, height: 40)
view.layer.cornerRadius = 20
imageView.center = view.center
view.backgroundColor = .init(rgb: 0x242424)

$0.configuration?.image = view.asImage()