diff --git a/Display/TabBarContollerNode.swift b/Display/TabBarContollerNode.swift index f3ba582203..10c81fc011 100644 --- a/Display/TabBarContollerNode.swift +++ b/Display/TabBarContollerNode.swift @@ -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) diff --git a/Display/TabBarController.swift b/Display/TabBarController.swift index d671c6a3bb..42bade03ae 100644 --- a/Display/TabBarController.swift +++ b/Display/TabBarController.swift @@ -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() diff --git a/Display/Toolbar.swift b/Display/Toolbar.swift index b9c103f024..b609dc3534 100644 --- a/Display/Toolbar.swift +++ b/Display/Toolbar.swift @@ -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 } } diff --git a/Display/ToolbarNode.swift b/Display/ToolbarNode.swift index ab504b4a83..06bbda961c 100644 --- a/Display/ToolbarNode.swift +++ b/Display/ToolbarNode.swift @@ -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() + } } diff --git a/Display/ViewController.swift b/Display/ViewController.swift index 29a5be2113..ee9b509d4a 100644 --- a/Display/ViewController.swift +++ b/Display/ViewController.swift @@ -490,7 +490,7 @@ open class ViewControllerPresentationArguments { } } - open func toolbarActionSelected(left: Bool) { + open func toolbarActionSelected(action: ToolbarActionOption) { } }