Skip to content

Commit 6e9d4d3

Browse files
committed
Use constraints instead of frames for message animation
1 parent 1b4217c commit 6e9d4d3

File tree

4 files changed

+68
-31
lines changed

4 files changed

+68
-31
lines changed

Sources/Controllers/BarcodeScannerViewController.swift

Lines changed: 43 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,11 @@ open class BarcodeScannerViewController: UIViewController {
6565
/// Camera view with custom buttons.
6666
public private(set) lazy var cameraViewController: CameraViewController = .init()
6767

68+
// Constraints that are activated when the view is used as a footer.
69+
private lazy var collapsedConstraints: [NSLayoutConstraint] = self.makeCollapsedMessageConstraints()
70+
// Constraints that are activated when the view is used for loading animation and error messages.
71+
private lazy var expandedConstraints: [NSLayoutConstraint] = self.makeExpandedMessageConstraints()
72+
6873
private var messageView: UIView {
6974
return messageViewController.view
7075
}
@@ -76,38 +81,26 @@ open class BarcodeScannerViewController: UIViewController {
7681
}
7782
}
7883

79-
/// Calculated frame for the info view.
80-
private var messageViewFrame: CGRect {
81-
let height = status.state != .processing ? 75 : view.bounds.height
82-
return CGRect(
83-
x: 0, y: view.bounds.height - height,
84-
width: view.bounds.width, height: height
85-
)
86-
}
87-
8884
// MARK: - View lifecycle
8985

9086
open override func viewDidLoad() {
9187
super.viewDidLoad()
9288
view.backgroundColor = UIColor.black
89+
90+
add(childViewController: messageViewController)
91+
messageView.translatesAutoresizingMaskIntoConstraints = false
92+
collapsedConstraints.activate()
93+
9394
cameraViewController.metadata = metadata
9495
cameraViewController.delegate = self
95-
9696
add(childViewController: cameraViewController)
97-
add(childViewController: messageViewController)
97+
98+
view.bringSubview(toFront: messageView)
9899
}
99100

100101
open override func viewWillAppear(_ animated: Bool) {
101102
super.viewWillAppear(animated)
102-
setupConstraints()
103-
}
104-
105-
open override func viewWillTransition(to size: CGSize,
106-
with coordinator: UIViewControllerTransitionCoordinator) {
107-
super.viewWillTransition(to: size, with: coordinator)
108-
coordinator.animate(alongsideTransition: { (context) in
109-
self.messageView.frame = self.messageViewFrame
110-
})
103+
setupCameraConstraints()
111104
}
112105

113106
// MARK: - State handling
@@ -147,13 +140,20 @@ open class BarcodeScannerViewController: UIViewController {
147140
resetState()
148141
}
149142

143+
if newValue.state != .processing {
144+
expandedConstraints.deactivate()
145+
collapsedConstraints.activate()
146+
} else {
147+
collapsedConstraints.deactivate()
148+
expandedConstraints.activate()
149+
}
150+
150151
messageViewController.state = newValue.state
151152

152153
UIView.animate(
153154
withDuration: duration,
154155
animations: ({
155-
self.messageView.layoutIfNeeded()
156-
self.messageView.frame = self.messageViewFrame
156+
self.view.layoutIfNeeded()
157157
}),
158158
completion: ({ [weak self] _ in
159159
if delayReset {
@@ -209,11 +209,12 @@ open class BarcodeScannerViewController: UIViewController {
209209
// MARK: - Layout
210210

211211
private extension BarcodeScannerViewController {
212-
private func setupConstraints() {
213-
guard constraintsActivated else {
212+
private func setupCameraConstraints() {
213+
guard !constraintsActivated else {
214214
return
215215
}
216216

217+
constraintsActivated = true
217218
let cameraView = cameraViewController.view!
218219

219220
NSLayoutConstraint.activate(
@@ -239,6 +240,24 @@ private extension BarcodeScannerViewController {
239240
)
240241
}
241242
}
243+
244+
private func makeExpandedMessageConstraints() -> [NSLayoutConstraint] {
245+
return [
246+
messageView.topAnchor.constraint(equalTo: view.topAnchor),
247+
messageView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
248+
messageView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
249+
messageView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
250+
]
251+
}
252+
253+
private func makeCollapsedMessageConstraints() -> [NSLayoutConstraint] {
254+
return [
255+
messageView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
256+
messageView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
257+
messageView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
258+
messageView.heightAnchor.constraint(equalToConstant: 75)
259+
]
260+
}
242261
}
243262

244263
// MARK: - HeaderViewControllerDelegate

Sources/Controllers/CameraViewController.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -218,8 +218,8 @@ public final class CameraViewController: UIViewController {
218218
return
219219
}
220220

221-
regularFocusViewConstraints.forEach({ $0.isActive = false })
222-
animatedFocusViewConstraints.forEach({ $0.isActive = true })
221+
regularFocusViewConstraints.deactivate()
222+
animatedFocusViewConstraints.activate()
223223

224224
UIView.animate(
225225
withDuration: 1.0, delay:0,

Sources/Controllers/MessageViewController.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -142,11 +142,11 @@ public final class MessageViewController: UIViewController {
142142
}
143143

144144
if state == .scanning || state == .unauthorized {
145-
expandedConstraints.forEach({ $0.isActive = false })
146-
collapsedConstraints.forEach({ $0.isActive = true })
145+
expandedConstraints.deactivate()
146+
collapsedConstraints.activate()
147147
} else {
148-
collapsedConstraints.forEach({ $0.isActive = false })
149-
expandedConstraints.forEach({ $0.isActive = true })
148+
collapsedConstraints.deactivate()
149+
expandedConstraints.activate()
150150
}
151151
}
152152
}
@@ -164,7 +164,7 @@ extension MessageViewController {
164164
imageView.widthAnchor.constraint(equalToConstant: 30),
165165
imageView.heightAnchor.constraint(equalToConstant: 27),
166166

167-
textLabel.topAnchor.constraint(equalTo: imageView.bottomAnchor, constant: 14),
167+
textLabel.topAnchor.constraint(equalTo: imageView.bottomAnchor, constant: 18),
168168
textLabel.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: padding),
169169
textLabel.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -padding),
170170

Sources/Extensions/NSLayoutConstraint+Extensions.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,21 @@ extension NSLayoutConstraint {
1313
}
1414
}
1515
}
16+
17+
extension Array where Element: NSLayoutConstraint {
18+
func activate() {
19+
forEach {
20+
if !$0.isActive {
21+
$0.isActive = true
22+
}
23+
}
24+
}
25+
26+
func deactivate() {
27+
forEach {
28+
if $0.isActive {
29+
$0.isActive = false
30+
}
31+
}
32+
}
33+
}

0 commit comments

Comments
 (0)