Skip to content

Commit

Permalink
Add completion handlers to the UIKit extensions
Browse files Browse the repository at this point in the history
  • Loading branch information
ellneal committed Dec 3, 2020
1 parent f8c8d1e commit be1cd5b
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 14 deletions.
32 changes: 27 additions & 5 deletions Sources/Extensions/AppKitExtension.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,23 @@ public extension NSTableView {
/// updates should be stopped and performed reloadData. Default is nil.
/// - setData: A closure that takes the collection as a parameter.
/// The collection should be set to data-source of NSTableView.
/// - completion: A closure that is called when the reload is completed.

func reload<C>(
using stagedChangeset: StagedChangeset<C>,
with animation: @autoclosure () -> NSTableView.AnimationOptions,
interrupt: ((Changeset<C>) -> Bool)? = nil,
setData: (C) -> Void
setData: (C) -> Void,
completion: (() -> Void)? = nil
) {
reload(
using: stagedChangeset,
deleteRowsAnimation: animation(),
insertRowsAnimation: animation(),
reloadRowsAnimation: animation(),
interrupt: interrupt,
setData: setData
setData: setData,
completion: completion
)
}

Expand All @@ -47,14 +50,21 @@ public extension NSTableView {
/// updates should be stopped and performed reloadData. Default is nil.
/// - setData: A closure that takes the collection as a parameter.
/// The collection should be set to data-source of NSTableView.
/// - completion: A closure that is called when the reload is completed.
func reload<C>(
using stagedChangeset: StagedChangeset<C>,
deleteRowsAnimation: @autoclosure () -> NSTableView.AnimationOptions,
insertRowsAnimation: @autoclosure () -> NSTableView.AnimationOptions,
reloadRowsAnimation: @autoclosure () -> NSTableView.AnimationOptions,
interrupt: ((Changeset<C>) -> Bool)? = nil,
setData: (C) -> Void
setData: (C) -> Void,
completion: (() -> Void)? = nil
) {
let group = DispatchGroup()
defer {
group.notify(queue: .main) { completion?() }
}

if case .none = window, let data = stagedChangeset.last?.data {
setData(data)
return reloadData()
Expand All @@ -66,6 +76,9 @@ public extension NSTableView {
return reloadData()
}

group.enter()
CATransaction.begin()
CATransaction.setCompletionBlock({ group.leave() })
beginUpdates()
setData(changeset.data)

Expand All @@ -86,6 +99,7 @@ public extension NSTableView {
}

endUpdates()
CATransaction.commit()
}
}
}
Expand All @@ -104,11 +118,18 @@ public extension NSCollectionView {
/// updates should be stopped and performed reloadData. Default is nil.
/// - setData: A closure that takes the collection as a parameter.
/// The collection should be set to data-source of NSCollectionView.
/// - completion: A closure that is called when the reload is completed.
func reload<C>(
using stagedChangeset: StagedChangeset<C>,
interrupt: ((Changeset<C>) -> Bool)? = nil,
setData: (C) -> Void
setData: (C) -> Void,
completion: (() -> Void)? = nil
) {
let group = DispatchGroup()
defer {
group.notify(queue: .main) { completion?() }
}

if case .none = window, let data = stagedChangeset.last?.data {
setData(data)
return reloadData()
Expand All @@ -120,6 +141,7 @@ public extension NSCollectionView {
return reloadData()
}

group.enter()
animator().performBatchUpdates({
setData(changeset.data)

Expand All @@ -138,7 +160,7 @@ public extension NSCollectionView {
for (source, target) in changeset.elementMoved {
moveItem(at: IndexPath(item: source.element, section: source.section), to: IndexPath(item: target.element, section: target.section))
}
})
}, completionHandler: { _ in group.leave() })
}
}
}
Expand Down
40 changes: 31 additions & 9 deletions Sources/Extensions/UIKitExtension.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,13 @@ public extension UITableView {
/// updates should be stopped and performed reloadData. Default is nil.
/// - setData: A closure that takes the collection as a parameter.
/// The collection should be set to data-source of UITableView.
/// - completion: A closure that is called when the reload is completed.
func reload<C>(
using stagedChangeset: StagedChangeset<C>,
with animation: @autoclosure () -> RowAnimation,
interrupt: ((Changeset<C>) -> Bool)? = nil,
setData: (C) -> Void
setData: (C) -> Void,
completion: (() -> Void)? = nil
) {
reload(
using: stagedChangeset,
Expand All @@ -30,7 +32,8 @@ public extension UITableView {
insertRowsAnimation: animation(),
reloadRowsAnimation: animation(),
interrupt: interrupt,
setData: setData
setData: setData,
completion: completion
)
}

Expand All @@ -52,6 +55,7 @@ public extension UITableView {
/// updates should be stopped and performed reloadData. Default is nil.
/// - setData: A closure that takes the collection as a parameter.
/// The collection should be set to data-source of UITableView.
/// - completion: A closure that is called when the reload is completed.
func reload<C>(
using stagedChangeset: StagedChangeset<C>,
deleteSectionsAnimation: @autoclosure () -> RowAnimation,
Expand All @@ -61,8 +65,14 @@ public extension UITableView {
insertRowsAnimation: @autoclosure () -> RowAnimation,
reloadRowsAnimation: @autoclosure () -> RowAnimation,
interrupt: ((Changeset<C>) -> Bool)? = nil,
setData: (C) -> Void
setData: (C) -> Void,
completion: (() -> Void)? = nil
) {
let group = DispatchGroup()
defer {
group.notify(queue: .main) { completion?() }
}

if case .none = window, let data = stagedChangeset.last?.data {
setData(data)
return reloadData()
Expand All @@ -74,7 +84,8 @@ public extension UITableView {
return reloadData()
}

_performBatchUpdates {
group.enter()
_performBatchUpdates({
setData(changeset.data)

if !changeset.sectionDeleted.isEmpty {
Expand Down Expand Up @@ -108,18 +119,21 @@ public extension UITableView {
for (source, target) in changeset.elementMoved {
moveRow(at: IndexPath(row: source.element, section: source.section), to: IndexPath(row: target.element, section: target.section))
}
}
}, completion: { group.leave() })
}
}

private func _performBatchUpdates(_ updates: () -> Void) {
private func _performBatchUpdates(_ updates: () -> Void, completion: (() -> Void)?) {
if #available(iOS 11.0, tvOS 11.0, *) {
performBatchUpdates(updates)
performBatchUpdates(updates, completion: { _ in completion?() })
}
else {
CATransaction.begin()
CATransaction.setCompletionBlock(completion)
beginUpdates()
updates()
endUpdates()
CATransaction.commit()
}
}
}
Expand All @@ -137,11 +151,18 @@ public extension UICollectionView {
/// updates should be stopped and performed reloadData. Default is nil.
/// - setData: A closure that takes the collection as a parameter.
/// The collection should be set to data-source of UICollectionView.
/// - completion: A closure that is called when the reload is completed.
func reload<C>(
using stagedChangeset: StagedChangeset<C>,
interrupt: ((Changeset<C>) -> Bool)? = nil,
setData: (C) -> Void
setData: (C) -> Void,
completion: (() -> Void)? = nil
) {
let group = DispatchGroup()
defer {
group.notify(queue: .main) { completion?() }
}

if case .none = window, let data = stagedChangeset.last?.data {
setData(data)
return reloadData()
Expand All @@ -153,6 +174,7 @@ public extension UICollectionView {
return reloadData()
}

group.enter()
performBatchUpdates({
setData(changeset.data)

Expand Down Expand Up @@ -187,7 +209,7 @@ public extension UICollectionView {
for (source, target) in changeset.elementMoved {
moveItem(at: IndexPath(item: source.element, section: source.section), to: IndexPath(item: target.element, section: target.section))
}
})
}, completion: { _ in group.leave() })
}
}
}
Expand Down

0 comments on commit be1cd5b

Please sign in to comment.