Skip to content
This repository has been archived by the owner on Dec 22, 2023. It is now read-only.

Commit

Permalink
Merge pull request #210 from zenangst/improve/family-when-using-compo…
Browse files Browse the repository at this point in the history
…sitional-layouts

Improve usage of compositional layouts
  • Loading branch information
zenangst committed Apr 26, 2021
2 parents e464cdd + 70e1bc1 commit ef80cea
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 124 deletions.
2 changes: 1 addition & 1 deletion Family.podspec
Original file line number Diff line number Diff line change
@@ -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" }
Expand Down
2 changes: 1 addition & 1 deletion Sources/Shared/FamilyFriendly.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import CoreGraphics
import Foundation

protocol FamilyFriendly: class {
protocol FamilyFriendly: AnyObject {
func addChild(_ childController: ViewController)
func addChild<T: ViewController>(_ childController: T,
at index: Int?,
Expand Down
73 changes: 19 additions & 54 deletions Sources/UIKit/FamilyScrollView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)
}
Expand Down Expand Up @@ -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 {
Expand All @@ -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
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
})
Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -756,18 +707,28 @@ 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
/// based on the views index inside `subviewsInLayoutOrder`. This is invoked
/// 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 }

Expand Down Expand Up @@ -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)
Expand Down
69 changes: 1 addition & 68 deletions Sources/UIKit/FamilyViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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()
}
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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
}
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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 {
Expand All @@ -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 {
Expand Down

0 comments on commit ef80cea

Please sign in to comment.