diff --git a/Family.podspec b/Family.podspec index 41ca911..bde2836 100644 --- a/Family.podspec +++ b/Family.podspec @@ -1,7 +1,7 @@ Pod::Spec.new do |s| s.name = "Family" s.summary = "A child view controller framework that makes setting up your parent controllers as easy as pie." - s.version = "2.2.2" + s.version = "2.2.3" s.homepage = "https://github.com/zenangst/Family" s.license = 'MIT' s.author = { "Christoffer Winterkvist" => "christoffer@winterkvist.com" } diff --git a/Sources/Shared/FamilyFriendly.swift b/Sources/Shared/FamilyFriendly.swift index 5fe58cd..b7af565 100644 --- a/Sources/Shared/FamilyFriendly.swift +++ b/Sources/Shared/FamilyFriendly.swift @@ -1,7 +1,7 @@ import CoreGraphics import Foundation -protocol FamilyFriendly: class { +protocol FamilyFriendly: AnyObject { func addChild(_ childController: ViewController) func addChild(_ childController: T, at index: Int?, diff --git a/Sources/UIKit/FamilyScrollView.swift b/Sources/UIKit/FamilyScrollView.swift index e8eb04c..4108dc3 100644 --- a/Sources/UIKit/FamilyScrollView.swift +++ b/Sources/UIKit/FamilyScrollView.swift @@ -2,7 +2,6 @@ import UIKit public class FamilyScrollView: UIScrollView, UIGestureRecognizerDelegate { - public static var signpostsEnabled: Bool = false public var isFastScrolling: Bool = false /// The amount of insets that should be inserted inbetween views. @@ -164,12 +163,6 @@ public class FamilyScrollView: UIScrollView, UIGestureRecognizerDelegate { } } - if Self.signpostsEnabled { - let log = OSSignpostController(category: String(describing: FamilyScrollView.self), signpostsEnabled: Self.signpostsEnabled) - log.signpost(.begin, #function) - defer { log.signpost(.end, #function) } - } - if backgrounds.values.contains(view) { super.addSubview(view) return @@ -213,12 +206,6 @@ public class FamilyScrollView: UIScrollView, UIGestureRecognizerDelegate { } } - if Self.signpostsEnabled { - let log = OSSignpostController(category: String(describing: FamilyScrollView.self), signpostsEnabled: Self.signpostsEnabled) - log.signpost(.begin, #function) - defer { log.signpost(.end, #function) } - } - if backgrounds.values.contains(view) { super.addSubview(view) return @@ -255,12 +242,6 @@ public class FamilyScrollView: UIScrollView, UIGestureRecognizerDelegate { } private func addSubviewsInLayoutOrder() { - if Self.signpostsEnabled { - let log = OSSignpostController(category: String(describing: FamilyScrollView.self), signpostsEnabled: Self.signpostsEnabled) - log.signpost(.begin, #function) - defer { log.signpost(.end, #function) } - } - for (index, view) in subviewsInLayoutOrder.reversed().enumerated() { super.insertSubview(view, at: index) } @@ -291,12 +272,6 @@ public class FamilyScrollView: UIScrollView, UIGestureRecognizerDelegate { /// - Parameter scrollView: The scroll view that should be configured /// and observed. func didAddScrollViewToContainer(_ scrollView: UIScrollView) { - if Self.signpostsEnabled { - let log = OSSignpostController(category: String(describing: FamilyScrollView.self), signpostsEnabled: Self.signpostsEnabled) - log.signpost(.begin, #function) - defer { log.signpost(.end, #function) } - } - scrollView.autoresizingMask = [.flexibleWidth] guard subviewsInLayoutOrder.contains(scrollView) else { @@ -311,12 +286,6 @@ public class FamilyScrollView: UIScrollView, UIGestureRecognizerDelegate { /// /// - Parameter subview: The subview that got removed from the view heirarcy. open override func willRemoveSubview(_ subview: UIView) { - if Self.signpostsEnabled { - let log = OSSignpostController(category: String(describing: FamilyScrollView.self), signpostsEnabled: Self.signpostsEnabled) - log.signpost(.begin, #function) - defer { log.signpost(.end, #function) } - } - if subview.isSystemView { isFastScrolling = false return @@ -392,12 +361,6 @@ public class FamilyScrollView: UIScrollView, UIGestureRecognizerDelegate { } func adjustContentSize(for view: UIView, scrollView: UIScrollView, withAnimation animation: CAAnimation?) { - if Self.signpostsEnabled { - let log = OSSignpostController(category: String(describing: FamilyScrollView.self), signpostsEnabled: Self.signpostsEnabled) - log.signpost(.begin, #function) - defer { log.signpost(.end, #function) } - } - guard let entry = cache.entry(for: view) else { return } let validAttributes = getValidAttributes(in: discardableRect) let margins = self.margins(for: entry.view) @@ -456,12 +419,6 @@ public class FamilyScrollView: UIScrollView, UIGestureRecognizerDelegate { /// /// - Parameter view: The view that should be observered. private func observeView(view: UIScrollView) { - if Self.signpostsEnabled { - let log = OSSignpostController(category: String(describing: FamilyScrollView.self), signpostsEnabled: Self.signpostsEnabled) - log.signpost(.begin, #function) - defer { log.signpost(.end, #function) } - } - observers.filter({ $0.view === view }).forEach({ observers.remove($0) }) @@ -584,12 +541,6 @@ public class FamilyScrollView: UIScrollView, UIGestureRecognizerDelegate { func purgeWrapperViews() { if isPerformingBatchUpdates { return } - if Self.signpostsEnabled { - let log = OSSignpostController(category: String(describing: FamilyScrollView.self), signpostsEnabled: Self.signpostsEnabled) - log.signpost(.begin, #function) - defer { log.signpost(.end, #function) } - } - for case let wrapperView as FamilyWrapperView in subviews { if wrapperView != wrapperView.view.superview { wrapperView.removeFromSuperview() @@ -756,6 +707,21 @@ public class FamilyScrollView: UIScrollView, UIGestureRecognizerDelegate { layoutViews() } + private func applyCompositionalLayoutFix(_ collectionView: UICollectionView) { + // Compositional layouts won't adjust the layouts content size if the collection view + // has a non-positive height. To work around this issue, we try and bump the collection views + // height to at least one pixel if the collection view has items and the height is 0. + // This will kick-off a re-render and the view will now show up in the hierarchy. + if #available(tvOS 13.0, *) { + if collectionView.numberOfItems(inSection: 0) > 0, + collectionView.frame.size.height == 0, + (collectionView.collectionViewLayout is UICollectionViewCompositionalLayout) + { + collectionView.frame.size.height = 1 + } + } + } + // MARK: - Layout Algorithm /// The layout algorithm simply lays out the view in linear order vertically @@ -763,11 +729,6 @@ public class FamilyScrollView: UIScrollView, UIGestureRecognizerDelegate { /// when a view changes size or origin. It also scales the frame of scroll views /// in order to keep dequeuing for table and collection views. internal func runLayoutSubviewsAlgorithm() { - if Self.signpostsEnabled { - let log = OSSignpostController(category: String(describing: FamilyScrollView.self), signpostsEnabled: Self.signpostsEnabled) - log.signpost(.begin, #function) - defer { log.signpost(.end, #function) } - } guard cache.state != .isRunning else { return } @@ -866,6 +827,10 @@ public class FamilyScrollView: UIScrollView, UIGestureRecognizerDelegate { let scrollView = attributes.scrollView let padding = spaceManager.padding(for: attributes.view) + if let collectionView = scrollView as? UICollectionView { + applyCompositionalLayoutFix(collectionView) + } + var frame = scrollView.frame var contentOffset = scrollView.contentOffset var newHeight: CGFloat = fmin(self.frame.height, scrollView.contentSize.height) diff --git a/Sources/UIKit/FamilyViewController.swift b/Sources/UIKit/FamilyViewController.swift index 7b0fef7..a4e64c2 100644 --- a/Sources/UIKit/FamilyViewController.swift +++ b/Sources/UIKit/FamilyViewController.swift @@ -7,7 +7,6 @@ import UIKit /// adds the controllers view or custom view to view heirarcy inside the /// content view of the `FamilyScrollView`. open class FamilyViewController: UIViewController, FamilyFriendly { - public static var signpostsEnabled: Bool = false var registry = [ViewController: (view: View, observer: NSKeyValueObservation)]() /// A custom implementation of a `UIScrollView` that handles continious scrolling @@ -185,13 +184,6 @@ open class FamilyViewController: UIViewController, FamilyFriendly { /// /// - Parameter childController: The view controller to be added as a child. open override func addChild(_ childController: UIViewController) { - if Self.signpostsEnabled { - let log = OSSignpostController(category: String(describing: FamilyViewController.self), - signpostsEnabled: Self.signpostsEnabled) - log.signpost(.begin, #function) - defer { log.signpost(.end, #function) } - } - if childController.parent != nil { childController.removeFromParent() } @@ -222,13 +214,6 @@ open class FamilyViewController: UIViewController, FamilyFriendly { insets: Insets? = nil, height: CGFloat? = nil, view handler: ((T) -> UIView)? = nil) -> Self { - if Self.signpostsEnabled { - let log = OSSignpostController(category: String(describing: FamilyViewController.self), - signpostsEnabled: Self.signpostsEnabled) - log.signpost(.begin, #function) - defer { log.signpost(.end, #function) } - } - purgeRemovedViews() childController.willMove(toParent: self) super.addChild(childController) @@ -286,13 +271,6 @@ open class FamilyViewController: UIViewController, FamilyFriendly { at index: Int? = nil, insets: Insets? = nil, height: CGFloat? = nil) -> Self { - if Self.signpostsEnabled { - let log = OSSignpostController(category: String(describing: FamilyViewController.self), - signpostsEnabled: Self.signpostsEnabled) - log.signpost(.begin, #function) - defer { log.signpost(.end, #function) } - } - var newWidth = view.bounds.size.width if let insets = insets { @@ -326,13 +304,6 @@ open class FamilyViewController: UIViewController, FamilyFriendly { /// /// - Returns: A collection of view controllers. public func viewControllersInLayoutOrder() -> [ViewController] { - if Self.signpostsEnabled { - let log = OSSignpostController(category: String(describing: FamilyViewController.self), - signpostsEnabled: Self.signpostsEnabled) - log.signpost(.begin, #function) - defer { log.signpost(.end, #function) } - } - if !_viewControllersInLayoutOrder.isEmpty { return _viewControllersInLayoutOrder } @@ -405,25 +376,8 @@ open class FamilyViewController: UIViewController, FamilyFriendly { animation: CAAnimation? = nil, _ handler: (FamilyViewController) -> Void, completion: ((FamilyViewController, Bool) -> Void)? = nil) -> Self { - if Self.signpostsEnabled { - let log = OSSignpostController(category: String(describing: FamilyViewController.self), - signpostsEnabled: Self.signpostsEnabled) - log.signpost(.begin, #function) - defer { log.signpost(.end, #function) } - } - scrollView.isPerformingBatchUpdates = true - if Self.signpostsEnabled { - let handlerLog = OSSignpostController(category: String(describing: FamilyViewController.self), - name: "performBatchupdates.handler", - signpostsEnabled: Self.signpostsEnabled) - handlerLog.signpost(.begin, "performBatchupdates.handler") - handler(self) - handlerLog.signpost(.end, "performBatchupdates.handler") - } else { - handler(self) - } - + handler(self) _viewControllersInLayoutOrder = [] scrollView.isPerformingBatchUpdates = false @@ -489,13 +443,6 @@ open class FamilyViewController: UIViewController, FamilyFriendly { public func purgeRemovedViews() -> Self { if scrollView.isPerformingBatchUpdates { return self } - if Self.signpostsEnabled { - let log = OSSignpostController(category: String(describing: FamilyViewController.self), - signpostsEnabled: Self.signpostsEnabled) - log.signpost(.begin, #function) - defer { log.signpost(.end, #function) } - } - for (controller, container) in registry where controller.parent == nil { _removeChild(controller) if container.view.superview is FamilyWrapperView { @@ -558,13 +505,6 @@ open class FamilyViewController: UIViewController, FamilyFriendly { /// on if an index is provided. /// - index: An optional index for where the view should appear. private func addOrInsertView(_ view: UIView, at index: Int? = nil) { - if Self.signpostsEnabled { - let log = OSSignpostController(category: String(describing: FamilyViewController.self), - signpostsEnabled: Self.signpostsEnabled) - log.signpost(.begin, #function) - defer { log.signpost(.end, #function) } - } - if let index = index, index < scrollView.subviews.count { scrollView.insertSubview(view, at: index) } else { @@ -585,13 +525,6 @@ open class FamilyViewController: UIViewController, FamilyFriendly { /// - Returns: A view that matches the criteria depending on the /// view controllers type. private func viewToAdd(from childController: UIViewController) -> View { - if Self.signpostsEnabled { - let log = OSSignpostController(category: String(describing: FamilyViewController.self), - signpostsEnabled: Self.signpostsEnabled) - log.signpost(.begin, #function) - defer { log.signpost(.end, #function) } - } - let view: UIView switch childController {