Skip to content

Instantly share code, notes, and snippets.

@pcperini
Last active August 16, 2016 08:19
Show Gist options
  • Save pcperini/e749a510d90a83b4e82f to your computer and use it in GitHub Desktop.
Save pcperini/e749a510d90a83b4e82f to your computer and use it in GitHub Desktop.
import UIKit
public protocol ConstraintStateMachineType: class {
// MARK: Types
typealias State: RawRepresentable
// MARK: Properties
var state: State? { get set }
var allConstraints: [NSLayoutConstraint] { get }
// MARK: Mutators
func setNeedsUpdateConstraints()
}
public extension ConstraintStateMachineType where State.RawValue == String {
// MARK: Properties
var state: State? {
get {
let constraints = self.allConstraints.flatMap { $0 as? StatefulConstraint }
let rawValue = constraints.filter { $0.priority == UILayoutPriorityDefaultHigh }
.first?.state ?? ""
return State(rawValue: rawValue)
}
set {
guard let state = newValue else { return }
let constraints = self.allConstraints.flatMap { $0 as? StatefulConstraint }
constraints.filter { $0.state != state.rawValue }
.forEach { $0.priority = UILayoutPriorityDefaultLow }
constraints.filter { $0.state == state.rawValue }
.forEach { $0.priority = UILayoutPriorityDefaultHigh }
self.setNeedsUpdateConstraints()
}
}
}
public extension ConstraintStateMachineType where Self: UIViewController {
// MARK: Properties
var allConstraints: [NSLayoutConstraint] {
return self.view.flatConstraints // helper function, recursively collects constraints
// https://gist.github.com/pcperini/5a8ea37e8cbbe904a031
}
// MARK: Mutators
func setNeedsUpdateConstraints() {
self.view.setNeedsUpdateConstraints()
}
}
@IBDesignable
public class StatefulConstraint: NSLayoutConstraint {
// MARK: Properties
@IBInspectable var state: String = ""
}
public extension CollectionType {
// MARK: Flatteners
public func flatten(path: (Self.Generator.Element) -> [Self.Generator.Element]) -> [Self.Generator.Element] {
guard !self.isEmpty else { return [] }
return self + self.flatMap { path($0).flatten(path) }
}
}
public extension UIView {
// MARK: Properties
public var flatSubviews: [UIView] {
return self.subviews.flatten { $0.subviews }
}
public var flatConstraints: [NSLayoutConstraint] {
return (self.flatSubviews + [self]).flatMap { $0.constraints }
}
}
class ViewController: UIViewController, ConstraintStateMachineType {
typealias State = Alignment
enum Alignment: String {
case Left = "Left"
case Right = "Right"
}
override func viewDidLoad() {
super.viewDidLoad()
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(UInt64(2) * NSEC_PER_SEC)), dispatch_get_main_queue()) { () -> Void in
self.state = .Right
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment