WWDC21) UIKit Button System

pcsoyeon·2021년 10월 22일
0

Deprecated property/method in UIButton

  • reversesTitleShadowWhenHighlighted
  • adjustsImageWhenHighlighted
  • adjustsImageWhenDisabled
  • showsTouchWhenHighlighted
  • contentEdgeInsets
  • titleEdgeInsets
  • imageEdgeInsets
  • backgroundRect(forBounds:)
  • contentRect(forBounds:)
  • titleRect(forContentRect:)
  • imageRect(forContentRect:)
  • adjustsImageWhenHighlighted
  • titleEdgeInsets
    ... 대략 이정도가 deprecated 된 속성들이다 .. (생각보다 많다 .. 아직 저 속성들 제대로 써보지도 않았는데 .. 혼자 저 멀리 가는 swift)

What's new

  1. Gray, Tinted, Filled 스타일의 버튼이 추가

  2. Multiple Line Text 지원

  3. Dynamic Type을 기본적으로 지원

    이전 버전까지는 버튼의 인스펙터 창에서 Font, Text Color, Shadow Color를 지정했지만 새로운 버전부터는 Dynamic Type을 기본적으로 지원한다.

  4. Subtitle을 지원

  5. Activity Indicator를 지원

activity indicator의 경우 버튼의 configuration 속성 안에 있으므로 configuration.showsActivityIndicator = true 로 설정하면 된다.

(ConfigurationUpdateHandler 안에 있다면 업데이트 되고 있는 상태 변화를 사용자에게 알려줄 수 있어 좋을 것 같다.)

  1. Semaintic Styling

    semaintic styling을 사용하면 프로퍼티 변경 후 추가적인 작업 없이 오른쪽과 같은 상태를 갖을 수 있다.

  2. Pull Down / Pull Up Button
    pull down button은 이번에 추가 된 것은 아니고 14에 추가된 내용

    Pull Down과 Pull Up의 차이 ??
    Pull Down과 비슷하지만 메뉴 요소 중 하나만 선택 되도록

    self.button.showsMenuAsPrimaryAction = true
    self.button.changesSelectionAsPrimaryAction = true

    이렇게 두 줄만 추가하면 된다.
    (메뉴 요소 선택에 따라서 타이틀도 알아서 바뀐다.)

    메뉴 요소의 체크 표시
    기존의 메뉴 요소의 action에서 state를 on으로 하면 체크 표시가 여러개 나타날 수 있었다.
    그러나, iOS15부터 changesSelectionAsPrimaryAction를 true로 설정하면 먼저 추가한 것에만 체크 표시가 나타난다.

    self.button.changesSelectionAsPrimaryAction = true // iOS 15부터 사용 가능

    만약 저 코드가 없이 pull up butto을 구현하면 둘 다 state가 on인 상태가 되니 체크 표시가 두개가 나오고 버튼 타이틀이 변하지도 않는다.

  3. Inspector
    IB에서 변경 가능한 것

  • style 변경 가능
  • corner style 변경 가능 (fixed, dynamic, small, medium, large, capsule)

Configuration 적용


UIButton의 style이 다양해졌다.
위의 모습처럼 스토리보드에서 각 스타일의 컴포넌트를 사용할 수도 있고

let button = UIButton(type: .system) 
button.configuration = .filled() // ✅ 

위와 같이 코드로 설정할 수도 있다.

configuration을 사용하면,

var configuration = UIButton.Configuration.tinted() 
configuration.image = UIImage(systemName: "heart") 
configuration.imagePlacement = .trailing 
configuration.imagePadding = 30
configuration.subtitle = "대충 서브타이틀"
configuration.title = "대충 타이틀" 

let button = UIButton(configuration: configuration, primaryAction: nil)

원하는 UI로 버튼의 모습을 custom 할 수 있다.

✔️ 버튼이 눌렸을 때의 모습을 변화하고 싶다면?
=> ConfigurationUpdateHandler 를 통해 적용할 수 있다.

button.configurationUpdateHandler = { button in 
var config = button.configuration 
config?.image = button.isHighlighted ? UIImage(systemName: "heart.fill") : UIImage(systemName: "heart") 
button.configuration = config 
}

✔️ .isHighlighted 속성의 변화를 주고 싶다면?
만약 A라는 버튼을 눌러서 B의 버튼의 모습에 변화를 주고 싶다면?

간단하게 생각했을 때, 외부에 flag라는 변수를 두고

let secondButton = UIButton(configuration: secondConfig, primaryAction: UIAction(handler: { action in 
	self.flag.toggle() 
}))

이렇게 A버튼을 통해 flag의 상태를 바꿔주고

button.configurationUpdateHandler = { button in
            var config = button.configuration
            config?.subtitle = self.flag ? "You Clicked." : "Not Yet."
            config?.image = self.flag ? UIImage(systemName: "heart.fill") : UIImage(systemName: "heart")
            config?.imagePadding = 10
            config?.imagePlacement = .leading
            button.configuration = config
}

바뀌는 flag의 값에 따라서 B버튼의 모습을 다르게 해주면 될 것 같지만??
-> 결과는 바뀌지 않는다 !!!

이유는 >>
button의 state가 변경되지 않아서 configurationUpdateHandler가 호출되지 않은 것이다 !!

여기서 짚고 넘어가야 할 주의사항은

isHighlighted는 UIButton의 State이므로 해당 값이 변경될 때 ConfigurationUpdateHandler가 호출된다는 것

그러므로 만약 위와 같은 플로우로 configurationUpdateHandler를 호출하고 싶다면,

var flag = false { 
	didSet { 
    		self.button.setNeedsUpdateConfiguration() 
        } 
}

이렇게 flag의 변화로 setNeedsUpdateConfiguration를 호출하면 된다.

(📌 추가적으로 이유는 모르겠으나, 이런 식으로 상태 변화에 따라서 버튼의 configuration이 바뀌는 것은 스토리보드에서는 불가하고 코드 베이스로 구현했을 때만 가능한 것 같다.)

profile
Slowly But Surely

0개의 댓글