Skip to content

Latest commit

ย 

History

History
153 lines (107 loc) ยท 5.39 KB

TIL_2022:10:16_button_configuration_more.md

File metadata and controls

153 lines (107 loc) ยท 5.39 KB

Today I Learned


2022.10.16 (์ผ)

UIButton.Configuration์„ ์กฐ๊ธˆ ๋” ๊นŠ๊ฒŒ ํŒŒ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

๊ธฐ๋ณธ์ ์ธ ์š”์†Œ

// ์„ ์–ธ
var configuration = UIButton.Configuration.filled() 

// ํ‘œ์‹œ๋˜๋Š” UI 
configuration.title = "๋ฒ„ํŠผ์ž…๋‹ˆ๋‹ค"
configuration.subtitle = "์„œ๋ธŒ ํƒ€์ดํ‹€์ž…๋‹ˆ๋‹ค"
configuration.image = .init(systemName: "xmark")

// UI์˜ ๊ฐ„๊ฒฉ ๋ฐ ์œ„์น˜, ์‚ฌ์ด์ฆˆ ์กฐ์ ˆ
configuration.titleAlignment = .center
configuration.titlePadding = 10
configuration.imagePlacement = .trailing
configuration.imagePadding = 10
configuration.preferredSymbolConfigurationForImage = UIImage.SymbolConfiguration(scale: .medium)

// ์‚ฌ์ด์ฆˆ 
configuration.buttonSize = .mini 
configuration.buttonSize = .small
configuration.buttonSize = .medium  
configuration.buttonSize = .large 

์‚ฌ์ด์ฆˆ๊ฐ€ ์žˆ์ง€๋งŒ Constriaint๋ฅผ ์ง€์ •ํ•˜๋ฉด ์ด ๊ฐ’์€ ๋ฌด์‹œ๋ฉ๋‹ˆ๋‹ค. ์™œ ์žˆ๋Š” ์ง€ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค. ๋‹จ์ง€ ๊ฐœ๋ฐœ์ž๊ฐ€ ""์ด ๋ฒ„ํŠผ์˜ ์‚ฌ์ด์ฆˆ๋Š” ์ด์ •๋„์ด๋‹ค."๋ผ๊ณ  ๋ช…์„ธํ•˜๋Š” ์šฉ๋„๋กœ๋งŒ ์‚ฌ์šฉ๋˜๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์•„๋ž˜ ์˜์–ด๋Š” ๋ฌธ์„œ์— ์ž‘์„ฑ๋œ buttonSize์˜ Discussion: The size indicates a system-defined size you prefer for this button. The exact size of the button may change regardless of this value.

configuration.cornerStyle = .small
configuration.cornerStyle = .medium
configuration.cornerStyle = .large
configuration.cornerStyle = .capsule
configuration.cornerStyle = .dynamic

cornerStyle์€ background corner radius๋ฅผ ๋ฌด์‹œํ•˜๊ณ  ๋ฒ„ํŠผ corner radius๋ฅผ ์„ค์ •ํ•˜๋Š” ํ”„๋กœํผํ‹ฐ์ž…๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ fixed ์ผ€์ด์Šค๋งŒ ํ˜ผ์ž๋งŒ background corner radius๋ฅผ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค.

๊ทธ๋Ÿฐ๋ฐ, dynamic๊ณผ fixed์˜ ์ฐจ์ด๊ฐ€ ๋ญ˜๊นŒ? ์ด๊ฑด ์ซŒ ๋‚˜์ค‘์— ์ฐพ์•„๋ด…์‹œ๋‹ค.

configuration.cornerStyle = .fixed
configuration.background.cornerRadius = 14

์กฐ๊ธˆ ๊นŠ๊ฒŒ - ๋ฒ„ํŠผ ์ œ๋ชฉ ํ”„๋กœํผํ‹ฐ ์ˆ˜์ •ํ•˜๊ธฐ

configuration.titleTextAttributesTransformer = UIConfigurationTextAttributesTransformer { incoming in
		var outgoing = incoming
		outgoing.font = UIFont.preferredFont(forTextStyle: .headline)
		return outgoing
}

incoming๊ณผ outgoing์€ AttributeContainer ํƒ€์ž…์ž…๋‹ˆ๋‹ค. title๊ณผ ๊ด€๋ จ๋œ attribute๋ฅผ ์ˆ˜์ •ํ•˜๊ณ  ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

AttributeContainer๋„ ๋‚˜์ค‘์— ๊ณต๋ถ€ํ•ฉ์‹œ๋‹ค. ์ผ๋‹จ์€ UILabel์˜ ์—ฌ๋Ÿฌ ํ”„๋กœํผํ‹ฐ๋“ค์„ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ํƒ€์ž…์ด๋ผ๊ณ ๋งŒ ์•Œ์•„๋‘ก์‹œ๋‹ค.


๋”์šฑ ๊นŠ๊ฒŒ - ๋กœ๋”ฉ ๋ฒ„ํŠผ

