@@ -32,6 +32,15 @@ open class UKButton: UIView, UKComponent {
3232 /// A label that displays the title from the model.
3333 public var titleLabel = UILabel ( )
3434
35+ /// A loader view, created with the preferred loading VM from the model.
36+ public let loaderView : UKLoading
37+
38+ /// A stack view that arranges the loader and title label.
39+ private let stackView = UIStackView ( )
40+
41+ /// A image view for displaying the image from the model.
42+ public let imageView : UIImageView = UIImageView ( )
43+
3544 // MARK: UIView Properties
3645
3746 open override var intrinsicContentSize : CGSize {
@@ -50,6 +59,7 @@ open class UKButton: UIView, UKComponent {
5059 ) {
5160 self . model = model
5261 self . action = action
62+ self . loaderView = UKLoading ( model: model. preferredLoadingVM)
5363 super. init ( frame: . zero)
5464
5565 self . setup ( )
@@ -64,7 +74,7 @@ open class UKButton: UIView, UKComponent {
6474 // MARK: Setup
6575
6676 private func setup( ) {
67- self . addSubview ( self . titleLabel )
77+ self . addSubview ( self . stackView )
6878
6979 if #available( iOS 17 . 0 , * ) {
7080 self . registerForTraitChanges ( [ UITraitUserInterfaceStyle . self] ) { ( view: Self , _: UITraitCollection ) in
@@ -78,12 +88,23 @@ open class UKButton: UIView, UKComponent {
7888 private func style( ) {
7989 Self . Style. mainView ( self , model: self . model)
8090 Self . Style. titleLabel ( self . titleLabel, model: self . model)
91+ Self . Style. configureStackView (
92+ self . stackView,
93+ model: self . model,
94+ loaderView: self . loaderView,
95+ titleLabel: self . titleLabel,
96+ imageView: self . imageView
97+ )
98+
99+ self . loaderView. model = self . model. preferredLoadingVM
100+
101+ self . loaderView. isHidden = !self . model. isLoading
81102 }
82103
83104 // MARK: Layout
84105
85106 private func layout( ) {
86- self . titleLabel . center ( )
107+ self . stackView . center ( )
87108 }
88109
89110 open override func layoutSubviews( ) {
@@ -99,15 +120,21 @@ open class UKButton: UIView, UKComponent {
99120
100121 self . style ( )
101122
102- if self . model. shouldUpdateSize ( oldModel) {
123+ self . imageView. image = self . model. uiImage
124+ self . imageView. tintColor = self . model. foregroundColor. uiColor
125+
126+ if self . model. shouldUpdateSize ( oldModel)
127+ || self . model. isLoading != oldModel. isLoading
128+ || self . model. imageSrc != oldModel. imageSrc
129+ || self . model. imageLocation != oldModel. imageLocation {
103130 self . invalidateIntrinsicContentSize ( )
104131 }
105132 }
106133
107134 // MARK: UIView methods
108135
109136 open override func sizeThatFits( _ size: CGSize ) -> CGSize {
110- let contentSize = self . titleLabel . sizeThatFits ( size )
137+ let contentSize = self . stackView . systemLayoutSizeFitting ( UIView . layoutFittingCompressedSize )
111138 let preferredSize = self . model. preferredSize (
112139 for: contentSize,
113140 parentWidth: self . superview? . bounds. width
@@ -183,5 +210,40 @@ extension UKButton {
183210 label. font = model. preferredFont. uiFont
184211 label. textColor = model. foregroundColor. uiColor
185212 }
213+ static func configureStackView(
214+ _ stackView: UIStackView ,
215+ model: Model ,
216+ loaderView: UKLoading ,
217+ titleLabel: UILabel ,
218+ imageView: UIImageView
219+ ) {
220+ stackView. axis = . horizontal
221+ stackView. alignment = . center
222+ stackView. spacing = model. contentSpacing
223+
224+ for subview in stackView. arrangedSubviews {
225+ stackView. removeArrangedSubview ( subview)
226+ subview. removeFromSuperview ( )
227+ }
228+
229+ if model. isLoading {
230+ stackView. addArrangedSubview ( loaderView)
231+ stackView. addArrangedSubview ( titleLabel)
232+ return
233+ }
234+
235+ if let _ = model. imageSrc {
236+ switch model. imageLocation {
237+ case . leading:
238+ stackView. addArrangedSubview ( imageView)
239+ stackView. addArrangedSubview ( titleLabel)
240+ case . trailing:
241+ stackView. addArrangedSubview ( titleLabel)
242+ stackView. addArrangedSubview ( imageView)
243+ }
244+ } else {
245+ stackView. addArrangedSubview ( titleLabel)
246+ }
247+ }
186248 }
187249}
0 commit comments