iOS 15.0 UIButton

hey_hen·2022년 1월 16일
0

WWDC2021가 발표한지는 한참 지났지만, 정리해보는 UIButton,
iOS15.0의 버튼이 특별히 달라지는 것은 아니지만, 기존에 서브클래싱 등으로 해결해야 했던것을 Configuration을 통해 제공해주는 것이 핵심이다.

Basic Style

iOS15.0 UIButton은 기본 4가지 스타일을 제공한다.

  • Plain
  • Gray
  • Tinted
  • Filed

전통적인 UIButton은 다음과 같을 것이다.

let button = UIButton(type: .system)
button.setTitle("Sign In", for: [])

여기에 Basic Style을 적용하는 방법은 아래와 같다.

let button = UIButton(type: .system)
button.setTitle("Sign In", for: [])
button.configuration = .filled()

Basic Style을 적용해서 BackgroundColor Tint와CornerRadius가 있는 버튼을 빠르게 얻을 수 있다.
바닐라 스타일을 사용하는 사람들에게는 편리한 기능으로 보인다.

UIButton.Configuration

UIButton 인스턴스를 생성 한 후에, 프로퍼티들을 바꾸는 것이 아니라, UIButton.Configuration을 미리 만들고, UIButton 인스턴스를 만들 때 configuration을 생성자에 전달할 수 있다.
이 방법은 굳이 UIButton을 서브클래싱 하는 것보다 더 나은 재사용성을 누릴 수 있다.

위 예제에서는 button을 생성 한 뒤에, 타이틀을 입력했지만 configuration을 사용하면 아래와 같이 할 수 있다.

var config = UIButton.Configuration.tinted()
config.title = "Hello, Swift!"
config.image = UIImage(systemName: "swift")

let button = UIButton(
  configuration: config,
  primaryAction: UIAction(handler: { _ in
    print("Hello, Swift!")
  }))

configuration에는 다양한 옵션이 있기 때문에 입맛대로 사용하기도 편하다.
예를들어서 이미지 위치가 왼쪽이 아니라 오른쪽에 위치했으면 좋겠다고 한다면

config.imagePlacement = .trailing

이 한출 추가하는 것으로 이미지는 오른쪽으로 이동한다.

이 외에도 타이틀과 이미지의 패딩, 타이틀의 정렬 기준 등등 다양하기 때문에 문서를 보고 사용해 보길 권장

ConfigurationUpdateHandler

Button을 사용하다보면, 항상 똑같은 모습을 보여주는 정적인 버튼 말고도, 상태에 따라 변하는 동적인 버튼을 많이 사용한다.
기존에는 버튼 상태를 나타내는 모델에서 모델이 변경되면 버튼을 업데이트 하도록 구성할 수 있었다.

   button.configurationUpdateHandler =  { [unowned self] button in
      var config = button.configuration
      config?.title = "오늘의 할일"
      config?.image = self.done
      ? UIImage(systemName: "checkmark.square.fill")
      : UIImage(systemName: "square")
      config?.subtitle = self.done
      ? "01/16 Done!"
      : "01/16"
      button.configuration = config
    }
button.setNeedsUpdateConfiguration()

setNeedsUpdateConfiguration()을 호출해서, 버튼 UI의 갱신상태를 변경 요청할 수 있다.

Other Features

Button.Configuration은 이외에도 다양하고 유용한 기능을 제공한다.

  • Activity Indicator: UIButton에 별도로 서브클래싱 없이 Activity Indicator를 넣을 수 있다.
  • Metrics adjustments: 타이틀, 이미지, 서브 타이틀간의 위치를 설정할 수 있다.
  • Semantic styling: 버튼을 만들기가 더 쉬워졌다.
  • Customization: Color, TextAttribute 등 커스텀에 필요한 기능을 Configuration을 통해 제공한다.

기존에 UIButton에 Activity Indicator를 이용하려면 서브클래싱을 통해서 해야했는데 Button.Configuration에 이 기능이 들어갔다.


var loggin: Bool = false {
    didSet {
      button.setNeedsUpdateConfiguration()
      button.isEnabled = !loggin
    }
  }

button.configurationUpdateHandler =  { [unowned self] button in
      var config = button.configuration
      config?.title = "Sign In"
      config?.showsActivityIndicator = loggin
      config?.image = UIImage(systemName: "externaldrive.connected.to.line.below")
      button.configuration = config
    }
    
func requestLoggin() {
  loggin = true
  //Network Request Code
  DispatchQueue.main.asyncAfter(deadline: .now() + 2.5) {
     self.loggin = false
  }
}   
 

configurationUpdateHandler()showActivityIndicator만 설정해 주면 된다.
예를들어서 로그인을 요청하면 서버에서 응답이 올때까지 버튼에 인디케이터가 표시 되어야 하는 경우, 다음 과 같이 코드를 작성할 수 있다.

Toggle Button

버튼의 On/Off 상태를 좀더 편리하게 사용해주는 새 기능으로 해당 프로퍼티를 true로 설정하게 되면 버튼 선택에 따른 상태를 얻을 수 있다.

button.changesSelectionAsPrimaryAction = true

changeSelectionAsPrimaryAction을 true로 하면 버튼 토글 상태가 button.isSelected로 전달된다.
맨 위에서 했던 예제로 다시 돌아가자면

button.changesSelectionAsPrimaryAction = true

button.configurationUpdateHandler =  { button in
  var config = button.configuration
  config?.title = "오늘의 할일"
  config?.image = button.isSelected
  ? UIImage(systemName: "checkmark.square.fill")
  : UIImage(systemName: "square")
  config?.subtitle = button.isSelected
  ? "01/16 Done!"
  : "01/16"
  button.configuration = config
}

버튼의 상태를 isSelected로 선택해볼 수 있다.

Pop-up button

버튼을 구성할 때 팝업 버튼 형식으로 쓰고 싶을 때는 showMenuAsPrimaryActiontrue로 두기만 하면 된다.

button.showsMenuAsPrimaryAction = true
button.menu = UIMenu(children: [
  UIAction(title: "삭제하기", attributes: .destructive, handler: deleteComment),
  UIAction(title: "수정하기", handler: editComment)
])

만약 팝업 버튼 안에서 토글 방식이 필요하다면 changeSelectionAsPrimaryAction을 true로 두면 팝업 안에서 토글 형식으로 쓸 수 있다

button.showsMenuAsPrimaryAction = true
button.menu = UIMenu(children: [
  UIAction(title: "매일반복", handler: repeatEveryday),
  UIAction(title: "요일반복", handler: repeatDay)
])
button.changesSelectionAsPrimaryAction = true

각 예제 프로젝트는 TIL에서 보실 수 있습니다.
https://github.com/urijan44/TIL-Store/tree/master/iOS_Swift/UIKit/UIButtonConfiguration.playground

profile
iOS Dev, Coffee in my bloodstream

0개의 댓글