This commit is contained in:
Chris Li 2017-01-23 14:08:40 -05:00
parent bc072808c3
commit 0653869ec6
5 changed files with 79 additions and 62 deletions

View File

@ -10,12 +10,9 @@ import UIKit
import CoreData import CoreData
import DZNEmptyDataSet import DZNEmptyDataSet
class BookmarkCollectionController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout, NSFetchedResultsControllerDelegate { class BookmarkCollectionController: CoreDataCollectionBaseController, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {
@IBOutlet weak var collectionView: UICollectionView!
private(set) var itemWidth: CGFloat = 0.0 private(set) var itemWidth: CGFloat = 0.0
private(set) var shouldReloadCollectionView = false
var book: Book? { var book: Book? {
didSet { didSet {
title = book?.title ?? "All" title = book?.title ?? "All"
@ -168,7 +165,6 @@ class BookmarkCollectionController: UIViewController, UICollectionViewDataSource
// MARK: - NSFetchedResultsController // MARK: - NSFetchedResultsController
private var closures = [() -> Void]()
let managedObjectContext = AppDelegate.persistentContainer.viewContext let managedObjectContext = AppDelegate.persistentContainer.viewContext
lazy var fetchedResultController: NSFetchedResultsController<Article> = { lazy var fetchedResultController: NSFetchedResultsController<Article> = {
let fetchRequest = Article.fetchRequest() let fetchRequest = Article.fetchRequest()
@ -182,58 +178,6 @@ class BookmarkCollectionController: UIViewController, UICollectionViewDataSource
try? controller.performFetch() try? controller.performFetch()
return controller as! NSFetchedResultsController<Article> return controller as! NSFetchedResultsController<Article>
}() }()
func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {
switch type {
case .insert:
guard collectionView.numberOfSections > 0,
let newIndexPath = newIndexPath,
collectionView.numberOfItems(inSection: newIndexPath.section) > 0 else {
shouldReloadCollectionView = true
break
}
closures.append({ [weak self] in self?.collectionView.insertItems(at: [newIndexPath]) })
case .delete:
guard let indexPath = indexPath else {break}
closures.append({ [weak self] in self?.collectionView.deleteItems(at: [indexPath]) })
case .move:
guard let indexPath = indexPath, let newIndexPath = newIndexPath else {break}
closures.append({ [weak self] in self?.collectionView.moveItem(at: indexPath, to: newIndexPath) })
case .update:
guard let indexPath = indexPath, collectionView.numberOfItems(inSection: indexPath.section) != 1 else {
self.shouldReloadCollectionView = true
break
}
closures.append({ [weak self] in self?.collectionView.reloadItems(at: [indexPath]) })
}
}
func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange sectionInfo: NSFetchedResultsSectionInfo, atSectionIndex sectionIndex: Int, for type: NSFetchedResultsChangeType) {
switch type {
case .insert:
closures.append({ [weak self] in self?.collectionView.insertSections(IndexSet(integer: sectionIndex)) })
case .delete:
closures.append({ [weak self] in self?.collectionView.deleteSections(IndexSet(integer: sectionIndex)) })
case .move:
break
case .update:
closures.append({ [weak self] in self?.collectionView.reloadSections(IndexSet(integer: sectionIndex)) })
}
}
func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
OperationQueue.main.addOperation({
if self.shouldReloadCollectionView {
self.collectionView.reloadData()
} else {
self.collectionView.performBatchUpdates({
self.closures.forEach({ $0() })
}, completion: { (completed) in
self.closures.removeAll()
})
}
})
}
} }
extension BookmarkCollectionController: DZNEmptyDataSetSource, DZNEmptyDataSetDelegate { extension BookmarkCollectionController: DZNEmptyDataSetSource, DZNEmptyDataSetDelegate {

View File

@ -7,6 +7,7 @@
// //
import UIKit import UIKit
import CoreData
class LibraryBooksController: UIViewController { class LibraryBooksController: UIViewController {
@ -16,8 +17,5 @@ class LibraryBooksController: UIViewController {
dismiss(animated: true, completion: nil) dismiss(animated: true, completion: nil)
} }
override func viewDidLoad() {
super.viewDidLoad()
}
} }

View File

@ -0,0 +1,70 @@
//
// CoreDataCollectionBaseController.swift
// Kiwix
//
// Created by Chris Li on 1/23/17.
// Copyright © 2017 Chris Li. All rights reserved.
//
import UIKit
import CoreData
class CoreDataCollectionBaseController: UIViewController, NSFetchedResultsControllerDelegate {
@IBOutlet weak var collectionView: UICollectionView!
private(set) var shouldReloadCollectionView = false
private var closures = [() -> Void]()
func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {
switch type {
case .insert:
guard collectionView.numberOfSections > 0,
let newIndexPath = newIndexPath,
collectionView.numberOfItems(inSection: newIndexPath.section) > 0 else {
shouldReloadCollectionView = true
break
}
closures.append({ [weak self] in self?.collectionView.insertItems(at: [newIndexPath]) })
case .delete:
guard let indexPath = indexPath else {break}
closures.append({ [weak self] in self?.collectionView.deleteItems(at: [indexPath]) })
case .move:
guard let indexPath = indexPath, let newIndexPath = newIndexPath else {break}
closures.append({ [weak self] in self?.collectionView.moveItem(at: indexPath, to: newIndexPath) })
case .update:
guard let indexPath = indexPath, collectionView.numberOfItems(inSection: indexPath.section) != 1 else {
self.shouldReloadCollectionView = true
break
}
closures.append({ [weak self] in self?.collectionView.reloadItems(at: [indexPath]) })
}
}
func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange sectionInfo: NSFetchedResultsSectionInfo, atSectionIndex sectionIndex: Int, for type: NSFetchedResultsChangeType) {
switch type {
case .insert:
closures.append({ [weak self] in self?.collectionView.insertSections(IndexSet(integer: sectionIndex)) })
case .delete:
closures.append({ [weak self] in self?.collectionView.deleteSections(IndexSet(integer: sectionIndex)) })
case .move:
break
case .update:
closures.append({ [weak self] in self?.collectionView.reloadSections(IndexSet(integer: sectionIndex)) })
}
}
func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
OperationQueue.main.addOperation({
if self.shouldReloadCollectionView {
self.collectionView.reloadData()
} else {
self.collectionView.performBatchUpdates({
self.closures.forEach({ $0() })
}, completion: { (completed) in
self.closures.removeAll()
})
}
})
}
}

View File

@ -57,6 +57,7 @@
<rect key="frame" x="0.0" y="0.0" width="50" height="50"/> <rect key="frame" x="0.0" y="0.0" width="50" height="50"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
</view> </view>
<color key="backgroundColor" red="1" green="0.50196081400000003" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
</collectionViewCell> </collectionViewCell>
</cells> </cells>
</collectionView> </collectionView>

View File

@ -10,6 +10,7 @@
7356F9FACBB84380CFC8F68F /* Pods_Kiwix_iOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EC884ACBBA260AF741C4C4FE /* Pods_Kiwix_iOS.framework */; }; 7356F9FACBB84380CFC8F68F /* Pods_Kiwix_iOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EC884ACBBA260AF741C4C4FE /* Pods_Kiwix_iOS.framework */; };
9705D5941E368189005292AC /* Library.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9705D5931E368189005292AC /* Library.storyboard */; }; 9705D5941E368189005292AC /* Library.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9705D5931E368189005292AC /* Library.storyboard */; };
9705D5961E368712005292AC /* LibraryBooksController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9705D5951E368712005292AC /* LibraryBooksController.swift */; }; 9705D5961E368712005292AC /* LibraryBooksController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9705D5951E368712005292AC /* LibraryBooksController.swift */; };
9705D5981E368933005292AC /* CoreDataCollectionBaseController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9705D5971E368933005292AC /* CoreDataCollectionBaseController.swift */; };
970A2A221DD562CB0078BB7C /* BookOperations.swift in Sources */ = {isa = PBXBuildFile; fileRef = 970A2A211DD562CB0078BB7C /* BookOperations.swift */; }; 970A2A221DD562CB0078BB7C /* BookOperations.swift in Sources */ = {isa = PBXBuildFile; fileRef = 970A2A211DD562CB0078BB7C /* BookOperations.swift */; };
970E7F741D9DB0FC00741290 /* 1.8.xcmappingmodel in Sources */ = {isa = PBXBuildFile; fileRef = 970E7F731D9DB0FC00741290 /* 1.8.xcmappingmodel */; }; 970E7F741D9DB0FC00741290 /* 1.8.xcmappingmodel in Sources */ = {isa = PBXBuildFile; fileRef = 970E7F731D9DB0FC00741290 /* 1.8.xcmappingmodel */; };
970E7F831DA0305000741290 /* WelcomeController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 970E7F7F1DA0305000741290 /* WelcomeController.swift */; }; 970E7F831DA0305000741290 /* WelcomeController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 970E7F7F1DA0305000741290 /* WelcomeController.swift */; };
@ -160,6 +161,7 @@
6DCB0E958A1083CA248C5A12 /* Pods-Kiwix-OSX.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Kiwix-OSX.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Kiwix-OSX/Pods-Kiwix-OSX.debug.xcconfig"; sourceTree = "<group>"; }; 6DCB0E958A1083CA248C5A12 /* Pods-Kiwix-OSX.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Kiwix-OSX.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Kiwix-OSX/Pods-Kiwix-OSX.debug.xcconfig"; sourceTree = "<group>"; };
9705D5931E368189005292AC /* Library.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Library.storyboard; sourceTree = "<group>"; }; 9705D5931E368189005292AC /* Library.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Library.storyboard; sourceTree = "<group>"; };
9705D5951E368712005292AC /* LibraryBooksController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LibraryBooksController.swift; sourceTree = "<group>"; }; 9705D5951E368712005292AC /* LibraryBooksController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LibraryBooksController.swift; sourceTree = "<group>"; };
9705D5971E368933005292AC /* CoreDataCollectionBaseController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoreDataCollectionBaseController.swift; sourceTree = "<group>"; };
970912551D7F452C00BBD5A1 /* 1.8.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = 1.8.xcdatamodel; sourceTree = "<group>"; }; 970912551D7F452C00BBD5A1 /* 1.8.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = 1.8.xcdatamodel; sourceTree = "<group>"; };
970A2A211DD562CB0078BB7C /* BookOperations.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BookOperations.swift; sourceTree = "<group>"; }; 970A2A211DD562CB0078BB7C /* BookOperations.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BookOperations.swift; sourceTree = "<group>"; };
970E7F731D9DB0FC00741290 /* 1.8.xcmappingmodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcmappingmodel; name = 1.8.xcmappingmodel; path = Kiwix/CoreData/Migration/1.8.xcmappingmodel; sourceTree = SOURCE_ROOT; }; 970E7F731D9DB0FC00741290 /* 1.8.xcmappingmodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcmappingmodel; name = 1.8.xcmappingmodel; path = Kiwix/CoreData/Migration/1.8.xcmappingmodel; sourceTree = SOURCE_ROOT; };
@ -609,6 +611,7 @@
children = ( children = (
970E7F7C1DA0305000741290 /* Alerts.swift */, 970E7F7C1DA0305000741290 /* Alerts.swift */,
973A5C911DEA3F5600C7804C /* CoreDataTableBaseController.swift */, 973A5C911DEA3F5600C7804C /* CoreDataTableBaseController.swift */,
9705D5971E368933005292AC /* CoreDataCollectionBaseController.swift */,
970E7F7F1DA0305000741290 /* WelcomeController.swift */, 970E7F7F1DA0305000741290 /* WelcomeController.swift */,
); );
path = Others; path = Others;
@ -1125,6 +1128,7 @@
97A1FD181D6F71CE00A80EE2 /* SearchResult.swift in Sources */, 97A1FD181D6F71CE00A80EE2 /* SearchResult.swift in Sources */,
977AE7F91DD8F22400F1E581 /* SearchBar.swift in Sources */, 977AE7F91DD8F22400F1E581 /* SearchBar.swift in Sources */,
97ED50111DD257D00089E9B6 /* Kiwix.xcdatamodeld in Sources */, 97ED50111DD257D00089E9B6 /* Kiwix.xcdatamodeld in Sources */,
9705D5981E368933005292AC /* CoreDataCollectionBaseController.swift in Sources */,
97A127C91D777CF100FB204D /* RecentSearchController.swift in Sources */, 97A127C91D777CF100FB204D /* RecentSearchController.swift in Sources */,
97599AE21E28193D00BA15EF /* BookmarkCollectionController.swift in Sources */, 97599AE21E28193D00BA15EF /* BookmarkCollectionController.swift in Sources */,
); );