Skip to content

Commit f9f144a

Browse files
add alert buttons and a helper to calculate orientation for these buttons
1 parent 9715b1d commit f9f144a

File tree

4 files changed

+93
-27
lines changed

4 files changed

+93
-27
lines changed
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import UIKit
2+
3+
struct AlertButtonsOrientationCalculator {
4+
enum Orientation {
5+
case vertical
6+
case horizontal
7+
}
8+
9+
private static let primaryButton = UKButton()
10+
private static let secondaryButton = UKButton()
11+
12+
private init() {}
13+
14+
static func preferredOrientation(model: AlertVM) -> Orientation {
15+
guard let primaryButtonVM = model.primaryButtonVM,
16+
let secondaryButtonVM = model.secondaryButtonVM else {
17+
return .vertical
18+
}
19+
20+
self.primaryButton.model = primaryButtonVM.updating {
21+
$0.isFullWidth = false
22+
}
23+
self.secondaryButton.model = secondaryButtonVM.updating {
24+
$0.isFullWidth = false
25+
}
26+
27+
let primaryButtonWidth = self.primaryButton.intrinsicContentSize.width
28+
let secondaryButtonWidth = self.secondaryButton.intrinsicContentSize.width
29+
30+
// Since the `maxWidth` of the alert is always less than the width of the
31+
// screen, we can assume that the width of the container is equal to this
32+
// `maxWidth` value.
33+
let containerWidth = model.modalVM.size.maxWidth
34+
let availableButtonsWidth = containerWidth
35+
- AlertVM.buttonsSpacing
36+
- model.contentPaddings.leading
37+
- model.contentPaddings.trailing
38+
let availableButtonWidth = availableButtonsWidth / 2
39+
40+
if primaryButtonWidth <= availableButtonWidth,
41+
secondaryButtonWidth <= availableButtonWidth {
42+
return .horizontal
43+
} else {
44+
return .vertical
45+
}
46+
}
47+
}

Sources/ComponentsKit/Components/Alert/Models/AlertVM.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,5 +97,6 @@ extension AlertVM {
9797
$0.title = "OK"
9898
$0.color = .primary
9999
$0.style = .filled
100+
$0.isFullWidth = true
100101
}
101102
}

Sources/ComponentsKit/Components/Alert/SUAlert.swift

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -70,13 +70,34 @@ extension View {
7070
}
7171
},
7272
footer: {
73-
SUButton(
74-
model: AlertVM.defaultButtonVM,
75-
action: {
76-
primaryAction?()
77-
isPresented.wrappedValue = false
73+
switch AlertButtonsOrientationCalculator.preferredOrientation(model: model) {
74+
case .horizontal:
75+
HStack {
76+
AlertButton(
77+
isAlertPresented: isPresented,
78+
model: model.secondaryButtonVM,
79+
action: secondaryAction
80+
)
81+
AlertButton(
82+
isAlertPresented: isPresented,
83+
model: model.primaryButtonVM,
84+
action: primaryAction
85+
)
7886
}
79-
)
87+
case .vertical:
88+
VStack {
89+
AlertButton(
90+
isAlertPresented: isPresented,
91+
model: model.primaryButtonVM,
92+
action: primaryAction
93+
)
94+
AlertButton(
95+
isAlertPresented: isPresented,
96+
model: model.secondaryButtonVM,
97+
action: secondaryAction
98+
)
99+
}
100+
}
80101
}
81102
)
82103
}
@@ -109,3 +130,18 @@ private struct AlertMessage: View {
109130
.frame(maxWidth: .infinity)
110131
}
111132
}
133+
134+
private struct AlertButton: View {
135+
@Binding var isAlertPresented: Bool
136+
let model: ButtonVM?
137+
let action: (() -> Void)?
138+
139+
var body: some View {
140+
if let model {
141+
SUButton(model: model) {
142+
self.action?()
143+
self.isAlertPresented = false
144+
}
145+
}
146+
}
147+
}

Sources/ComponentsKit/Components/Alert/UKAlertController.swift

Lines changed: 3 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -138,30 +138,12 @@ public class UKAlertController: UKCenterModalController {
138138
super.updateViewConstraints()
139139

140140
if self.buttonsStackView.arrangedSubviews.count == 2 {
141-
self.buttonsStackView.axis = .vertical
142-
let primaryButtonWidth = self.primaryButton.intrinsicContentSize.width
143-
let secondaryButtonWidth = self.secondaryButton.intrinsicContentSize.width
144-
145-
// Since the `maxWidth` of the alert is always less than the width of the
146-
// screen, we can assume that the width of the container is equal to this
147-
// `maxWidth` value.
148-
let containerWidth = self.model.size.maxWidth
149-
let availableButtonsWidth = containerWidth
150-
- AlertVM.buttonsSpacing
151-
- self.model.contentPaddings.leading
152-
- self.model.contentPaddings.trailing
153-
let availableButtonWidth = availableButtonsWidth / 2
154-
155-
if primaryButtonWidth <= availableButtonWidth,
156-
secondaryButtonWidth <= availableButtonWidth {
141+
switch AlertButtonsOrientationCalculator.preferredOrientation(model: self.alertVM) {
142+
case .horizontal:
157143
self.buttonsStackView.removeArrangedSubview(self.secondaryButton)
158144
self.buttonsStackView.insertArrangedSubview(self.secondaryButton, at: 0)
159-
160145
self.buttonsStackView.axis = .horizontal
161-
} else {
162-
self.buttonsStackView.removeArrangedSubview(self.secondaryButton)
163-
self.buttonsStackView.insertArrangedSubview(self.secondaryButton, at: 1)
164-
146+
case .vertical:
165147
self.buttonsStackView.axis = .vertical
166148
}
167149
} else {

0 commit comments

Comments
 (0)