Skip to content
This repository has been archived by the owner on Nov 4, 2022. It is now read-only.

Commit

Permalink
Merge pull request #15 from apptekstudios/dev
Browse files Browse the repository at this point in the history
Fix crash on Xcode 11.2b
  • Loading branch information
apptekstudios authored Oct 17, 2019
2 parents 2452da6 + aff3781 commit 4316f8f
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 86 deletions.
4 changes: 4 additions & 0 deletions Demo/ASCollectionViewDemo/Views/Compositional/GridView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ struct GridView: View
{ item in
ASRemoteImageView(item.squareThumbURL)
.aspectRatio(1, contentMode: .fill)
.contextMenu {
Text("Test item")
Text("Another item")
}
}
}
}
Expand Down
7 changes: 5 additions & 2 deletions Demo/ASCollectionViewDemo/Views/Feed/PostView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,10 @@ struct PostView: View
{
if !self.captionExpanded
{
self.captionExpanded = true
self.invalidateCellLayout()
withAnimation() {
self.captionExpanded = true
self.invalidateCellLayout()
}
}
}
Text("View all \(post.comments) comments").foregroundColor(Color(.systemGray))
Expand All @@ -103,6 +105,7 @@ struct PostView: View
)
buttonBar
textContent
Spacer()
}
.padding([.top, .bottom])
}
Expand Down
6 changes: 4 additions & 2 deletions Demo/ASCollectionViewDemo/Views/Orthogonal/OrthoView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ struct OrthoView: View
heightDimension: .estimated(34)),
elementKind: UICollectionView.elementKindSectionHeader,
alignment: .top)
header.contentInsets = nestedGroup.contentInsets
header.contentInsets.leading = nestedGroup.contentInsets.leading
header.contentInsets.trailing = nestedGroup.contentInsets.trailing

let section = NSCollectionLayoutSection(group: nestedGroup)
section.boundarySupplementaryItems = [header]
Expand Down Expand Up @@ -110,7 +111,8 @@ struct OrthoView: View
heightDimension: .estimated(34)),
elementKind: UICollectionView.elementKindSectionHeader,
alignment: .top)
header.contentInsets = nestedGroup.contentInsets
header.contentInsets.leading = nestedGroup.contentInsets.leading
header.contentInsets.trailing = nestedGroup.contentInsets.trailing

let section = NSCollectionLayoutSection(group: nestedGroup)
section.boundarySupplementaryItems = [header]
Expand Down
152 changes: 70 additions & 82 deletions Sources/ASCollectionView/ASCollectionView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -267,89 +267,77 @@ public struct ASCollectionView<SectionID: Hashable>: UIViewControllerRepresentab
private var prefetchSubscription: AnyCancellable?
private var currentlyPrefetching: Set<IndexPath> = []

func setupPrefetching()
{
prefetchSubscription = queuePrefetch
.collect(.byTime(DispatchQueue.main, 0.1)) // Wanted to use .throttle(for: 0.1, scheduler: DispatchQueue(label: "TEST"), latest: true) -> THIS CRASHES?? BUG??
.compactMap
{ _ in
self.collectionViewController?.collectionView.indexPathsForVisibleItems
}
.receive(on: DispatchQueue.global(qos: .background))
.map
{ visibleIndexPaths -> [Int: [IndexPath]] in
let visibleIndexPathsBySection = Dictionary(grouping: visibleIndexPaths) { $0.section }.compactMapValues
{ (indexPaths) -> (section: Int, first: Int, last: Int)? in
guard let first = indexPaths.min(), let last = indexPaths.max() else { return nil }
return (section: first.section, first: first.item, last: last.item)
}
var toPrefetch: [Int: [IndexPath]] = visibleIndexPathsBySection.mapValues
{ item in
let sectionIndexPaths = self.parent.sections[item.section].getIndexPaths(withSectionIndex: item.section)
let nextItemsInSection = sectionIndexPaths.suffix(from: item.last).dropFirst().prefix(5)
let previousItemsInSection = sectionIndexPaths.prefix(upTo: item.first).suffix(5)
return Array(nextItemsInSection) + Array(previousItemsInSection)
}
// CHECK IF THERES AN EARLIER SECTION TO PRELOAD
if
let firstSection = toPrefetch.keys.min(), // FIND THE EARLIEST VISIBLE SECTION
(firstSection - 1) >= self.parent.sections.startIndex, // CHECK THERE IS A SECTION BEFORE THIS
let firstIndex = visibleIndexPathsBySection[firstSection]?.first, firstIndex < 5 // CHECK HOW CLOSE TO THIS SECTION WE ARE
{
let precedingSection = firstSection - 1
toPrefetch[precedingSection] = self.parent.sections[precedingSection].getIndexPaths(withSectionIndex: precedingSection).suffix(5)
}
// CHECK IF THERES A LATER SECTION TO PRELOAD
if
let lastSection = toPrefetch.keys.max(), // FIND THE EARLIEST VISIBLE SECTION
(lastSection + 1) < self.parent.sections.endIndex, // CHECK THERE IS A SECTION BEFORE THIS
let lastIndex = visibleIndexPathsBySection[lastSection]?.last,
let lastSectionEndIndex = self.parent.sections[lastSection].getIndexPaths(withSectionIndex: lastSection).last?.item,
(lastSectionEndIndex - lastIndex) < 5 // CHECK HOW CLOSE TO THIS SECTION WE ARE
{
let nextSection = lastSection + 1
toPrefetch[nextSection] = Array(self.parent.sections[nextSection].getIndexPaths(withSectionIndex: nextSection).prefix(5))
}
return toPrefetch
}
.sink
{ prefetch in
prefetch.forEach
{ sectionIndex, toPrefetch in
if !toPrefetch.isEmpty
{
self.parent.sections[sectionIndex].prefetch(toPrefetch)
}
let toCancel = Array(self.currentlyPrefetching.filter { $0.section == sectionIndex }.subtracting(toPrefetch))
if !toCancel.isEmpty
{
self.parent.sections[sectionIndex].cancelPrefetch(toCancel)
}
}

self.currentlyPrefetching = Set(prefetch.flatMap { $0.value })
}
}

