Toolbar: add middle action

This commit is contained in:
Peter 2019-04-26 20:06:26 +04:00
parent 05c5fec8cb
commit 6f1f814217
5 changed files with 55 additions and 23 deletions

View File

@ -1,12 +1,18 @@
import Foundation
import AsyncDisplayKit
public enum ToolbarActionOption {
case left
case right
case middle
}
final class TabBarControllerNode: ASDisplayNode {
private var theme: TabBarControllerTheme
let tabBarNode: TabBarNode
private let navigationBar: NavigationBar?
private var toolbarNode: ToolbarNode?
private let toolbarActionSelected: (Bool) -> Void
private let toolbarActionSelected: (ToolbarActionOption) -> Void
var currentControllerNode: ASDisplayNode? {
didSet {
@ -18,21 +24,7 @@ final class TabBarControllerNode: ASDisplayNode {
}
}
/*override var accessibilityElements: [Any]? {
get {
var accessibilityElements: [Any] = []
if let navigationBar = self.navigationBar {
addAccessibilityChildren(of: navigationBar, container: self, to: &accessibilityElements)
}
if let currentControllerNode = self.currentControllerNode {
addAccessibilityChildren(of: currentControllerNode, container: self, to: &accessibilityElements)
}
return accessibilityElements
} set(value) {
}
}*/
init(theme: TabBarControllerTheme, navigationBar: NavigationBar?, itemSelected: @escaping (Int, Bool, [ASDisplayNode]) -> Void, toolbarActionSelected: @escaping (Bool) -> Void) {
init(theme: TabBarControllerTheme, navigationBar: NavigationBar?, itemSelected: @escaping (Int, Bool, [ASDisplayNode]) -> Void, toolbarActionSelected: @escaping (ToolbarActionOption) -> Void) {
self.theme = theme
self.navigationBar = navigationBar
self.tabBarNode = TabBarNode(theme: theme, itemSelected: itemSelected)
@ -81,9 +73,11 @@ final class TabBarControllerNode: ASDisplayNode {
toolbarNode.updateLayout(size: tabBarFrame.size, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right, bottomInset: bottomInset, toolbar: toolbar, transition: transition)
} else {
let toolbarNode = ToolbarNode(theme: self.theme, left: { [weak self] in
self?.toolbarActionSelected(true)
self?.toolbarActionSelected(.left)
}, right: { [weak self] in
self?.toolbarActionSelected(false)
self?.toolbarActionSelected(.right)
}, middle: { [weak self] in
self?.toolbarActionSelected(.middle)
})
toolbarNode.frame = tabBarFrame
toolbarNode.updateLayout(size: tabBarFrame.size, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right, bottomInset: bottomInset, toolbar: toolbar, transition: .immediate)

View File

@ -180,8 +180,8 @@ open class TabBarController: ViewController {
}
}))
}
}, toolbarActionSelected: { [weak self] left in
self?.currentController?.toolbarActionSelected(left: left)
}, toolbarActionSelected: { [weak self] action in
self?.currentController?.toolbarActionSelected(action: action)
})
self.updateSelectedIndex()

View File

