no message

This commit is contained in:
Peter 2016-12-22 03:19:59 +03:00
parent bed02f5c56
commit 269fccdcc9
9 changed files with 231 additions and 76 deletions

View File

@ -32,38 +32,46 @@ public enum ContainedViewLayoutTransition {
public extension ContainedViewLayoutTransition {
func updateFrame(node: ASDisplayNode, frame: CGRect, completion: ((Bool) -> Void)? = nil) {
switch self {
case .immediate:
node.frame = frame
if let completion = completion {
completion(true)
}
case let .animated(duration, curve):
let previousFrame = node.frame
node.frame = frame
node.layer.animateFrame(from: previousFrame, to: frame, duration: duration, timingFunction: curve.timingFunction, completion: { result in
if node.frame.equalTo(frame) {
completion?(true)
} else {
switch self {
case .immediate:
node.frame = frame
if let completion = completion {
completion(result)
completion(true)
}
})
case let .animated(duration, curve):
let previousFrame = node.frame
node.frame = frame
node.layer.animateFrame(from: previousFrame, to: frame, duration: duration, timingFunction: curve.timingFunction, completion: { result in
if let completion = completion {
completion(result)
}
})
}
}
}
func updatePosition(node: ASDisplayNode, position: CGPoint, completion: ((Bool) -> Void)? = nil) {
switch self {
case .immediate:
node.position = position
if let completion = completion {
completion(true)
}
case let .animated(duration, curve):
let previousPosition = node.position
node.position = position
node.layer.animatePosition(from: previousPosition, to: position, duration: duration, timingFunction: curve.timingFunction, completion: { result in
if node.position.equalTo(position) {
completion?(true)
} else {
switch self {
case .immediate:
node.position = position
if let completion = completion {
completion(result)
completion(true)
}
})
case let .animated(duration, curve):
let previousPosition = node.position
node.position = position
node.layer.animatePosition(from: previousPosition, to: position, duration: duration, timingFunction: curve.timingFunction, completion: { result in
if let completion = completion {
completion(result)
}
})
}
}
}
@ -83,17 +91,21 @@ public extension ContainedViewLayoutTransition {
}
func animatePosition(node: ASDisplayNode, to position: CGPoint, removeOnCompletion: Bool = true, completion: ((Bool) -> Void)? = nil) {
switch self {
case .immediate:
if let completion = completion {
completion(true)
if node.position.equalTo(position) {
completion?(true)
} else {
switch self {
case .immediate:
if let completion = completion {
completion(true)
}
case let .animated(duration, curve):
node.layer.animatePosition(from: node.position, to: position, duration: duration, timingFunction: curve.timingFunction, removeOnCompletion: removeOnCompletion, completion: { result in
if let completion = completion {
completion(result)
}
})
}
case let .animated(duration, curve):
node.layer.animatePosition(from: node.position, to: position, duration: duration, timingFunction: curve.timingFunction, removeOnCompletion: removeOnCompletion, completion: { result in
if let completion = completion {
completion(result)
}
})
}
}
@ -115,20 +127,24 @@ public extension ContainedViewLayoutTransition {
}
func updateFrame(layer: CALayer, frame: CGRect, completion: ((Bool) -> Void)? = nil) {
switch self {
case .immediate:
layer.frame = frame
if let completion = completion {
completion(true)
}
case let .animated(duration, curve):
let previousFrame = layer.frame
layer.frame = frame
layer.animateFrame(from: previousFrame, to: frame, duration: duration, timingFunction: curve.timingFunction, completion: { result in
if layer.frame.equalTo(frame) {
completion?(true)
} else {
switch self {
case .immediate:
layer.frame = frame
if let completion = completion {
completion(result)
completion(true)
}
})
case let .animated(duration, curve):
let previousFrame = layer.frame
layer.frame = frame
layer.animateFrame(from: previousFrame, to: frame, duration: duration, timingFunction: curve.timingFunction, completion: { result in
if let completion = completion {
completion(result)
}
})
}
}
}

View File

@ -13,6 +13,18 @@ public struct Font {
return CTFontCreateWithName("HelveticaNeue-Medium" as CFString, size, nil)
}
}
public static func bold(_ size: CGFloat) -> UIFont {
if #available(iOS 8.2, *) {
return UIFont.systemFont(ofSize: size, weight: UIFontWeightBold)
} else {
return CTFontCreateWithName("HelveticaNeue-Bold" as CFString, size, nil)
}
}
public static func italic(_ size: CGFloat) -> UIFont {
return UIFont.italicSystemFont(ofSize: size)
}
}
public extension NSAttributedString {

View File

@ -87,7 +87,16 @@ public func generateStretchableFilledCircleImage(radius: CGFloat, color: UIColor
public func generateStretchableFilledCircleImage(diameter: CGFloat, color: UIColor?, backgroundColor: UIColor? = nil) -> UIImage? {
let intRadius = Int(diameter / 2.0)
let cap = intRadius == 1 ? 2 : intRadius
let intDiameter = Int(diameter)
let cap: Int
if intDiameter == 3 {
cap = 1
} else if intRadius == 1 {
cap = 2
} else {
cap = intRadius
}
return generateFilledCircleImage(diameter: diameter, color: color, backgroundColor: backgroundColor)?.stretchableImage(withLeftCapWidth: cap, topCapHeight: cap)
}

View File

@ -1,6 +1,15 @@
import UIKit
private class GridNodeScrollerLayer: CALayer {
override func setNeedsDisplay() {
}
}
private class GridNodeScrollerView: UIScrollView {
override class var layerClass: AnyClass {
return GridNodeScrollerLayer.self
}
override func touchesShouldCancel(in view: UIView) -> Bool {
return true
}

View File

@ -14,6 +14,9 @@ private final class ListViewBackingLayer: CALayer {
override func layoutSublayers() {
}
override func setNeedsDisplay() {
}
}
final class ListViewBackingView: UIView {
@ -146,6 +149,8 @@ open class ListView: ASDisplayNode, UIScrollViewDelegate, UIGestureRecognizerDel
private var flashNodesDelayTimer: Foundation.Timer?
private var highlightedItemIndex: Int?
private let waitingForNodesDisposable = MetaDisposable()
public func reportDurationInMS(duration: Int, smallDropEvent: Double, largeDropEvent: Double) {
print("reportDurationInMS duration: \(duration), smallDropEvent: \(smallDropEvent), largeDropEvent: \(largeDropEvent)")
}
@ -241,6 +246,15 @@ open class ListView: ASDisplayNode, UIScrollViewDelegate, UIGestureRecognizerDel
deinit {
self.pauseAnimations()
self.displayLink.invalidate()
for itemNode in self.itemNodes {
ASDeallocQueue.sharedDeallocation().releaseObject(inBackground: itemNode)
}
for itemHeaderNode in self.itemHeaderNodes {
ASDeallocQueue.sharedDeallocation().releaseObject(inBackground: itemHeaderNode)
}
self.waitingForNodesDisposable.dispose()
}
@objc func frictionSliderChanged(_ slider: UISlider) {
@ -738,7 +752,7 @@ open class ListView: ASDisplayNode, UIScrollViewDelegate, UIGestureRecognizerDel
DispatchQueue.global().async(execute: f)
}
private func nodeForItem(synchronous: Bool, item: ListViewItem, previousNode: ListViewItemNode?, index: Int, previousItem: ListViewItem?, nextItem: ListViewItem?, width: CGFloat, updateAnimation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNode, ListViewItemNodeLayout, @escaping () -> Void) -> Void) {
private func nodeForItem(synchronous: Bool, item: ListViewItem, previousNode: ListViewItemNode?, index: Int, previousItem: ListViewItem?, nextItem: ListViewItem?, width: CGFloat, updateAnimation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNode, ListViewItemNodeLayout, @escaping () -> (Signal<Void, NoError>?, () -> Void)) -> Void) {
if let previousNode = previousNode {
item.updateNode(async: { f in
if synchronous {
@ -750,21 +764,27 @@ open class ListView: ASDisplayNode, UIScrollViewDelegate, UIGestureRecognizerDel
if Thread.isMainThread {
if synchronous {
completion(previousNode, layout, {
previousNode.index = index
apply()
return (nil, {
previousNode.index = index
apply()
})
})
} else {
self.async {
completion(previousNode, layout, {
previousNode.index = index
apply()
return (nil, {
previousNode.index = index
apply()
})
})
}
}
} else {
completion(previousNode, layout, {
previousNode.index = index
apply()
return (nil, {
previousNode.index = index
apply()
})
})
}
})
@ -1068,7 +1088,53 @@ open class ListView: ASDisplayNode, UIScrollViewDelegate, UIGestureRecognizerDel
let stationaryItemIndex = updatedState.stationaryOffset?.0
let next = {
self.replayOperations(animated: animated, animateAlpha: options.contains(.AnimateAlpha), animateTopItemVerticalOrigin: options.contains(.AnimateTopItemPosition), operations: updatedOperations, requestItemInsertionAnimationsIndices: options.contains(.RequestItemInsertionAnimations) ? insertedIndexSet : Set(), scrollToItem: scrollToItem, updateSizeAndInsets: updateSizeAndInsets, stationaryItemIndex: stationaryItemIndex, updateOpaqueState: updateOpaqueState, completion: completion)
var updatedOperations = updatedOperations
var readySignals: [Signal<Void, NoError>]?
if options.contains(.PreferSynchronousResourceLoading) {
var currentReadySignals: [Signal<Void, NoError>] = []
for i in 0 ..< updatedOperations.count {
if case let .InsertNode(index, offsetDirection, node, layout, apply) = updatedOperations[i] {
let (ready, commitApply) = apply()
updatedOperations[i] = .InsertNode(index: index, offsetDirection: offsetDirection, node: node, layout: layout, apply: {
return (nil, commitApply)
})
if let ready = ready {
currentReadySignals.append(ready)
}
}
}
readySignals = currentReadySignals
}
let beginReplay = { [weak self] in
if let strongSelf = self {
strongSelf.replayOperations(animated: animated, animateAlpha: options.contains(.AnimateAlpha), animateTopItemVerticalOrigin: options.contains(.AnimateTopItemPosition), operations: updatedOperations, requestItemInsertionAnimationsIndices: options.contains(.RequestItemInsertionAnimations) ? insertedIndexSet : Set(), scrollToItem: scrollToItem, updateSizeAndInsets: updateSizeAndInsets, stationaryItemIndex: stationaryItemIndex, updateOpaqueState: updateOpaqueState, completion: {
if options.contains(.PreferSynchronousResourceLoading) {
let startTime = CACurrentMediaTime()
self?.recursivelyEnsureDisplaySynchronously(true)
let deltaTime = CACurrentMediaTime() - startTime
print("ListView: waited \(deltaTime * 1000.0) ms for nodes to display")
}
completion()
})
}
}
if let readySignals = readySignals, !readySignals.isEmpty && false {
let readyWithTimeout = combineLatest(readySignals)
|> deliverOnMainQueue
|> timeout(0.2, queue: Queue.mainQueue(), alternate: .single([]))
let startTime = CACurrentMediaTime()
self.waitingForNodesDisposable.set(readyWithTimeout.start(completed: {
let deltaTime = CACurrentMediaTime() - startTime
print("ListView: waited \(deltaTime * 1000.0) ms for nodes to load")
beginReplay()
}))
} else {
beginReplay()
}
}
if options.contains(.LowLatency) || options.contains(.Synchronous) {
@ -1123,7 +1189,9 @@ open class ListView: ASDisplayNode, UIScrollViewDelegate, UIGestureRecognizerDel
let heightDelta = layout.size.height - updatedState.nodes[i].frame.size.height
updatedOperations.append(.UpdateLayout(index: i, layout: layout, apply: apply))
updatedOperations.append(.UpdateLayout(index: i, layout: layout, apply: {
return (nil, apply)
}))
if !animated {
let previousFrame = updatedState.nodes[i].frame
@ -1252,7 +1320,7 @@ open class ListView: ASDisplayNode, UIScrollViewDelegate, UIGestureRecognizerDel
}
}
private func insertNodeAtIndex(animated: Bool, animateAlpha: Bool, forceAnimateInsertion: Bool, previousFrame: CGRect?, nodeIndex: Int, offsetDirection: ListViewInsertionOffsetDirection, node: ListViewItemNode, layout: ListViewItemNodeLayout, apply: () -> (), timestamp: Double) {
private func insertNodeAtIndex(animated: Bool, animateAlpha: Bool, forceAnimateInsertion: Bool, previousFrame: CGRect?, nodeIndex: Int, offsetDirection: ListViewInsertionOffsetDirection, node: ListViewItemNode, layout: ListViewItemNodeLayout, apply: () -> (Signal<Void, NoError>?, () -> Void), timestamp: Double) {
let insertionOrigin = self.referencePointForInsertionAtIndex(nodeIndex)
let nodeOrigin: CGPoint
@ -1272,7 +1340,7 @@ open class ListView: ASDisplayNode, UIScrollViewDelegate, UIGestureRecognizerDel
node.insets = layout.insets
node.apparentHeight = animated ? 0.0 : layout.size.height
node.frame = nodeFrame
apply()
apply().1()
self.itemNodes.insert(node, at: nodeIndex)
if useDynamicTuning {
@ -1514,10 +1582,10 @@ open class ListView: ASDisplayNode, UIScrollViewDelegate, UIGestureRecognizerDel
if let height = height, let previousLayout = previousLayout {
if takenPreviousNodes.contains(referenceNode) {
self.insertNodeAtIndex(animated: false, animateAlpha: false, forceAnimateInsertion: false, previousFrame: nil, nodeIndex: index, offsetDirection: offsetDirection, node: ListViewItemNode(layerBacked: true), layout: ListViewItemNodeLayout(contentSize: CGSize(width: self.visibleSize.width, height: height), insets: UIEdgeInsets()), apply: { }, timestamp: timestamp)
self.insertNodeAtIndex(animated: false, animateAlpha: false, forceAnimateInsertion: false, previousFrame: nil, nodeIndex: index, offsetDirection: offsetDirection, node: ListViewItemNode(layerBacked: true), layout: ListViewItemNodeLayout(contentSize: CGSize(width: self.visibleSize.width, height: height), insets: UIEdgeInsets()), apply: { return (nil, {}) }, timestamp: timestamp)
} else {
referenceNode.index = nil
self.insertNodeAtIndex(animated: false, animateAlpha: false, forceAnimateInsertion: false, previousFrame: nil, nodeIndex: index, offsetDirection: offsetDirection, node: referenceNode, layout: previousLayout, apply: { }, timestamp: timestamp)
self.insertNodeAtIndex(animated: false, animateAlpha: false, forceAnimateInsertion: false, previousFrame: nil, nodeIndex: index, offsetDirection: offsetDirection, node: referenceNode, layout: previousLayout, apply: { return (nil, {}) }, timestamp: timestamp)
self.addSubnode(referenceNode)
}
} else {
@ -1562,7 +1630,7 @@ open class ListView: ASDisplayNode, UIScrollViewDelegate, UIGestureRecognizerDel
node.contentSize = layout.contentSize
node.insets = layout.insets
apply()
apply().1()
let updatedApparentHeight = node.bounds.size.height
let updatedInsets = node.insets
@ -1893,7 +1961,6 @@ open class ListView: ASDisplayNode, UIScrollViewDelegate, UIGestureRecognizerDel
let lowestHeaderNode = self.lowestHeaderNode()
for itemNode in temporaryPreviousNodes {
itemNode.frame = itemNode.frame.offsetBy(dx: 0.0, dy: offset)
temporaryPreviousNodes.append(itemNode)
if let lowestHeaderNode = lowestHeaderNode {
self.insertSubnode(itemNode, belowSubnode: lowestHeaderNode)
} else {
@ -1942,12 +2009,18 @@ open class ListView: ASDisplayNode, UIScrollViewDelegate, UIGestureRecognizerDel
animation.completion = { _ in
for itemNode in temporaryPreviousNodes {
itemNode.removeFromSupernode()
ASDeallocQueue.sharedDeallocation().releaseObject(inBackground: itemNode)
}
for headerNode in temporaryHeaderNodes {
headerNode.removeFromSupernode()
ASDeallocQueue.sharedDeallocation().releaseObject(inBackground: headerNode)
}
}
self.layer.add(animation, forKey: nil)
} else {
for itemNode in temporaryPreviousNodes {
ASDeallocQueue.sharedDeallocation().releaseObject(inBackground: itemNode)
}
}
}
@ -1977,6 +2050,12 @@ open class ListView: ASDisplayNode, UIScrollViewDelegate, UIGestureRecognizerDel
//print("replayOperations \(delta * 1000.0) ms")
}
for (previousNode, _) in previousApparentFrames {
if previousNode.supernode == nil {
ASDeallocQueue.sharedDeallocation().releaseObject(inBackground: previousNode)
}
}
completion()
}
})
@ -2306,6 +2385,7 @@ open class ListView: ASDisplayNode, UIScrollViewDelegate, UIGestureRecognizerDel
let node = self.itemNodes[i]
if node.index == nil && node.apparentHeight <= CGFloat(FLT_EPSILON) {
self.removeItemNodeAtIndex(i)
ASDeallocQueue.sharedDeallocation().releaseObject(inBackground: node)
} else {
i += 1
}
@ -2507,6 +2587,9 @@ open class ListView: ASDisplayNode, UIScrollViewDelegate, UIGestureRecognizerDel
if true { //!(itemNode.hitTest(CGPoint(x: strongSelf.touchesPosition.x - itemNode.frame.minX, y: strongSelf.touchesPosition.y - itemNode.frame.minY), with: event) is UIControl) {
if !itemNode.isLayerBacked {
strongSelf.view.bringSubview(toFront: itemNode.view)
for (_, headerNode) in strongSelf.itemHeaderNodes {
strongSelf.view.bringSubview(toFront: headerNode.view)
}
}
itemNode.setHighlighted(true, animated: false)
}
@ -2594,6 +2677,9 @@ open class ListView: ASDisplayNode, UIScrollViewDelegate, UIGestureRecognizerDel
if itemNode.index == index {
if !itemNode.isLayerBacked {
self.view.bringSubview(toFront: itemNode.view)
for (_, headerNode) in self.itemHeaderNodes {
self.view.bringSubview(toFront: headerNode.view)
}
}
itemNode.setHighlighted(true, animated: false)
break

View File

@ -1,4 +1,5 @@
import Foundation
import SwiftSignalKit
public enum ListViewCenterScrollPositionOverflow {
case Top
@ -121,6 +122,7 @@ public struct ListViewDeleteAndInsertOptions: OptionSet {
public static let Synchronous = ListViewDeleteAndInsertOptions(rawValue: 8)
public static let RequestItemInsertionAnimations = ListViewDeleteAndInsertOptions(rawValue: 16)
public static let AnimateTopItemPosition = ListViewDeleteAndInsertOptions(rawValue: 32)
public static let PreferSynchronousResourceLoading = ListViewDeleteAndInsertOptions(rawValue: 64)
}
public struct ListViewUpdateSizeAndInsets {
@ -222,7 +224,7 @@ struct TransactionState {
struct PendingNode {
let index: Int
let node: ListViewItemNode
let apply: () -> ()
let apply: () -> (Signal<Void, NoError>?, () -> Void)
let frame: CGRect
let apparentHeight: CGFloat
}
@ -701,7 +703,7 @@ struct ListViewState {
return height
}
mutating func insertNode(_ itemIndex: Int, node: ListViewItemNode, layout: ListViewItemNodeLayout, apply: @escaping () -> (), offsetDirection: ListViewInsertionOffsetDirection, animated: Bool, operations: inout [ListViewStateOperation], itemCount: Int) {
mutating func insertNode(_ itemIndex: Int, node: ListViewItemNode, layout: ListViewItemNodeLayout, apply: @escaping () -> (Signal<Void, NoError>?, () -> Void), offsetDirection: ListViewInsertionOffsetDirection, animated: Bool, operations: inout [ListViewStateOperation], itemCount: Int) {
let (insertionOrigin, insertionIndex) = self.nodeInsertionPointAndIndex(itemIndex)
let nodeOrigin: CGPoint
@ -806,7 +808,7 @@ struct ListViewState {
}
}
mutating func updateNodeAtItemIndex(_ itemIndex: Int, layout: ListViewItemNodeLayout, direction: ListViewItemOperationDirectionHint?, animation: ListViewItemUpdateAnimation, apply: @escaping () -> Void, operations: inout [ListViewStateOperation]) {
mutating func updateNodeAtItemIndex(_ itemIndex: Int, layout: ListViewItemNodeLayout, direction: ListViewItemOperationDirectionHint?, animation: ListViewItemUpdateAnimation, apply: @escaping () -> (Signal<Void, NoError>?, () -> Void), operations: inout [ListViewStateOperation]) {
var i = -1
for node in self.nodes {
i += 1
@ -862,9 +864,9 @@ struct ListViewState {
}
enum ListViewStateOperation {
case InsertNode(index: Int, offsetDirection: ListViewInsertionOffsetDirection, node: ListViewItemNode, layout: ListViewItemNodeLayout, apply: () -> ())
case InsertNode(index: Int, offsetDirection: ListViewInsertionOffsetDirection, node: ListViewItemNode, layout: ListViewItemNodeLayout, apply: () -> (Signal<Void, NoError>?, () -> Void))
case InsertDisappearingPlaceholder(index: Int, referenceNode: ListViewItemNode, offsetDirection: ListViewInsertionOffsetDirection)
case Remove(index: Int, offsetDirection: ListViewInsertionOffsetDirection)
case Remap([Int: Int])
case UpdateLayout(index: Int, layout: ListViewItemNodeLayout, apply: () -> ())
case UpdateLayout(index: Int, layout: ListViewItemNodeLayout, apply: () -> (Signal<Void, NoError>?, () -> Void))
}

View File

@ -6,8 +6,22 @@ public enum ListViewItemUpdateAnimation {
case System(duration: Double)
}
public struct ListViewItemConfigureNodeFlags: OptionSet {
public var rawValue: Int32
public init() {
self.rawValue = 0
}
public init(rawValue: Int32) {
self.rawValue = rawValue
}
public static let preferSynchronousResourceLoading = ListViewItemConfigureNodeFlags(rawValue: 1 << 0)
}
public protocol ListViewItem {
func nodeConfiguredForWidth(async: @escaping (@escaping () -> Void) -> Void, width: CGFloat, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> Void) -> Void)
func nodeConfiguredForWidth(async: @escaping (@escaping () -> Void) -> Void, width: CGFloat, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal<Void, NoError>?, () -> Void)) -> Void)
func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: ListViewItemNode, width: CGFloat, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping () -> Void) -> Void)
var accessoryItem: ListViewAccessoryItem? { get }
@ -37,8 +51,4 @@ public extension ListViewItem {
func selected(listView: ListView) {
}
func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: ListViewItemNode, width: CGFloat, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping () -> Void) -> Void) {
completion(ListViewItemNodeLayout(contentSize: node.contentSize, insets: node.insets), {})
}
}

View File

@ -1,5 +1,6 @@
import Foundation
import AsyncDisplayKit
import SwiftSignalKit
var testSpringFrictionLimits: (CGFloat, CGFloat) = (3.0, 60.0)
var testSpringFriction: CGFloat = 31.8211269378662
@ -133,6 +134,10 @@ open class ListViewItemNode: ASDisplayNode {
return ListViewItemNodeLayout(contentSize: contentSize, insets: insets)
}
public var displayResourcesReady: Signal<Void, NoError> {
return .complete()
}
public init(layerBacked: Bool, dynamicBounce: Bool = true, rotated: Bool = false) {
if true {
if dynamicBounce {
@ -163,6 +168,12 @@ open class ListViewItemNode: ASDisplayNode {
self.isLayerBacked = layerBacked
}
/*deinit {
if Thread.isMainThread {
print("deallocating on main thread")
}
}*/
var apparentHeight: CGFloat = 0.0
private var _bounds: CGRect = CGRect()
private var _position: CGPoint = CGPoint()

View File

@ -56,7 +56,7 @@ class NavigationTransitionCoordinator {
self.dimView.backgroundColor = UIColor.black
self.shadowView = UIImageView(image: shadowImage)
if let topNavigationBar = topNavigationBar, let bottomNavigationBar = bottomNavigationBar {
if let topNavigationBar = topNavigationBar, let bottomNavigationBar = bottomNavigationBar, !topNavigationBar.isHidden, !bottomNavigationBar.isHidden {
var topFrame = topNavigationBar.view.convert(topNavigationBar.bounds, to: container)
var bottomFrame = bottomNavigationBar.view.convert(bottomNavigationBar.bounds, to: container)
topFrame.origin.x = 0.0
@ -111,7 +111,7 @@ class NavigationTransitionCoordinator {
}
func updateNavigationBarTransition() {
if let topNavigationBar = self.topNavigationBar, let bottomNavigationBar = self.bottomNavigationBar {
if let topNavigationBar = self.topNavigationBar, let bottomNavigationBar = self.bottomNavigationBar, self.inlineNavigationBarTransition {
let position: CGFloat
switch self.transition {
case .Push:
@ -126,7 +126,7 @@ class NavigationTransitionCoordinator {
}
func maybeCreateNavigationBarTransition() {
if let topNavigationBar = self.topNavigationBar, let bottomNavigationBar = self.bottomNavigationBar {
if let topNavigationBar = self.topNavigationBar, let bottomNavigationBar = self.bottomNavigationBar, self.inlineNavigationBarTransition {
let position: CGFloat
switch self.transition {
case .Push:
@ -141,7 +141,7 @@ class NavigationTransitionCoordinator {
}
func endNavigationBarTransition() {
if let topNavigationBar = self.topNavigationBar, let bottomNavigationBar = self.bottomNavigationBar {
if let topNavigationBar = self.topNavigationBar, let bottomNavigationBar = self.bottomNavigationBar, self.inlineNavigationBarTransition {
topNavigationBar.transitionState = nil
bottomNavigationBar.transitionState = nil
}