/*
//DISABLED AS PREFETCH API WAS NOT WORKING FOR COMPOSITIONAL LAYOUT
public func collectionView(_ collectionView: UICollectionView, prefetchItemsAt indexPaths: [IndexPath]) {
print("PREFETCH \(indexPaths)")
/* let itemIDsToPrefetchBySection: [Int: [ASCollectionViewItemUniqueID]] = indexPaths.reduce(into: [:]) { (result, indexPath) in
guard let itemID = dataSource?.itemIdentifier(for: indexPath) else { return }
if result[indexPath.section] == nil {
result[indexPath.section] = [itemID]
} else {
result[indexPath.section]?.append(itemID)
}
}
itemIDsToPrefetchBySection.forEach {
parent.sections[$0.key].onCellEvent($0.value)
} */
}
public func collectionView(_ collectionView: UICollectionView, cancelPrefetchingForItemsAt indexPaths: [IndexPath]) {
print("CANCEL PREFETCH \(indexPaths)")
}*/
//REPLACED WITH CUSTOM PREFETCH SOLUTION AS PREFETCH API WAS NOT WORKING FOR COMPOSITIONAL LAYOUT
public func collectionView(_ collectionView: UICollectionView, prefetchItemsAt indexPaths: [IndexPath])
public func collectionView(_ collectionView: UICollectionView, cancelPrefetchingForItemsAt indexPaths: [IndexPath])
*/
}
}

extension ASCollectionView.Coordinator {
func setupPrefetching()
{
prefetchSubscription = queuePrefetch
.collect(.byTime(DispatchQueue.main, 0.1)) // Wanted to use .throttle(for: 0.1, scheduler: DispatchQueue(label: "TEST"), latest: true) -> THIS CRASHES?? BUG??
.compactMap
{ _ in
self.collectionViewController?.collectionView.indexPathsForVisibleItems
}
.receive(on: DispatchQueue.global(qos: .background))
.map
{ visibleIndexPaths -> [Int: [IndexPath]] in
let visibleIndexPathsBySection = Dictionary(grouping: visibleIndexPaths) { $0.section }.compactMapValues
{ (indexPaths) -> (section: Int, first: Int, last: Int)? in
guard let first = indexPaths.min(), let last = indexPaths.max() else { return nil }
return (section: first.section, first: first.item, last: last.item)
}
var toPrefetch: [Int: [IndexPath]] = visibleIndexPathsBySection.mapValues
{ item in
let sectionIndexPaths = self.parent.sections[item.section].getIndexPaths(withSectionIndex: item.section)
let nextItemsInSection = sectionIndexPaths.suffix(from: item.last).dropFirst().prefix(5)
let previousItemsInSection = sectionIndexPaths.prefix(upTo: item.first).suffix(5)
return Array(nextItemsInSection) + Array(previousItemsInSection)
}
// CHECK IF THERES AN EARLIER SECTION TO PRELOAD
if
let firstSection = toPrefetch.keys.min(), // FIND THE EARLIEST VISIBLE SECTION
(firstSection - 1) >= self.parent.sections.startIndex, // CHECK THERE IS A SECTION BEFORE THIS
let firstIndex = visibleIndexPathsBySection[firstSection]?.first, firstIndex < 5 // CHECK HOW CLOSE TO THIS SECTION WE ARE
{
let precedingSection = firstSection - 1
toPrefetch[precedingSection] = self.parent.sections[precedingSection].getIndexPaths(withSectionIndex: precedingSection).suffix(5)
}
// CHECK IF THERES A LATER SECTION TO PRELOAD
if
let lastSection = toPrefetch.keys.max(), // FIND THE EARLIEST VISIBLE SECTION
(lastSection + 1) < self.parent.sections.endIndex, // CHECK THERE IS A SECTION BEFORE THIS
let lastIndex = visibleIndexPathsBySection[lastSection]?.last,
let lastSectionEndIndex = self.parent.sections[lastSection].getIndexPaths(withSectionIndex: lastSection).last?.item,
(lastSectionEndIndex - lastIndex) < 5 // CHECK HOW CLOSE TO THIS SECTION WE ARE
{
let nextSection = lastSection + 1
toPrefetch[nextSection] = Array(self.parent.sections[nextSection].getIndexPaths(withSectionIndex: nextSection).prefix(5))
}
return toPrefetch
}
.sink
{ prefetch in
prefetch.forEach
{ sectionIndex, toPrefetch in
if !toPrefetch.isEmpty
{
self.parent.sections[sectionIndex].prefetch(toPrefetch)
}
let toCancel = Array(self.currentlyPrefetching.filter { $0.section == sectionIndex }.subtracting(toPrefetch))
if !toCancel.isEmpty
{
self.parent.sections[sectionIndex].cancelPrefetch(toCancel)
}
}

self.currentlyPrefetching = Set(prefetch.flatMap { $0.value })
}
}
}

0 comments on commit 4316f8f

Please sign in to comment.