Various changes to NavigationBarContentNode to support putting search bar into navigation bar.

This commit is contained in:
Ilya Laktyushin 2019-01-03 21:41:03 +04:00
parent c91d10ec4b
commit ae7e54565b
5 changed files with 86 additions and 15 deletions

View File

@ -107,6 +107,7 @@ open class NavigationBar: ASDisplayNode {
private var validLayout: (CGSize, CGFloat, CGFloat)?
private var requestedLayout: Bool = false
var requestContainerLayout: (ContainedViewLayoutTransition) -> Void = { _ in }
public var backPressed: () -> () = { }
@ -519,6 +520,7 @@ open class NavigationBar: ASDisplayNode {
private let leftButtonNode: NavigationButtonNode
private let rightButtonNode: NavigationButtonNode
private var _transitionState: NavigationBarTransitionState?
var transitionState: NavigationBarTransitionState? {
get {
@ -722,14 +724,23 @@ open class NavigationBar: ASDisplayNode {
let backButtonInset: CGFloat = leftInset + 27.0
transition.updateFrame(node: self.clippingNode, frame: CGRect(origin: CGPoint(), size: size))
var expansionHeight: CGFloat = 0.0
if let contentNode = self.contentNode {
transition.updateFrame(node: contentNode, frame: CGRect(origin: CGPoint(x: leftInset, y: 0.0), size: CGSize(width: size.width - leftInset - rightInset, height: size.height)))
let contentNodeFrame: CGRect
switch contentNode.mode {
case .replacement:
contentNodeFrame = CGRect(origin: CGPoint(x: leftInset, y: 0.0), size: CGSize(width: size.width - leftInset - rightInset, height: size.height))
case .expansion:
expansionHeight = contentNode.height
contentNodeFrame = CGRect(origin: CGPoint(x: leftInset, y: size.height - expansionHeight), size: CGSize(width: size.width - leftInset - rightInset, height: expansionHeight))
}
transition.updateFrame(node: contentNode, frame: contentNodeFrame)
}
transition.updateFrame(node: self.stripeNode, frame: CGRect(x: 0.0, y: size.height, width: size.width, height: UIScreenPixel))
let nominalHeight: CGFloat = self.collapsed ? 32.0 : 44.0
let contentVerticalOrigin = size.height - nominalHeight
let contentVerticalOrigin = size.height - nominalHeight - expansionHeight
var leftTitleInset: CGFloat = leftInset + 1.0
var rightTitleInset: CGFloat = rightInset + 1.0
@ -960,6 +971,22 @@ open class NavigationBar: ASDisplayNode {
}
}
public var canTransitionInline: Bool {
if let contentNode = self.contentNode, case .replacement = contentNode.mode {
return false
} else {
return true
}
}
public var contentHeight: CGFloat {
if let contentNode = self.contentNode, case .expansion = contentNode.mode {
return 44.0 + contentNode.height
} else {
return 44.0
}
}
public func setContentNode(_ contentNode: NavigationBarContentNode?, animated: Bool) {
if self.contentNode !== contentNode {
if let previous = self.contentNode {
@ -976,6 +1003,9 @@ open class NavigationBar: ASDisplayNode {
}
}
self.contentNode = contentNode
self.contentNode?.requestContainerLayout = { [weak self] transition in
self?.requestContainerLayout(transition)
}
if let contentNode = contentNode {
contentNode.layer.removeAnimation(forKey: "opacity")
self.addSubnode(contentNode)
@ -983,7 +1013,7 @@ open class NavigationBar: ASDisplayNode {
contentNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
}
if !self.clippingNode.alpha.isZero {
if case .replacement = contentNode.mode, !self.clippingNode.alpha.isZero {
self.clippingNode.alpha = 0.0
if animated {
self.clippingNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2)
@ -1004,4 +1034,18 @@ open class NavigationBar: ASDisplayNode {
}
}
}
public func setHidden(_ hidden: Bool, animated: Bool) {
if let contentNode = self.contentNode, case .replacement = contentNode.mode {
} else {
let targetAlpha: CGFloat = hidden ? 0.0 : 1.0
let previousAlpha = self.clippingNode.alpha
if previousAlpha != targetAlpha {
self.clippingNode.alpha = targetAlpha
if animated {
self.clippingNode.layer.animateAlpha(from: previousAlpha, to: targetAlpha, duration: 0.2)
}
}
}
}
}

View File

@ -1,6 +1,23 @@
import Foundation
import AsyncDisplayKit
open class NavigationBarContentNode: ASDisplayNode {
public enum NavigationBarContentMode {
case replacement
case expansion
}
open class NavigationBarContentNode: ASDisplayNode {
open var requestContainerLayout: (ContainedViewLayoutTransition) -> Void = { _ in }
open var height: CGFloat {
return self.nominalHeight
}
open var nominalHeight: CGFloat {
return 0.0
}
open var mode: NavigationBarContentMode {
return .replacement
}
}

View File

@ -56,12 +56,12 @@ class NavigationTransitionCoordinator {
self.dimView.backgroundColor = UIColor.black
self.shadowView = UIImageView(image: shadowImage)
if let topNavigationBar = topNavigationBar, let bottomNavigationBar = bottomNavigationBar, !topNavigationBar.isHidden, !bottomNavigationBar.isHidden, topNavigationBar.contentNode == nil, bottomNavigationBar.contentNode == nil, topNavigationBar.item?.leftBarButtonItem == nil {
if let topNavigationBar = topNavigationBar, let bottomNavigationBar = bottomNavigationBar, !topNavigationBar.isHidden, !bottomNavigationBar.isHidden, topNavigationBar.canTransitionInline, bottomNavigationBar.canTransitionInline, topNavigationBar.item?.leftBarButtonItem == nil {
var topFrame = topNavigationBar.view.convert(topNavigationBar.bounds, to: container)
var bottomFrame = bottomNavigationBar.view.convert(bottomNavigationBar.bounds, to: container)
topFrame.origin.x = 0.0
bottomFrame.origin.x = 0.0
self.inlineNavigationBarTransition = topFrame.equalTo(bottomFrame)
self.inlineNavigationBarTransition = true// topFrame.equalTo(bottomFrame)
} else {
self.inlineNavigationBarTransition = false
}

View File

@ -158,9 +158,6 @@ open class TabBarController: ViewController {
var displayNavigationBar = false
if let currentController = self.currentController {
currentController.willMove(toParentViewController: self)
if let validLayout = self.validLayout {
currentController.containerLayoutUpdated(validLayout.addedInsets(insets: UIEdgeInsets(top: 0.0, left: 0.0, bottom: 49.0, right: 0.0)), transition: .immediate)
}
self.tabBarControllerNode.currentControllerView = currentController.view
currentController.navigationBar?.isHidden = true
self.addChildViewController(currentController)
@ -169,6 +166,7 @@ open class TabBarController: ViewController {
currentController.navigationBar?.layoutSuspended = true
currentController.navigationItem.setTarget(self.navigationItem)
displayNavigationBar = currentController.displayNavigationBar
self.navigationBar?.setContentNode(currentController.navigationBar?.contentNode, animated: false)
currentController.displayNode.recursivelyEnsureDisplaySynchronously(true)
self.statusBar.statusBarStyle = currentController.statusBar.statusBarStyle
} else {
@ -177,6 +175,7 @@ open class TabBarController: ViewController {
self.navigationItem.rightBarButtonItem = nil
self.navigationItem.titleView = nil
self.navigationItem.backBarButtonItem = nil
self.navigationBar?.setContentNode(nil, animated: false)
displayNavigationBar = false
}
if self.displayNavigationBar != displayNavigationBar {
@ -184,7 +183,7 @@ open class TabBarController: ViewController {
}
if let validLayout = self.validLayout {
self.tabBarControllerNode.containerLayoutUpdated(validLayout, toolbar: self.currentController?.toolbar, transition: .immediate)
self.containerLayoutUpdated(validLayout, transition: .immediate)
}
}

View File

@ -143,7 +143,11 @@ open class ViewControllerPresentationArguments {
open var navigationHeight: CGFloat {
if let navigationBar = self.navigationBar {
return navigationBar.frame.maxY
var height = navigationBar.frame.maxY
if let contentNode = navigationBar.contentNode, case .expansion = contentNode.mode {
height += contentNode.nominalHeight - contentNode.height
}
return height
} else {
return 0.0
}
@ -205,6 +209,9 @@ open class ViewControllerPresentationArguments {
strongSelf.navigationController?.popViewController(animated: true)
}
}
self.navigationBar?.requestContainerLayout = { [weak self] transition in
self?.requestLayout(transition: transition)
}
self.navigationBar?.item = self.navigationItem
self.automaticallyAdjustsScrollViewInsets = false
@ -233,7 +240,7 @@ open class ViewControllerPresentationArguments {
}
let statusBarHeight: CGFloat = layout.statusBarHeight ?? 0.0
let navigationBarHeight: CGFloat = max(20.0, statusBarHeight) + 44.0
let navigationBarHeight: CGFloat = max(20.0, statusBarHeight) + (self.navigationBar?.contentHeight ?? 44.0)
let navigationBarOffset: CGFloat
if statusBarHeight.isZero {
navigationBarOffset = -20.0
@ -242,19 +249,23 @@ open class ViewControllerPresentationArguments {
}
var navigationBarFrame = CGRect(origin: CGPoint(x: 0.0, y: navigationBarOffset), size: CGSize(width: layout.size.width, height: navigationBarHeight))
if layout.statusBarHeight == nil {
navigationBarFrame.size.height = 64.0
navigationBarFrame.size.height = (self.navigationBar?.contentHeight ?? 44.0) + 20.0
}
if !self.displayNavigationBar {
navigationBarFrame.origin.y = -navigationBarFrame.size.height
}
navigationBarOrigin = navigationBarFrame.origin.y
self.navigationBarOrigin = navigationBarFrame.origin.y
navigationBarFrame.origin.y += self.navigationOffset
if let navigationBar = self.navigationBar {
if let contentNode = navigationBar.contentNode, case .expansion = contentNode.mode, !self.displayNavigationBar {
navigationBarFrame.origin.y += contentNode.height + statusBarHeight
}
transition.updateFrame(node: navigationBar, frame: navigationBarFrame)
navigationBar.updateLayout(size: navigationBarFrame.size, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right, transition: transition)
navigationBar.setHidden(!self.displayNavigationBar, animated: transition.isAnimated)
}
self.presentationContext.containerLayoutUpdated(layout, transition: transition)