Commit 51a7d750 by Daniel Dahan

development: updated ControlView and NavigationBar grid layouts

parent 9efac5ec
...@@ -48,7 +48,7 @@ open class ControlView: View { ...@@ -48,7 +48,7 @@ open class ControlView: View {
/// A wrapper around grid.contentInset. /// A wrapper around grid.contentInset.
@IBInspectable @IBInspectable
open var contentInset: EdgeInsets { open var contentEdgeInsets: EdgeInsets {
get { get {
return grid.contentEdgeInsets return grid.contentEdgeInsets
} }
...@@ -151,49 +151,48 @@ open class ControlView: View { ...@@ -151,49 +151,48 @@ open class ControlView: View {
if willRenderView { if willRenderView {
layoutIfNeeded() layoutIfNeeded()
let g = Int(width / gridFactor) let l = (CGFloat(leftControls.count) * interimSpace)
let columns = g + 1 let r = (CGFloat(rightControls.count) * interimSpace)
let p = width - l - r - contentEdgeInsets.left - contentEdgeInsets.right
let columns = Int(p / gridFactor)
grid.views = [] grid.views.removeAll()
grid.axis.columns = columns grid.axis.columns = columns
contentView.grid.columns = columns contentView.grid.columns = columns
// leftControls for v in leftControls {
for c in leftControls { var w: CGFloat = 0
let w: CGFloat = c.intrinsicContentSize.width if let b = v as? UIButton {
(c as? UIButton)?.contentEdgeInsets = .zero b.contentEdgeInsets = .zero
c.height = frame.size.height - contentInset.top - contentInset.bottom b.sizeToFit()
w = b.width
let q: Int = Int(w / gridFactor) }
c.grid.columns = q + 1 v.height = frame.size.height - contentEdgeInsets.top - contentEdgeInsets.bottom
v.grid.columns = Int(ceil(w / gridFactor)) + 1
contentView.grid.columns -= c.grid.columns contentView.grid.columns -= v.grid.columns
addSubview(c) grid.views.append(v)
grid.views.append(c)
} }
addSubview(contentView)
grid.views.append(contentView) grid.views.append(contentView)
// rightControls for v in rightControls {
for c in rightControls { var w: CGFloat = 0
let w = c.intrinsicContentSize.width if let b = v as? UIButton {
(c as? UIButton)?.contentEdgeInsets = .zero b.contentEdgeInsets = .zero
c.height = frame.size.height - contentInset.top - contentInset.bottom b.sizeToFit()
w = b.width
let q: Int = Int(w / gridFactor) }
c.grid.columns = q + 1 v.height = frame.size.height - contentEdgeInsets.top - contentEdgeInsets.bottom
v.grid.columns = Int(ceil(w / gridFactor)) + 1
contentView.grid.columns -= c.grid.columns contentView.grid.columns -= v.grid.columns
addSubview(c) grid.views.append(v)
grid.views.append(c)
} }
grid.contentEdgeInsets = contentInset
grid.interimSpace = interimSpace
contentView.grid.reload() contentView.grid.reload()
} }
} }
......
...@@ -61,19 +61,19 @@ open class NavigationBar: UINavigationBar { ...@@ -61,19 +61,19 @@ open class NavigationBar: UINavigationBar {
/// Will render the view. /// Will render the view.
open var willRenderView: Bool { open var willRenderView: Bool {
return 0 < width && 0 < height && nil != superview return 0 < width && 0 < height
} }
/// A preset wrapper around contentInset. /// A preset wrapper around contentInset.
open var contentEdgeInsetsPreset = EdgeInsetsPreset.none { open var contentEdgeInsetsPreset = EdgeInsetsPreset.none {
didSet { didSet {
contentInset = EdgeInsetsPresetToValue(preset: contentEdgeInsetsPreset) contentEdgeInsets = EdgeInsetsPresetToValue(preset: contentEdgeInsetsPreset)
} }
} }
/// A wrapper around grid.contentInset. /// A wrapper around grid.contentInset.
@IBInspectable @IBInspectable
open var contentInset = EdgeInsets.zero { open var contentEdgeInsets = EdgeInsets.zero {
didSet { didSet {
layoutSubviews() layoutSubviews()
} }
...@@ -175,7 +175,9 @@ open class NavigationBar: UINavigationBar { ...@@ -175,7 +175,9 @@ open class NavigationBar: UINavigationBar {
layoutNavigationItem(item: v) layoutNavigationItem(item: v)
} }
divider?.reload() if let v = divider {
v.reload()
}
} }
open override func pushItem(_ item: UINavigationItem, animated: Bool) { open override func pushItem(_ item: UINavigationItem, animated: Bool) {
...@@ -194,52 +196,51 @@ open class NavigationBar: UINavigationBar { ...@@ -194,52 +196,51 @@ open class NavigationBar: UINavigationBar {
let titleView = prepareTitleView(item: item) let titleView = prepareTitleView(item: item)
let contentView = prepareContentView(item: item) let contentView = prepareContentView(item: item)
let g = Int(width / gridFactor) let l = (CGFloat(item.leftControls.count) * interimSpace)
let columns = g + 1 let r = (CGFloat(item.rightControls.count) * interimSpace)
let p = width - l - r - contentEdgeInsets.left - contentEdgeInsets.right
let columns = Int(p / gridFactor)
titleView.frame.origin = .zero titleView.frame.origin = .zero
titleView.frame.size = intrinsicContentSize titleView.frame.size = intrinsicContentSize
titleView.grid.views = [] titleView.grid.views.removeAll()
titleView.grid.axis.columns = columns titleView.grid.axis.columns = columns
contentView.grid.columns = columns contentView.grid.columns = columns
// leftControls for v in item.leftControls {
if let v = item.leftControls { var w: CGFloat = 0
for c in v { if let b = v as? UIButton {
let w = c.intrinsicContentSize.width b.contentEdgeInsets = .zero
(c as? UIButton)?.contentEdgeInsets = .zero b.sizeToFit()
c.height = titleView.height - contentInset.top - contentInset.bottom w = b.width
}
c.grid.columns = Int(w / gridFactor) + 1 v.height = frame.size.height - contentEdgeInsets.top - contentEdgeInsets.bottom
v.grid.columns = Int(ceil(w / gridFactor)) + 1
contentView.grid.columns -= c.grid.columns contentView.grid.columns -= v.grid.columns
titleView.addSubview(c) titleView.grid.views.append(v)
titleView.grid.views.append(c)
}
} }
titleView.addSubview(contentView)
titleView.grid.views.append(contentView) titleView.grid.views.append(contentView)
// rightControls for v in item.rightControls {
if let v = item.rightControls { var w: CGFloat = 0
for c in v { if let b = v as? UIButton {
let w = c.intrinsicContentSize.width b.contentEdgeInsets = .zero
(c as? UIButton)?.contentEdgeInsets = .zero b.sizeToFit()
c.height = titleView.height - contentInset.top - contentInset.bottom w = b.width
}
c.grid.columns = Int(w / gridFactor) + 1 v.height = frame.size.height - contentEdgeInsets.top - contentEdgeInsets.bottom
v.grid.columns = Int(ceil(w / gridFactor)) + 1
contentView.grid.columns -= c.grid.columns contentView.grid.columns -= v.grid.columns
titleView.addSubview(c) titleView.grid.views.append(v)
titleView.grid.views.append(c)
}
} }
titleView.grid.contentEdgeInsets = contentInset titleView.grid.contentEdgeInsets = contentEdgeInsets
titleView.grid.interimSpace = interimSpace titleView.grid.interimSpace = interimSpace
titleView.grid.reload() titleView.grid.reload()
......
...@@ -43,7 +43,7 @@ extension UINavigationController { ...@@ -43,7 +43,7 @@ extension UINavigationController {
} }
@IBDesignable @IBDesignable
open class NavigationController: UINavigationController, UIGestureRecognizerDelegate { open class NavigationController: UINavigationController {
/** /**
An initializer that initializes the object with a NSCoder object. An initializer that initializes the object with a NSCoder object.
- Parameter aDecoder: A NSCoder instance. - Parameter aDecoder: A NSCoder instance.
...@@ -72,17 +72,22 @@ open class NavigationController: UINavigationController, UIGestureRecognizerDele ...@@ -72,17 +72,22 @@ open class NavigationController: UINavigationController, UIGestureRecognizerDele
open override func viewWillAppear(_ animated: Bool) { open override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated) super.viewWillAppear(animated)
if let v = interactivePopGestureRecognizer { guard let v = interactivePopGestureRecognizer else {
if let x = navigationDrawerController { return
}
guard let x = navigationDrawerController else {
return
}
if let l = x.leftPanGesture { if let l = x.leftPanGesture {
l.require(toFail: v) l.require(toFail: v)
} }
if let r = x.rightPanGesture { if let r = x.rightPanGesture {
r.require(toFail: v) r.require(toFail: v)
} }
} }
}
}
open override func viewDidLoad() { open override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
...@@ -100,16 +105,25 @@ open class NavigationController: UINavigationController, UIGestureRecognizerDele ...@@ -100,16 +105,25 @@ open class NavigationController: UINavigationController, UIGestureRecognizerDele
} }
/** /**
Detects the gesture recognizer being used. This is necessary when using Prepares the view instance when intialized. When subclassing,
NavigationDrawerController. It eliminates the conflict in panning. it is recommended to override the prepareView method
- Parameter gestureRecognizer: A UIGestureRecognizer to detect. to initialize property values and other setup operations.
- Parameter touch: The UITouch event. The super.prepareView method should always be called immediately
- Returns: A Boolean of whether to continue the gesture or not, true yes, false no. when subclassing.
*/ */
open func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool { open func prepareView() {
return interactivePopGestureRecognizer == gestureRecognizer && nil != navigationBar.backItem view.clipsToBounds = true
view.contentScaleFactor = Device.scale
// This ensures the panning gesture is available when going back between views.
if let v = interactivePopGestureRecognizer {
v.isEnabled = true
v.delegate = self
}
} }
}
extension NavigationController: UINavigationBarDelegate {
/** /**
Delegation method that is called when a new UINavigationItem is about to be pushed. Delegation method that is called when a new UINavigationItem is about to be pushed.
This is used to prepare the transitions between UIViewControllers on the stack. This is used to prepare the transitions between UIViewControllers on the stack.
...@@ -118,19 +132,13 @@ open class NavigationController: UINavigationController, UIGestureRecognizerDele ...@@ -118,19 +132,13 @@ open class NavigationController: UINavigationController, UIGestureRecognizerDele
- Returns: A Boolean value that indicates whether to push the item on to the stack or not. - Returns: A Boolean value that indicates whether to push the item on to the stack or not.
True is yes, false is no. True is yes, false is no.
*/ */
open func navigationBar(navigationBar: UINavigationBar, shouldPushItem item: UINavigationItem) -> Bool { public func navigationBar(_ navigationBar: UINavigationBar, shouldPush item: UINavigationItem) -> Bool {
if let v = navigationBar as? NavigationBar { if let v = navigationBar as? NavigationBar {
let backButton = IconButton(image: v.backButtonImage) let backButton = IconButton(image: v.backButtonImage, tintColor: Color.blue.base)
backButton.pulseColor = Color.white backButton.pulseColor = Color.white
backButton.addTarget(self, action: #selector(handleBackButton), for: .touchUpInside) backButton.addTarget(self, action: #selector(handleBackButton), for: .touchUpInside)
if var c = item.leftControls { item.leftControls.append(backButton)
c.append(backButton)
item.leftControls = c
} else {
item.leftControls = [backButton]
}
item.backButton = backButton item.backButton = backButton
v.layoutNavigationItem(item: item) v.layoutNavigationItem(item: item)
} }
...@@ -141,22 +149,17 @@ open class NavigationController: UINavigationController, UIGestureRecognizerDele ...@@ -141,22 +149,17 @@ open class NavigationController: UINavigationController, UIGestureRecognizerDele
internal func handleBackButton() { internal func handleBackButton() {
popViewController(animated: true) popViewController(animated: true)
} }
}
extension NavigationController: UIGestureRecognizerDelegate {
/** /**
Prepares the view instance when intialized. When subclassing, Detects the gesture recognizer being used. This is necessary when using
it is recommended to override the prepareView method NavigationDrawerController. It eliminates the conflict in panning.
to initialize property values and other setup operations. - Parameter gestureRecognizer: A UIGestureRecognizer to detect.
The super.prepareView method should always be called immediately - Parameter touch: The UITouch event.
when subclassing. - Returns: A Boolean of whether to continue the gesture or not, true yes, false no.
*/ */
open func prepareView() { public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
view.clipsToBounds = true return interactivePopGestureRecognizer == gestureRecognizer && nil != navigationBar.backItem
view.contentScaleFactor = Device.scale
// This ensures the panning gesture is available when going back between views.
if let v = interactivePopGestureRecognizer {
v.isEnabled = true
v.delegate = self
}
} }
} }
...@@ -53,10 +53,10 @@ public class NavigationItem { ...@@ -53,10 +53,10 @@ public class NavigationItem {
public private(set) var detailLabel: UILabel! public private(set) var detailLabel: UILabel!
/// Left controls. /// Left controls.
public var leftControls: [UIView]? public var leftControls = [UIView]()
/// Right controls. /// Right controls.
public var rightControls: [UIView]? public var rightControls = [UIView]()
/// Initializer. /// Initializer.
public init() { public init() {
...@@ -153,7 +153,7 @@ extension UINavigationItem { ...@@ -153,7 +153,7 @@ extension UINavigationItem {
} }
/// Left side UIViews. /// Left side UIViews.
public var leftControls: [UIView]? { public var leftControls: [UIView] {
get { get {
return navigationItem.leftControls return navigationItem.leftControls
} }
...@@ -163,7 +163,7 @@ extension UINavigationItem { ...@@ -163,7 +163,7 @@ extension UINavigationItem {
} }
/// Right side UIViews. /// Right side UIViews.
public var rightControls: [UIView]? { public var rightControls: [UIView] {
get { get {
return navigationItem.rightControls return navigationItem.rightControls
} }
......
...@@ -49,7 +49,7 @@ open class Snackbar: BarView { ...@@ -49,7 +49,7 @@ open class Snackbar: BarView {
} }
/// Text label. /// Text label.
public private(set) var textLabel: UILabel! public internal(set) var textLabel: UILabel!
open override var intrinsicContentSize: CGSize { open override var intrinsicContentSize: CGSize {
return CGSize(width: width, height: 49) return CGSize(width: width, height: 49)
...@@ -58,22 +58,6 @@ open class Snackbar: BarView { ...@@ -58,22 +58,6 @@ open class Snackbar: BarView {
/// The status of the snackbar. /// The status of the snackbar.
open internal(set) var status = SnackbarStatus.notVisible open internal(set) var status = SnackbarStatus.notVisible
open override func layoutSubviews() {
super.layoutSubviews()
if willRenderView {
if nil != text && "" != text {
if nil == textLabel.superview {
contentView.addSubview(textLabel)
}
textLabel.frame = contentView.bounds
} else {
textLabel.removeFromSuperview()
}
contentView.grid.reload()
}
}
/** /**
Prepares the view instance when intialized. When subclassing, Prepares the view instance when intialized. When subclassing,
it is recommended to override the prepareView method it is recommended to override the prepareView method
...@@ -83,9 +67,10 @@ open class Snackbar: BarView { ...@@ -83,9 +67,10 @@ open class Snackbar: BarView {
*/ */
open override func prepareView() { open override func prepareView() {
super.prepareView() super.prepareView()
interimSpace = 24
contentEdgeInsets.left = interimSpace
contentEdgeInsets.right = interimSpace
backgroundColor = Color.grey.darken3 backgroundColor = Color.grey.darken3
grid.contentEdgeInsets = EdgeInsets(top: 0, left: 24, bottom: 0, right: 24)
grid.interimSpace = 24
prepareTextLabel() prepareTextLabel()
} }
...@@ -96,5 +81,6 @@ open class Snackbar: BarView { ...@@ -96,5 +81,6 @@ open class Snackbar: BarView {
textLabel.font = RobotoFont.medium(with: 14) textLabel.font = RobotoFont.medium(with: 14)
textLabel.textAlignment = .left textLabel.textAlignment = .left
textLabel.textColor = Color.white textLabel.textColor = Color.white
contentView.grid.views.append(textLabel)
} }
} }
...@@ -92,6 +92,7 @@ open class SnackbarController: RootController { ...@@ -92,6 +92,7 @@ open class SnackbarController: RootController {
*/ */
open func animate(snackbar status: SnackbarStatus, animations: (@escaping (Snackbar) -> Void)? = nil, completion: (@escaping (Snackbar) -> Void)? = nil) { open func animate(snackbar status: SnackbarStatus, animations: (@escaping (Snackbar) -> Void)? = nil, completion: (@escaping (Snackbar) -> Void)? = nil) {
isAnimating = true isAnimating = true
isUserInteractionEnabled = false
UIView.animate(withDuration: 0.25, animations: { [weak self, status = status, animations = animations] in UIView.animate(withDuration: 0.25, animations: { [weak self, status = status, animations = animations] in
guard let s = self else { guard let s = self else {
return return
...@@ -105,6 +106,7 @@ open class SnackbarController: RootController { ...@@ -105,6 +106,7 @@ open class SnackbarController: RootController {
} }
s.isAnimating = false s.isAnimating = false
s.isUserInteractionEnabled = true
s.snackbar.status = status s.snackbar.status = status
completion?(s.snackbar) completion?(s.snackbar)
} }
......
...@@ -43,7 +43,7 @@ open class Toolbar: BarView { ...@@ -43,7 +43,7 @@ open class Toolbar: BarView {
} }
/// Title label. /// Title label.
open private(set) var titleLabel: UILabel! open internal(set) var titleLabel: UILabel!
/// A convenience property to set the detailLabel text. /// A convenience property to set the detailLabel text.
open var detail: String? { open var detail: String? {
...@@ -57,7 +57,7 @@ open class Toolbar: BarView { ...@@ -57,7 +57,7 @@ open class Toolbar: BarView {
} }
/// Detail label. /// Detail label.
open private(set) var detailLabel: UILabel! open internal(set) var detailLabel: UILabel!
open override func layoutSubviews() { open override func layoutSubviews() {
super.layoutSubviews() super.layoutSubviews()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment