Commit 9efac5ec by Daniel Dahan

development: updates to RootController types and Snackbar

parent e1fd6014
......@@ -51,7 +51,7 @@ extension UIViewController {
@IBDesignable
public class MenuController: RootController {
/// Reference to the MenuView.
public private(set) lazy var menuView: MenuView = MenuView()
public private(set) lazy var menuView: MenuView = MenuView()
/**
Opens the menu with a callback.
......
......@@ -75,14 +75,14 @@ public class NavigationItem {
/// Prepares the titleLabel.
private func prepareTitleLabel() {
titleLabel = UILabel()
titleLabel.font = RobotoFont.mediumWithSize(size: 17)
titleLabel.font = RobotoFont.medium(with: 17)
titleLabel.textAlignment = .center
}
/// Prepares the detailLabel.
private func prepareDetailLabel() {
detailLabel = UILabel()
detailLabel.font = RobotoFont.regularWithSize(size: 12)
detailLabel.font = RobotoFont.regular(with: 12)
detailLabel.textAlignment = .center
}
}
......
......@@ -110,7 +110,7 @@ open class PageTabBarController: RootController {
open var pageTabBarAlignment = PageTabBarAlignment.bottom
/// Reference to the PageTabBar.
open internal(set) var pageTabBar: PageTabBar!
open internal(set) lazy var pageTabBar: PageTabBar = PageTabBar()
/// Delegation handler.
open weak var delegate: PageTabBarControllerDelegate?
......@@ -147,30 +147,39 @@ open class PageTabBarController: RootController {
*/
open override func layoutSubviews() {
super.layoutSubviews()
guard let v = pageTabBar else {
return
}
let w = view.width
let h = view.height
let p = v.intrinsicContentSize.height + v.grid.layoutEdgeInsets.top + v.grid.layoutEdgeInsets.bottom
let p = pageTabBar.intrinsicContentSize.height + pageTabBar.grid.layoutEdgeInsets.top + pageTabBar.grid.layoutEdgeInsets.bottom
let y = h - p
v.height = p
v.width = w + v.grid.layoutEdgeInsets.left + v.grid.layoutEdgeInsets.right
pageTabBar.height = p
pageTabBar.width = w + pageTabBar.grid.layoutEdgeInsets.left + pageTabBar.grid.layoutEdgeInsets.right
rootViewController.view.height = y
switch pageTabBarAlignment {
case .top:
v.y = 0
pageTabBar.y = 0
rootViewController.view.y = p
case .bottom:
v.y = y
pageTabBar.y = y
rootViewController.view.y = 0
}
v.divider.reload()
pageTabBar.divider.reload()
}
/**
Sets the view controllers.
- Parameter _ viewController: An Array of UIViewControllers.
- Parameter direction: A UIPageViewControllerNavigationDirection enum value.
- Parameter animated: A boolean indicating to include animation.
- Parameter completion: An optional completion block.
*/
open func setViewControllers(_ viewControllers: [UIViewController], direction: UIPageViewControllerNavigationDirection, animated: Bool, completion: (@escaping (Bool) -> Void)? = nil) {
pageViewController?.setViewControllers(viewControllers, direction: direction, animated: animated, completion: completion)
preparePageTabBarItems()
}
/**
......@@ -248,19 +257,9 @@ open class PageTabBarController: RootController {
/// Prepares the pageTabBar.
private func preparePageTabBar() {
if nil == pageTabBar {
pageTabBar = PageTabBar()
pageTabBar.zPosition = 1000
view.addSubview(pageTabBar)
pageTabBar.select(at: selectedIndex)
}
}
}
extension PageTabBarController {
open func setViewControllers(_ viewControllers: [UIViewController]?, direction: UIPageViewControllerNavigationDirection, animated: Bool, completion: (@escaping (Bool) -> Void)? = nil) {
pageViewController?.setViewControllers(viewControllers, direction: direction, animated: animated, completion: completion)
preparePageTabBarItems()
pageTabBar.zPosition = 1000
view.addSubview(pageTabBar)
pageTabBar.select(at: selectedIndex)
}
}
......
......@@ -38,35 +38,35 @@ public struct RobotoFont: FontType {
/// Thin font.
public static var thin: UIFont {
return thinWithSize(size: Font.pointSize)
return thin(with: Font.pointSize)
}
/// Light font.
public static var light: UIFont {
return lightWithSize(size: Font.pointSize)
return light(with: Font.pointSize)
}
/// Regular font.
public static var regular: UIFont {
return regularWithSize(size: Font.pointSize)
return regular(with: Font.pointSize)
}
/// Medium font.
public static var medium: UIFont {
return mediumWithSize(size: Font.pointSize)
return medium(with: Font.pointSize)
}
/// Bold font.
public static var bold: UIFont {
return boldWithSize(size: Font.pointSize)
return bold(with: Font.pointSize)
}
/**
Thin with size font.
- Parameter size: A CGFLoat for the font size.
- Parameter with size: A CGFLoat for the font size.
- Returns: A UIFont.
*/
public static func thinWithSize(size: CGFloat) -> UIFont {
public static func thin(with size: CGFloat) -> UIFont {
Font.loadFontIfNeeded(name: "Roboto-Thin")
if let f = UIFont(name: "Roboto-Thin", size: size) {
return f
......@@ -76,10 +76,10 @@ public struct RobotoFont: FontType {
/**
Light with size font.
- Parameter size: A CGFLoat for the font size.
- Parameter with size: A CGFLoat for the font size.
- Returns: A UIFont.
*/
public static func lightWithSize(size: CGFloat) -> UIFont {
public static func light(with size: CGFloat) -> UIFont {
Font.loadFontIfNeeded(name: "Roboto-Light")
if let f = UIFont(name: "Roboto-Light", size: size) {
return f
......@@ -89,10 +89,10 @@ public struct RobotoFont: FontType {
/**
Regular with size font.
- Parameter size: A CGFLoat for the font size.
- Parameter with size: A CGFLoat for the font size.
- Returns: A UIFont.
*/
public static func regularWithSize(size: CGFloat) -> UIFont {
public static func regular(with size: CGFloat) -> UIFont {
Font.loadFontIfNeeded(name: "Roboto-Regular")
if let f = UIFont(name: "Roboto-Regular", size: size) {
return f
......@@ -102,10 +102,10 @@ public struct RobotoFont: FontType {
/**
Medium with size font.
- Parameter size: A CGFLoat for the font size.
- Parameter with size: A CGFLoat for the font size.
- Returns: A UIFont.
*/
public static func mediumWithSize(size: CGFloat) -> UIFont {
public static func medium(with size: CGFloat) -> UIFont {
Font.loadFontIfNeeded(name: "Roboto-Medium")
if let f = UIFont(name: "Roboto-Medium", size: size) {
return f
......@@ -115,10 +115,10 @@ public struct RobotoFont: FontType {
/**
Bold with size font.
- Parameter size: A CGFLoat for the font size.
- Parameter with size: A CGFLoat for the font size.
- Returns: A UIFont.
*/
public static func boldWithSize(size: CGFloat) -> UIFont {
public static func bold(with size: CGFloat) -> UIFont {
Font.loadFontIfNeeded(name: "Roboto-Bold")
if let f = UIFont(name: "Roboto-Bold", size: size) {
return f
......
......@@ -30,15 +30,16 @@
import UIKit
public class SearchBar: BarView {
open class SearchBar: BarView {
/// The UITextField for the searchBar.
public private(set) var textField: UITextField!
open private(set) var textField: UITextField!
/// Reference to the clearButton.
public private(set) var clearButton: IconButton!
open private(set) var clearButton: IconButton!
/// Handle the clearButton manually.
@IBInspectable public var clearButtonAutoHandleEnabled: Bool = true {
@IBInspectable
open var clearButtonAutoHandleEnabled: Bool = true {
didSet {
clearButton.removeTarget(self, action: #selector(handleClearButton), for: .touchUpInside)
if clearButtonAutoHandleEnabled {
......@@ -48,7 +49,8 @@ public class SearchBar: BarView {
}
/// TintColor for searchBar.
@IBInspectable public override var tintColor: UIColor? {
@IBInspectable
open override var tintColor: UIColor? {
get {
return textField.tintColor
}
......@@ -58,7 +60,8 @@ public class SearchBar: BarView {
}
/// TextColor for searchBar.
@IBInspectable public var textColor: UIColor? {
@IBInspectable
open var textColor: UIColor? {
get {
return textField.textColor
}
......@@ -68,7 +71,8 @@ public class SearchBar: BarView {
}
/// Sets the textField placeholder value.
@IBInspectable public var placeholder: String? {
@IBInspectable
open var placeholder: String? {
didSet {
if let v: String = placeholder {
textField.attributedPlaceholder = NSAttributedString(string: v, attributes: [NSForegroundColorAttributeName: placeholderColor])
......@@ -77,7 +81,8 @@ public class SearchBar: BarView {
}
/// Placeholder textColor.
@IBInspectable public var placeholderColor: UIColor = Color.darkText.others {
@IBInspectable
open var placeholderColor: UIColor = Color.darkText.others {
didSet {
if let v: String = placeholder {
textField.attributedPlaceholder = NSAttributedString(string: v, attributes: [NSForegroundColorAttributeName: placeholderColor])
......@@ -85,7 +90,7 @@ public class SearchBar: BarView {
}
}
public override func layoutSubviews() {
open override func layoutSubviews() {
super.layoutSubviews()
if willRenderView {
textField.frame = contentView.bounds
......@@ -127,14 +132,14 @@ public class SearchBar: BarView {
The super.prepareView method should always be called immediately
when subclassing.
*/
public override func prepareView() {
open override func prepareView() {
super.prepareView()
prepareTextField()
prepareClearButton()
}
/// Layout the clearButton.
public func layoutClearButton() {
open func layoutClearButton() {
let h: CGFloat = textField.frame.height
clearButton.frame = CGRect(x: textField.frame.width - h, y: 0, width: h, height: h)
}
......@@ -148,7 +153,7 @@ public class SearchBar: BarView {
private func prepareTextField() {
textField = UITextField()
textField.contentScaleFactor = Device.scale
textField.font = RobotoFont.regularWithSize(size: 17)
textField.font = RobotoFont.regular(with: 17)
textField.backgroundColor = Color.clear
textField.clearButtonMode = .whileEditing
tintColor = placeholderColor
......
......@@ -50,7 +50,7 @@ extension UIViewController {
open class SearchBarController: RootController {
/// Reference to the SearchBar.
open internal(set) var searchBar: SearchBar!
open internal(set) lazy var searchBar: SearchBar = SearchBar()
/**
To execute in the order of the layout chain, override this
......@@ -59,23 +59,20 @@ open class SearchBarController: RootController {
*/
open override func layoutSubviews() {
super.layoutSubviews()
guard let v = searchBar else {
return
}
v.grid.layoutEdgeInsets.top = .phone == Device.userInterfaceIdiom && Device.isLandscape ? 0 : 20
searchBar.grid.layoutEdgeInsets.top = .phone == Device.userInterfaceIdiom && Device.isLandscape ? 0 : 20
let w = view.width
let h = view.height
let p = v.intrinsicContentSize.height + v.grid.layoutEdgeInsets.top + v.grid.layoutEdgeInsets.bottom
let p = searchBar.intrinsicContentSize.height + searchBar.grid.layoutEdgeInsets.top + searchBar.grid.layoutEdgeInsets.bottom
v.width = w + v.grid.layoutEdgeInsets.left + v.grid.layoutEdgeInsets.right
v.height = p
searchBar.width = w + searchBar.grid.layoutEdgeInsets.left + searchBar.grid.layoutEdgeInsets.right
searchBar.height = p
rootViewController.view.y = p
rootViewController.view.height = h - p
v.divider.reload()
searchBar.divider.reload()
}
/**
......@@ -92,10 +89,7 @@ open class SearchBarController: RootController {
/// Prepares the searchBar.
private func prepareSearchBar() {
if nil == searchBar {
searchBar = SearchBar()
searchBar.zPosition = 1000
view.addSubview(searchBar)
}
searchBar.zPosition = 1000
view.addSubview(searchBar)
}
}
......@@ -30,55 +30,49 @@
import UIKit
@objc(SnackbarDelegate)
public protocol SnackbarDelegate {
/**
A delegation method that is executed when a Snackbar will show.
- Parameter snackbar: A Snackbar.
*/
@objc
optional func snackbarWillShow(snackbar: Snackbar)
/**
A delegation method that is executed when a Snackbar did show.
- Parameter snackbar: A Snackbar.
*/
@objc
optional func snackbarDidShow(snackbar: Snackbar)
/**
A delegation method that is executed when a Snackbar will hide.
- Parameter snackbar: A Snackbar.
*/
@objc
optional func snackbarWillHide(snackbar: Snackbar)
/**
A delegation method that is executed when a Snackbar did hide.
- Parameter snackbar: A Snackbar.
*/
@objc
optional func snackbarDidHide(snackbar: Snackbar)
}
@objc(SnackbarStatus)
public enum SnackbarStatus: Int {
case visible
case notVisible
case animating
}
@objc(Snackbar)
open class Snackbar: BarView {
/// Delegation handler.
open weak var delegate: SnackbarDelegate?
/// A convenience property to set the titleLabel text.
public var text: String? {
get {
return textLabel?.text
}
set(value) {
textLabel?.text = value
layoutSubviews()
}
}
/// Text label.
public private(set) var textLabel: UILabel!
open override var intrinsicContentSize: CGSize {
return CGSize(width: width, height: 48)
return CGSize(width: width, height: 49)
}
/// The status of the snackbar.
open internal(set) var status = SnackbarStatus.visible
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,
......@@ -89,6 +83,18 @@ open class Snackbar: BarView {
*/
open override func prepareView() {
super.prepareView()
backgroundColor = Color.grey.darken4
backgroundColor = Color.grey.darken3
grid.contentEdgeInsets = EdgeInsets(top: 0, left: 24, bottom: 0, right: 24)
grid.interimSpace = 24
prepareTextLabel()
}
/// Prepares the textLabel.
private func prepareTextLabel() {
textLabel = UILabel()
textLabel.contentScaleFactor = Device.scale
textLabel.font = RobotoFont.medium(with: 14)
textLabel.textAlignment = .left
textLabel.textColor = Color.white
}
}
......@@ -30,6 +30,37 @@
import UIKit
//@objc(SnackbarDelegate)
//public protocol SnackbarDelegate {
// /**
// A delegation method that is executed when a Snackbar will show.
// - Parameter snackbar: A Snackbar.
// */
// @objc
// optional func snackbarWillShow(snackbar: Snackbar)
//
// /**
// A delegation method that is executed when a Snackbar did show.
// - Parameter snackbar: A Snackbar.
// */
// @objc
// optional func snackbarDidShow(snackbar: Snackbar)
//
// /**
// A delegation method that is executed when a Snackbar will hide.
// - Parameter snackbar: A Snackbar.
// */
// @objc
// optional func snackbarWillHide(snackbar: Snackbar)
//
// /**
// A delegation method that is executed when a Snackbar did hide.
// - Parameter snackbar: A Snackbar.
// */
// @objc
// optional func snackbarDidHide(snackbar: Snackbar)
//}
extension UIViewController {
/**
A convenience property that provides access to the SnackbarController.
......@@ -49,14 +80,35 @@ extension UIViewController {
}
open class SnackbarController: RootController {
/**
A boolean that indicates whether to move the view controller
when the Snackbar animates.
*/
open var isSnackbarAttachedToController = false
/// A boolean indicating if the Snacbar is animating.
open internal(set) var isAnimating = false
/// Reference to the Snackbar.
open internal(set) var snackbar: Snackbar!
open internal(set) lazy var snackbar: Snackbar = Snackbar()
/**
Animates to a SnackbarStatus.
- Parameter status: A SnackbarStatus enum value.
*/
open func animate(snackbar status: SnackbarStatus, animations: (@escaping (Snackbar) -> Void)? = nil, completion: (@escaping (Snackbar) -> Void)? = nil) {
isAnimating = true
UIView.animate(withDuration: 0.25, animations: { [weak self, status = status, animations = animations] in
guard let s = self else {
return
}
s.layoutSnackbar(status: status)
animations?(s.snackbar)
}) { [weak self, status = status, completion = completion] _ in
guard let s = self else {
return
}
s.isAnimating = false
s.snackbar.status = status
completion?(s.snackbar)
}
}
/**
To execute in the order of the layout chain, override this
......@@ -65,35 +117,11 @@ open class SnackbarController: RootController {
*/
open override func layoutSubviews() {
super.layoutSubviews()
guard let v = snackbar else {
guard !isAnimating else {
return
}
let w = view.width
let h = view.height
let p = v.intrinsicContentSize.height + v.grid.layoutEdgeInsets.top + v.grid.layoutEdgeInsets.bottom
v.width = w
v.height = p
rootViewController.view.x = 0
rootViewController.view.y = 0
rootViewController.view.width = w
switch v.status {
case .visible:
let y = h - p
v.y = y
v.isHidden = false
rootViewController.view.height = y
case .notVisible:
v.y = h
v.isHidden = true
rootViewController.view.height = h
case .animating:break
}
v.divider.reload()
layoutSnackbar(status: snackbar.status)
}
/**
......@@ -110,10 +138,42 @@ open class SnackbarController: RootController {
/// Prepares the snackbar.
private func prepareSnackbar() {
if nil == snackbar {
snackbar = Snackbar()
snackbar.zPosition = 10000
view.addSubview(snackbar)
snackbar.zPosition = 10000
view.addSubview(snackbar)
}
/**
Lays out the Snackbar.
- Parameter status: A SnackbarStatus enum value.
*/
private func layoutSnackbar(status: SnackbarStatus) {
guard let vc = rootViewController else {
return
}
let w = view.width
let h = view.height
let p = snackbar.intrinsicContentSize.height + snackbar.grid.layoutEdgeInsets.top + snackbar.grid.layoutEdgeInsets.bottom
snackbar.width = w
snackbar.height = p
vc.view.x = 0
vc.view.y = 0
vc.view.width = w
switch status {
case .visible:
let y = h - p
snackbar.y = y
snackbar.isHidden = false
vc.view.height = y
case .notVisible:
snackbar.y = h
snackbar.isHidden = true
vc.view.height = h
}
snackbar.divider.reload()
}
}
......@@ -49,16 +49,16 @@ extension UIViewController {
}
@IBDesignable
public class StatusBarController: RootController {
open class StatusBarController: RootController {
/// A reference to the statusBarView.
public private(set) var statusBarView: View!
open internal(set) lazy var statusBarView = View()
/**
To execute in the order of the layout chain, override this
method. LayoutSubviews should be called immediately, unless you
have a certain need.
*/
public override func layoutSubviews() {
open override func layoutSubviews() {
super.layoutSubviews()
statusBarView.isHidden = Device.isLandscape && .phone == Device.userInterfaceIdiom
rootViewController.view.frame = view.bounds
......@@ -71,14 +71,13 @@ public class StatusBarController: RootController {
The super.prepareView method should always be called immediately
when subclassing.
*/
public override func prepareView() {
open override func prepareView() {
super.prepareView()
prepareStatusBarView()
}
/// Prepares the statusBarView.
private func prepareStatusBarView() {
statusBarView = View()
statusBarView.zPosition = 3000
statusBarView.backgroundColor = Color.black.withAlphaComponent(0.12)
_ = view.layout(statusBarView).top(0).horizontally().height(20)
......
......@@ -509,13 +509,13 @@ open class TextField: UITextField {
private func preparePlaceholderLabel() {
placeholderLabel = UILabel(frame: .zero)
placeholderColor = Color.darkText.others
font = RobotoFont.regularWithSize(size: 16)
font = RobotoFont.regular(with: 16)
addSubview(placeholderLabel)
}
/// Prepares the detailLabel.
private func prepareDetailLabel() {
detailLabel.font = RobotoFont.regularWithSize(size: 12)
detailLabel.font = RobotoFont.regular(with: 12)
detailColor = Color.darkText.others
addSubview(detailLabel)
}
......
......@@ -30,9 +30,9 @@
import UIKit
public class Toolbar: BarView {
open class Toolbar: BarView {
/// A convenience property to set the titleLabel text.
public var title: String? {
open var title: String? {
get {
return titleLabel?.text
}
......@@ -43,10 +43,10 @@ public class Toolbar: BarView {
}
/// Title label.
public private(set) var titleLabel: UILabel!
open private(set) var titleLabel: UILabel!
/// A convenience property to set the detailLabel text.
public var detail: String? {
open var detail: String? {
get {
return detailLabel?.text
}
......@@ -57,9 +57,9 @@ public class Toolbar: BarView {
}
/// Detail label.
public private(set) var detailLabel: UILabel!
open private(set) var detailLabel: UILabel!
public override func layoutSubviews() {
open override func layoutSubviews() {
super.layoutSubviews()
if willRenderView {
......@@ -134,7 +134,7 @@ public class Toolbar: BarView {
The super.prepareView method should always be called immediately
when subclassing.
*/
public override func prepareView() {
open override func prepareView() {
super.prepareView()
prepareTitleLabel()
prepareDetailLabel()
......@@ -144,7 +144,7 @@ public class Toolbar: BarView {
private func prepareTitleLabel() {
titleLabel = UILabel()
titleLabel.contentScaleFactor = Device.scale
titleLabel.font = RobotoFont.mediumWithSize(size: 17)
titleLabel.font = RobotoFont.medium(with: 17)
titleLabel.textAlignment = .left
}
......@@ -152,7 +152,7 @@ public class Toolbar: BarView {
private func prepareDetailLabel() {
detailLabel = UILabel()
detailLabel.contentScaleFactor = Device.scale
detailLabel.font = RobotoFont.regularWithSize(size: 12)
detailLabel.font = RobotoFont.regular(with: 12)
detailLabel.textAlignment = .left
}
}
......@@ -73,7 +73,7 @@ open class ToolbarController: RootController {
private var internalFloatingViewController: UIViewController?
/// Reference to the Toolbar.
open internal(set) var toolbar: Toolbar!
open internal(set) lazy var toolbar: Toolbar = Toolbar()
/// Delegation handler.
open weak var delegate: ToolbarControllerDelegate?
......@@ -84,7 +84,7 @@ open class ToolbarController: RootController {
return internalFloatingViewController
}
set(value) {
if let v: UIViewController = internalFloatingViewController {
if let v = internalFloatingViewController {
v.view.layer.rasterizationScale = Device.scale
v.view.layer.shouldRasterize = true
delegate?.toolbarControllerWillCloseFloatingViewController?(toolbarController: self)
......@@ -113,7 +113,7 @@ open class ToolbarController: RootController {
}
}
if let v: UIViewController = value {
if let v = value {
// Add the noteViewController! to the view.
addChildViewController(v)
v.view.frame = view.bounds
......@@ -162,23 +162,20 @@ open class ToolbarController: RootController {
*/
open override func layoutSubviews() {
super.layoutSubviews()
guard let v = toolbar else {
return
}
v.grid.layoutEdgeInsets.top = .phone == Device.userInterfaceIdiom && Device.isLandscape ? 0 : 20
toolbar.grid.layoutEdgeInsets.top = .phone == Device.userInterfaceIdiom && Device.isLandscape ? 0 : 20
let w = view.width
let h = view.height
let p = v.intrinsicContentSize.height + v.grid.layoutEdgeInsets.top + v.grid.layoutEdgeInsets.bottom
let p = toolbar.intrinsicContentSize.height + toolbar.grid.layoutEdgeInsets.top + toolbar.grid.layoutEdgeInsets.bottom
v.width = w + v.grid.layoutEdgeInsets.left + v.grid.layoutEdgeInsets.right
v.height = p
toolbar.width = w + toolbar.grid.layoutEdgeInsets.left + toolbar.grid.layoutEdgeInsets.right
toolbar.height = p
rootViewController.view.y = p
rootViewController.view.height = h - p
v.divider.reload()
toolbar.divider.reload()
}
/**
......@@ -195,10 +192,7 @@ open class ToolbarController: RootController {
/// Prepares the toolbar.
private func prepareToolbar() {
if nil == toolbar {
toolbar = Toolbar()
toolbar.zPosition = 1000
view.addSubview(toolbar)
}
toolbar.zPosition = 1000
view.addSubview(toolbar)
}
}
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