Skip to content

Commit

Permalink
Merge pull request #90 from hyperoslo/fix/message-animation
Browse files Browse the repository at this point in the history
Refactoring: fix message animation
  • Loading branch information
vadymmarkov authored Jan 26, 2018
2 parents 752dbe6 + 3aafc30 commit 515d0cd
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 40 deletions.
18 changes: 18 additions & 0 deletions BarcodeScanner.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@
D5B2E89B1C3A780C00C0327D /* Frameworks */,
D5B2E89C1C3A780C00C0327D /* Headers */,
D5B2E89D1C3A780C00C0327D /* Resources */,
D5C113C9201A981500D46C9C /* SwiftLint */,
);
buildRules = (
);
Expand Down Expand Up @@ -221,6 +222,23 @@
};
/* End PBXResourcesBuildPhase section */

/* Begin PBXShellScriptBuildPhase section */
D5C113C9201A981500D46C9C /* SwiftLint */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = SwiftLint;
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "if which swiftlint >/dev/null; then\nswiftlint\nelse\necho \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi";
};
/* End PBXShellScriptBuildPhase section */

/* Begin PBXSourcesBuildPhase section */
D5B2E89A1C3A780C00C0327D /* Sources */ = {
isa = PBXSourcesBuildPhase;
Expand Down
67 changes: 43 additions & 24 deletions Sources/Controllers/BarcodeScannerViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,11 @@ open class BarcodeScannerViewController: UIViewController {
/// Camera view with custom buttons.
public private(set) lazy var cameraViewController: CameraViewController = .init()

// Constraints that are activated when the view is used as a footer.
private lazy var collapsedConstraints: [NSLayoutConstraint] = self.makeCollapsedMessageConstraints()
// Constraints that are activated when the view is used for loading animation and error messages.
private lazy var expandedConstraints: [NSLayoutConstraint] = self.makeExpandedMessageConstraints()

private var messageView: UIView {
return messageViewController.view
}
Expand All @@ -76,38 +81,26 @@ open class BarcodeScannerViewController: UIViewController {
}
}

/// Calculated frame for the info view.
private var messageViewFrame: CGRect {
let height = status.state != .processing ? 75 : view.bounds.height
return CGRect(
x: 0, y: view.bounds.height - height,
width: view.bounds.width, height: height
)
}

// MARK: - View lifecycle

open override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor.black

add(childViewController: messageViewController)
messageView.translatesAutoresizingMaskIntoConstraints = false
collapsedConstraints.activate()

cameraViewController.metadata = metadata
cameraViewController.delegate = self

add(childViewController: cameraViewController)
add(childViewController: messageViewController)

view.bringSubview(toFront: messageView)
}

open override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
setupConstraints()
}

open override func viewWillTransition(to size: CGSize,
with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
coordinator.animate(alongsideTransition: { (context) in
self.messageView.frame = self.messageViewFrame
})
setupCameraConstraints()
}

// MARK: - State handling
Expand Down Expand Up @@ -147,13 +140,20 @@ open class BarcodeScannerViewController: UIViewController {
resetState()
}

if newValue.state != .processing {
expandedConstraints.deactivate()
collapsedConstraints.activate()
} else {
collapsedConstraints.deactivate()
expandedConstraints.activate()
}

messageViewController.state = newValue.state