button.configurationUpdateHandler = { [unowned self] button in
  var config = button.configuration
  config?.showsActivityIndicator = self.signingIn
  config?.imagePlacement = self.signingIn ? .leading : .trailing
  config?.title = self.signingIn ? "Signing In..." : "Sign In"
  button.isEnabled = !self.signingIn
  button.configuration = config
}

// Configuration ์—…๋ฐ์ดํŠธ
button.setNeedsUpdateConfiguration()

๋ฒ„ํŠผ์—์„œ showsActivityIndicatorํ”„๋กœํผํ‹ฐ๋ฅผ ํ†ตํ•ด Indicator๋ฅผ ๋ณด์—ฌ์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•ด๋‹น ํ”„๋กœํผํ‹ฐ๋Š” Configuration์— ์†ํ•ด์žˆ๊ณ  ๋ณด์—ฌ์ฃผ๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋ฒ„ํŠผ์˜ Configuration์„ ์—…๋ฐ์ดํŠธํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค. ์ด ๋•Œ configurationUpdateHandlerํ”„๋กœํผํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. Configuration ์—…๋ฐ์ดํŠธ ํด๋กœ์ €๋ฅผ ์ž‘์„ฑํ•œ ํ›„ ์ง์ ‘ ์—…๋ฐ์ดํŠธ๋ฅผ ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” setNeedsUpdateConfiguration()๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.

[unowned self]๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ด์œ ์— ๋Œ€ํ•ด์„œ ํ•œ๋ฒˆ ์ƒ๊ฐํ•ด๋ด…์‹œ๋‹ค.


๋”์šฑ ๊นŠ๊ฒŒ - ํ† ๊ธ€ ๋ฒ„ํŠผ

button.configurationUpdateHandler = { [unowned self] button in
  var config = button.configuration
  let symbolName = self.isBookInCart ? "cart.badge.minus" : "cart.badge.plus"
  config?.image = UIImage(systemName: symbolName)
  button.configuration = config
}

// Configuration ์—…๋ฐ์ดํŠธ
button.setNeedsUpdateConfiguration()

ํ† ๊ธ€ ๋ฒ„ํŠผ์€ ๋กœ๋”ฉ ๋ฒ„ํŠผ์—์„œ ์ด์šฉํ–ˆ๋˜ configurationUpdateHandlerํ”„๋กœํผํ‹ฐ๋ฅผ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.


๋”์šฑ ๊นŠ๊ฒŒ - ํŒ์—… ๋ฒ„ํŠผ

button.showsMenuAsPrimaryAction = true
button.menu = UIMenu(children: [
    UIAction(title: "Action 1", image: UIImage(systemName: "hare.fill")) { _ in
      print("Action 1")
    },
    UIAction(title: "Action 2", image: UIImage(systemName: "tortoise.fill")) { _ in
      print("Action 2")
    }
])

button.changesSelectionAsPrimaryAction = true

ํŒ์—…๋ฒ„ํŠผ์€ showsMenuAsPrimaryActionํ”„๋กœํผํ‹ฐ๋ฅผ true๋กœ ์„ค์ •ํ•˜๊ณ  menu์— UIAction์„ ๋‹ด์•„์ค˜์•ผํ•ฉ๋‹ˆ๋‹ค. changesSelectionAsPrimaryAction์„ true๋กœ ์„ค์ •ํ•œ๋‹ค๋ฉด ํŒ์—…์ด ๋‚˜์˜ฌ ๋•Œ ๋งˆ์ง€๋ง‰์— ์„ ํƒํ•œ Action์ด ์„ ํƒ์ด ๋œ ์ƒํƒœ๋กœ ๋‚˜์˜ต๋‹ˆ๋‹ค. (๋งŒ์ผ ์ฒ˜์Œ์ด๋ผ๋ฉด ์ฒซ๋ฒˆ์งธ Action์ด ์„ ํƒ๋˜์–ด์ ธ์žˆ์Šต๋‹ˆ๋‹ค.)


๋”์šฑ ๊นŠ๊ฒŒ - UIAction

let button = UIButton(configuration: .filled(), primaryAction: UIAction(handler: { action in
    print("์•ˆ๋…•")
}))

UIAction์€ ๋ฉ”๋‰ด์˜ ํ•˜๋‚˜์˜ ๊ธฐ๋Šฅ์œผ๋กœ, ํด๋กœ์ €๋ฅผ ํ†ตํ•ด ์•ก์…˜์„ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. ๋ฉ”๋‰ด์˜ ์ผ์ข…์ด์ง€๋งŒ ๋ฒ„ํŠผ์˜ initiailzer์—๋„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์–ด์„œ addTarget๋Œ€์‹  ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๋ฒ„ํŠผ์˜ ์ดˆ๊ธฐํ™”์ดํ›„์—๋Š” ๋ฒ„ํŠผ์— ๋”ฐ๋กœ ์„ค์ •ํ•  ์ˆ˜ ๋Š” ์—†์Šต๋‹ˆ๋‹ค.

UIButton Configuration Ref