@ -13,9 +13,11 @@ public struct ToolbarAction: Equatable {
public struct Toolbar: Equatable {
public let leftAction: ToolbarAction?
public let rightAction: ToolbarAction?
public let middleAction: ToolbarAction?
public init(leftAction: ToolbarAction?, rightAction: ToolbarAction?) {
public init(leftAction: ToolbarAction?, rightAction: ToolbarAction?, middleAction: ToolbarAction?) {
self.leftAction = leftAction
self.rightAction = rightAction
self.middleAction = middleAction
}
}

View File

@ -6,18 +6,22 @@ public final class ToolbarNode: ASDisplayNode {
private let displaySeparator: Bool
private let left: () -> Void
private let right: () -> Void
private let middle: () -> Void
private let separatorNode: ASDisplayNode
private let leftTitle: ImmediateTextNode
private let leftButton: HighlightableButtonNode
private let rightTitle: ImmediateTextNode
private let rightButton: HighlightableButtonNode
private let middleTitle: ImmediateTextNode
private let middleButton: HighlightableButtonNode
public init(theme: TabBarControllerTheme, displaySeparator: Bool = false, left: @escaping () -> Void, right: @escaping () -> Void) {
public init(theme: TabBarControllerTheme, displaySeparator: Bool = false, left: @escaping () -> Void, right: @escaping () -> Void, middle: @escaping () -> Void) {
self.theme = theme
self.displaySeparator = displaySeparator
self.left = left
self.right = right
self.middle = middle
self.separatorNode = ASDisplayNode()
self.separatorNode.isLayerBacked = true
@ -28,6 +32,9 @@ public final class ToolbarNode: ASDisplayNode {
self.rightTitle = ImmediateTextNode()
self.rightTitle.displaysAsynchronously = false
self.rightButton = HighlightableButtonNode()
self.middleTitle = ImmediateTextNode()
self.middleTitle.displaysAsynchronously = false
self.middleButton = HighlightableButtonNode()
super.init()
@ -35,6 +42,8 @@ public final class ToolbarNode: ASDisplayNode {
self.addSubnode(self.leftButton)
self.addSubnode(self.rightTitle)
self.addSubnode(self.rightButton)
self.addSubnode(self.middleTitle)
self.addSubnode(self.middleButton)
if self.displaySeparator {
self.addSubnode(self.separatorNode)
}
@ -65,6 +74,18 @@ public final class ToolbarNode: ASDisplayNode {
}
}
}
self.middleButton.addTarget(self, action: #selector(self.middlePressed), forControlEvents: .touchUpInside)
self.middleButton.highligthedChanged = { [weak self] highlighted in
if let strongSelf = self {
if highlighted {
strongSelf.middleTitle.layer.removeAnimation(forKey: "opacity")
strongSelf.middleTitle.alpha = 0.4
} else {
strongSelf.middleTitle.alpha = 1.0
strongSelf.middleTitle.layer.animateAlpha(from: 0.4, to: 1.0, duration: 0.2)
}
}
}
}
public func updateTheme(_ theme: TabBarControllerTheme) {
@ -79,11 +100,14 @@ public final class ToolbarNode: ASDisplayNode {
self.leftTitle.attributedText = NSAttributedString(string: toolbar.leftAction?.title ?? "", font: Font.regular(17.0), textColor: (toolbar.leftAction?.isEnabled ?? false) ? self.theme.tabBarSelectedTextColor : self.theme.tabBarTextColor)
self.rightTitle.attributedText = NSAttributedString(string: toolbar.rightAction?.title ?? "", font: Font.regular(17.0), textColor: (toolbar.rightAction?.isEnabled ?? false) ? self.theme.tabBarSelectedTextColor : self.theme.tabBarTextColor)
self.middleTitle.attributedText = NSAttributedString(string: toolbar.middleAction?.title ?? "", font: Font.regular(17.0), textColor: (toolbar.middleAction?.isEnabled ?? false) ? self.theme.tabBarSelectedTextColor : self.theme.tabBarTextColor)
let leftSize = self.leftTitle.updateLayout(size)
let rightSize = self.rightTitle.updateLayout(size)
let middleSize = self.middleTitle.updateLayout(size)
let leftFrame = CGRect(origin: CGPoint(x: leftInset + sideInset, y: floor((size.height - bottomInset - leftSize.height) / 2.0)), size: leftSize)
let rightFrame = CGRect(origin: CGPoint(x: size.width - rightInset - sideInset - rightSize.width, y: floor((size.height - bottomInset - rightSize.height) / 2.0)), size: rightSize)
let middleFrame = CGRect(origin: CGPoint(x: floor((size.width - middleSize.width) / 2.0), y: floor((size.height - bottomInset - middleSize.height) / 2.0)), size: middleSize)
if leftFrame.size == self.leftTitle.frame.size {
transition.updateFrame(node: self.leftTitle, frame: leftFrame)
@ -97,11 +121,19 @@ public final class ToolbarNode: ASDisplayNode {
self.rightTitle.frame = rightFrame
}
if middleFrame.size == self.middleTitle.frame.size {
transition.updateFrame(node: self.middleTitle, frame: middleFrame)
} else {
self.middleTitle.frame = middleFrame
}
self.leftButton.isEnabled = toolbar.leftAction?.isEnabled ?? false
self.rightButton.isEnabled = toolbar.rightAction?.isEnabled ?? false
self.middleButton.isEnabled = toolbar.middleAction?.isEnabled ?? false
self.leftButton.frame = CGRect(origin: CGPoint(x: leftInset, y: 0.0), size: CGSize(width: leftSize.width + sideInset * 2.0, height: size.height - bottomInset))
self.rightButton.frame = CGRect(origin: CGPoint(x: size.width - rightInset - sideInset * 2.0 - rightSize.width, y: 0.0), size: CGSize(width: rightSize.width + sideInset * 2.0, height: size.height - bottomInset))
self.middleButton.frame = CGRect(origin: CGPoint(x: floor((size.width - middleSize.width) / 2.0), y: 0.0), size: CGSize(width: middleSize.width + sideInset * 2.0, height: size.height - bottomInset))
}
@objc private func leftPressed() {
@ -111,4 +143,8 @@ public final class ToolbarNode: ASDisplayNode {
@objc private func rightPressed() {
self.right()
}
@objc private func middlePressed() {
self.middle()
}
}

View File

@ -490,7 +490,7 @@ open class ViewControllerPresentationArguments {
}
}
open func toolbarActionSelected(left: Bool) {
open func toolbarActionSelected(action: ToolbarActionOption) {
}
}