UIView.animate(
withDuration: duration,
animations: ({
self.messageView.layoutIfNeeded()
self.messageView.frame = self.messageViewFrame
self.view.layoutIfNeeded()
}),
completion: ({ [weak self] _ in
if delayReset {
Expand Down Expand Up @@ -209,11 +209,12 @@ open class BarcodeScannerViewController: UIViewController {
// MARK: - Layout

private extension BarcodeScannerViewController {
private func setupConstraints() {
guard constraintsActivated else {
private func setupCameraConstraints() {
guard !constraintsActivated else {
return
}

constraintsActivated = true
let cameraView = cameraViewController.view!

NSLayoutConstraint.activate(
Expand All @@ -239,6 +240,24 @@ private extension BarcodeScannerViewController {
)
}
}

private func makeExpandedMessageConstraints() -> [NSLayoutConstraint] {
return [
messageView.topAnchor.constraint(equalTo: view.topAnchor),
messageView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
messageView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
messageView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
]
}

private func makeCollapsedMessageConstraints() -> [NSLayoutConstraint] {
return [
messageView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
messageView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
messageView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
messageView.heightAnchor.constraint(equalToConstant: 75)
]
}
}

// MARK: - HeaderViewControllerDelegate
Expand Down
25 changes: 14 additions & 11 deletions Sources/Controllers/CameraViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -114,11 +114,13 @@ public final class CameraViewController: UIViewController {
public override func viewWillTransition(to size: CGSize,
with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
coordinator.animate(alongsideTransition: { [weak self] _ in
self?.setupVideoPreviewLayerOrientation()
}) { [weak self] _ in
self?.animateFocusView()
}
coordinator.animate(
alongsideTransition: { [weak self] _ in
self?.setupVideoPreviewLayerOrientation()
},
completion: ({ [weak self] _ in
self?.animateFocusView()
}))
}

// MARK: - Video capturing
Expand Down Expand Up @@ -218,11 +220,12 @@ public final class CameraViewController: UIViewController {
return
}

regularFocusViewConstraints.forEach({ $0.isActive = false })
animatedFocusViewConstraints.forEach({ $0.isActive = true })
regularFocusViewConstraints.deactivate()
animatedFocusViewConstraints.activate()

UIView.animate(
withDuration: 1.0, delay:0,
withDuration: 1.0,
delay: 0,
options: [.repeat, .autoreverse, .beginFromCurrentState],
animations: ({ [weak self] in
self?.view.layoutIfNeeded()
Expand Down Expand Up @@ -300,7 +303,7 @@ private extension CameraViewController {
videoPreviewLayer.frame = view.layer.bounds

if let connection = videoPreviewLayer.connection, connection.isVideoOrientationSupported {
switch (UIApplication.shared.statusBarOrientation) {
switch UIApplication.shared.statusBarOrientation {
case .portrait:
connection.videoOrientation = .portrait
case .landscapeRight:
Expand Down Expand Up @@ -336,7 +339,7 @@ private extension CameraViewController {
let button = UIButton(type: .system)
let title = NSAttributedString(
string: localizedString("BUTTON_SETTINGS"),
attributes: [.font: UIFont.boldSystemFont(ofSize: 17), .foregroundColor : UIColor.white]
attributes: [.font: UIFont.boldSystemFont(ofSize: 17), .foregroundColor: UIColor.white]
)
button.setAttributedTitle(title, for: UIControlState())
button.sizeToFit()
Expand Down
10 changes: 5 additions & 5 deletions Sources/Controllers/MessageViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -142,11 +142,11 @@ public final class MessageViewController: UIViewController {
}

if state == .scanning || state == .unauthorized {
expandedConstraints.forEach({ $0.isActive = false })
collapsedConstraints.forEach({ $0.isActive = true })
expandedConstraints.deactivate()
collapsedConstraints.activate()
} else {
collapsedConstraints.forEach({ $0.isActive = false })
expandedConstraints.forEach({ $0.isActive = true })
collapsedConstraints.deactivate()
expandedConstraints.activate()
}
}
}
Expand All @@ -164,7 +164,7 @@ extension MessageViewController {
imageView.widthAnchor.constraint(equalToConstant: 30),
imageView.heightAnchor.constraint(equalToConstant: 27),

textLabel.topAnchor.constraint(equalTo: imageView.bottomAnchor, constant: 14),
textLabel.topAnchor.constraint(equalTo: imageView.bottomAnchor, constant: 18),
textLabel.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: padding),
textLabel.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -padding),

Expand Down
18 changes: 18 additions & 0 deletions Sources/Extensions/NSLayoutConstraint+Extensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,21 @@ extension NSLayoutConstraint {
}
}
}

extension Array where Element: NSLayoutConstraint {
func activate() {
forEach {
if !$0.isActive {
$0.isActive = true
}
}
}

func deactivate() {
forEach {
if $0.isActive {
$0.isActive = false
}
}
}
}

0 comments on commit 515d0cd

Please sign in to comment.