Updates remaining UICollectionView/UITableView logic to use RSTCellContentDataSource

This commit is contained in:
Riley Testut 2017-04-04 18:29:40 -07:00
parent 25eb70c5a6
commit 6b6be904b0
10 changed files with 118 additions and 257 deletions

View File

@ -39,7 +39,7 @@ class GamesDatabaseBrowserViewController: UITableViewController
self.dataSource = RSTArrayTableViewDataSource<GameMetadata>(items: [])
let placeholderView = RSTBackgroundView()
let placeholderView = RSTPlaceholderView()
placeholderView.textLabel.textColor = UIColor.lightText
placeholderView.detailTextLabel.textColor = UIColor.lightText
@ -140,7 +140,7 @@ extension GamesDatabaseBrowserViewController
func updatePlaceholderView()
{
guard let placeholderView = self.dataSource.placeholderView as? RSTBackgroundView else { return }
guard let placeholderView = self.dataSource.placeholderView as? RSTPlaceholderView else { return }
if self.dataSource.searchController.searchBar.text == ""
{

View File

@ -86,7 +86,7 @@ class GameViewController: DeltaCore.GameViewController
fileprivate var sustainButtonsContentView: UIView!
fileprivate var sustainButtonsBlurView: UIVisualEffectView!
fileprivate var sustainButtonsBackgroundView: RSTBackgroundView!
fileprivate var sustainButtonsBackgroundView: RSTPlaceholderView!
required init()
{
@ -171,7 +171,7 @@ extension GameViewController
vibrancyView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
self.sustainButtonsBlurView.contentView.addSubview(vibrancyView)
self.sustainButtonsBackgroundView = RSTBackgroundView(frame: CGRect(x: 0, y: 0, width: vibrancyView.contentView.bounds.width, height: vibrancyView.contentView.bounds.height))
self.sustainButtonsBackgroundView = RSTPlaceholderView(frame: CGRect(x: 0, y: 0, width: vibrancyView.contentView.bounds.width, height: vibrancyView.contentView.bounds.height))
self.sustainButtonsBackgroundView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
self.sustainButtonsBackgroundView.textLabel.text = NSLocalizedString("Select Buttons to Sustain", comment: "")
self.sustainButtonsBackgroundView.textLabel.numberOfLines = 1

View File

@ -44,7 +44,7 @@ class GameCollectionViewController: UICollectionViewController
fileprivate var activeSaveState: SaveStateProtocol?
fileprivate var dataSource: RSTFetchedResultsCollectionViewDataSource<Game>!
fileprivate let dataSource = RSTFetchedResultsCollectionViewDataSource<Game>(fetchedResultsController: NSFetchedResultsController())
fileprivate let prototypeCell = GridCollectionViewCell()
fileprivate var _performing3DTouchTransition = false
@ -61,6 +61,10 @@ extension GameCollectionViewController
{
super.viewDidLoad()
self.dataSource.cellConfigurationHandler = { [unowned self] (cell, item, indexPath) in
self.configure(cell as! GridCollectionViewCell, for: indexPath)
}
self.collectionView?.dataSource = self.dataSource
self.collectionView?.delegate = self
@ -74,13 +78,6 @@ extension GameCollectionViewController
self.collectionView?.addGestureRecognizer(longPressGestureRecognizer)
}
override func viewWillAppear(_ animated: Bool)
{
self.dataSource.fetchedResultsController.performFetchIfNeeded()
super.viewWillAppear(animated)
}
override func viewWillDisappear(_ animated: Bool)
{
super.viewWillDisappear(animated)
@ -148,8 +145,8 @@ extension GameCollectionViewController
let destinationViewController = segue.destination as! GameViewController
let cell = sender as! UICollectionViewCell
let indexPath = self.collectionView?.indexPath(for: cell)
let game = self.dataSource.fetchedResultsController.object(at: indexPath!)
let indexPath = self.collectionView!.indexPath(for: cell)!
let game = self.dataSource.item(at: indexPath)
destinationViewController.game = game
@ -201,21 +198,18 @@ private extension GameCollectionViewController
//MARK: - Update
func updateDataSource()
{
let fetchRequest = Game.rst_fetchRequest() as! NSFetchRequest<Game>
let fetchRequest: NSFetchRequest<Game> = Game.fetchRequest()
fetchRequest.predicate = NSPredicate(format: "ANY %K == %@", #keyPath(Game.gameCollections), self.gameCollection)
fetchRequest.sortDescriptors = [NSSortDescriptor(key: #keyPath(Game.name), ascending: true)]
fetchRequest.returnsObjectsAsFaults = false
self.dataSource = RSTFetchedResultsCollectionViewDataSource(fetchRequest: fetchRequest, managedObjectContext: DatabaseManager.shared.viewContext)
self.dataSource.cellConfigurationHandler = { [unowned self] (cell, item, indexPath) in
self.configure(cell as! GridCollectionViewCell, for: indexPath)
}
self.dataSource.fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: DatabaseManager.shared.viewContext, sectionNameKeyPath: nil, cacheName: nil)
}
//MARK: - Configure Cells
func configure(_ cell: GridCollectionViewCell, for indexPath: IndexPath, ignoreImageOperations: Bool = false)
{
let game = self.dataSource.fetchedResultsController.object(at: indexPath)
let game = self.dataSource.item(at: indexPath)
switch self.theme
{
@ -409,7 +403,7 @@ private extension GameCollectionViewController
guard let indexPath = self.collectionView?.indexPathForItem(at: gestureRecognizer.location(in: self.collectionView)) else { return }
let game = self.dataSource.fetchedResultsController.object(at: indexPath)
let game = self.dataSource.item(at: indexPath)
let actions = self.actions(for: game)
let alertController = UIAlertController(actions: actions)
@ -433,7 +427,7 @@ extension GameCollectionViewController: UIViewControllerPreviewingDelegate
previewingContext.sourceRect = layoutAttributes.frame
let game = self.dataSource.fetchedResultsController.object(at: indexPath)
let game = self.dataSource.item(at: indexPath)
let gameViewController = PreviewGameViewController()
gameViewController.game = game
@ -508,7 +502,7 @@ extension GameCollectionViewController
guard self.gameCollection.identifier != GameType.unknown.rawValue else { return }
let cell = collectionView.cellForItem(at: indexPath)
let game = self.dataSource.fetchedResultsController.object(at: indexPath)
let game = self.dataSource.item(at: indexPath)
if game.fileURL == self.activeEmulatorCore?.game.fileURL
{

View File

@ -35,7 +35,7 @@ class GamesViewController: UIViewController
}
fileprivate var pageViewController: UIPageViewController!
fileprivate var backgroundView: RSTBackgroundView!
fileprivate var placeholderView: RSTPlaceholderView!
fileprivate var pageControl: UIPageControl!
fileprivate let fetchedResultsController: NSFetchedResultsController<NSFetchRequestResult>
@ -67,11 +67,11 @@ extension GamesViewController
{
super.viewDidLoad()
self.backgroundView = RSTBackgroundView(frame: self.view.bounds)
self.backgroundView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
self.backgroundView.textLabel.text = NSLocalizedString("No Games", comment: "")
self.backgroundView.detailTextLabel.text = NSLocalizedString("You can import games by pressing the + button in the top right.", comment: "")
self.view.insertSubview(self.backgroundView, at: 0)
self.placeholderView = RSTPlaceholderView(frame: self.view.bounds)
self.placeholderView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
self.placeholderView.textLabel.text = NSLocalizedString("No Games", comment: "")
self.placeholderView.detailTextLabel.text = NSLocalizedString("You can import games by pressing the + button in the top right.", comment: "")
self.view.insertSubview(self.placeholderView, at: 0)
self.pageControl = UIPageControl()
self.pageControl.translatesAutoresizingMaskIntoConstraints = false
@ -237,7 +237,7 @@ private extension GamesViewController
if let viewController = self.viewControllerForIndex(index)
{
self.pageViewController.view.setHidden(false, animated: animated)
self.backgroundView.setHidden(true, animated: animated)
self.placeholderView.setHidden(true, animated: animated)
self.pageViewController.setViewControllers([viewController], direction: .forward, animated: false, completion: nil)
@ -255,7 +255,7 @@ private extension GamesViewController
self.title = NSLocalizedString("Games", comment: "")
self.pageViewController.view.setHidden(true, animated: animated)
self.backgroundView.setHidden(false, animated: animated)
self.placeholderView.setHidden(false, animated: animated)
}
}
}

View File

@ -23,15 +23,13 @@ class CheatsViewController: UITableViewController
{
var game: Game! {
didSet {
self.updateFetchedResultsController()
self.updateDataSource()
}
}
weak var delegate: CheatsViewControllerDelegate?
fileprivate var backgroundView: RSTBackgroundView!
fileprivate var fetchedResultsController: NSFetchedResultsController<NSFetchRequestResult>!
fileprivate let dataSource = RSTFetchedResultsTableViewDataSource<Cheat>(fetchedResultsController: NSFetchedResultsController())
}
extension CheatsViewController
@ -43,33 +41,27 @@ extension CheatsViewController
self.title = NSLocalizedString("Cheats", comment: "")
let vibrancyEffect = UIVibrancyEffect(blurEffect: UIBlurEffect(style: .dark))
let vibrancyView = UIVisualEffectView(effect: vibrancyEffect)
vibrancyView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
self.tableView.backgroundView = vibrancyView
self.backgroundView = RSTBackgroundView(frame: CGRect(x: 0, y: 0, width: vibrancyView.bounds.width, height: vibrancyView.bounds.height))
self.backgroundView.isHidden = false
self.backgroundView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
self.backgroundView.textLabel.text = NSLocalizedString("No Cheats", comment: "")
self.backgroundView.textLabel.textColor = UIColor.white
self.backgroundView.detailTextLabel.text = NSLocalizedString("You can add a new cheat by pressing the + button in the top right.", comment: "")
self.backgroundView.detailTextLabel.textColor = UIColor.white
vibrancyView.contentView.addSubview(self.backgroundView)
let placeholderView = RSTPlaceholderView(frame: CGRect(x: 0, y: 0, width: vibrancyView.bounds.width, height: vibrancyView.bounds.height))
placeholderView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
placeholderView.textLabel.text = NSLocalizedString("No Cheats", comment: "")
placeholderView.textLabel.textColor = UIColor.white
placeholderView.detailTextLabel.text = NSLocalizedString("You can add a new cheat by pressing the + button in the top right.", comment: "")
placeholderView.detailTextLabel.textColor = UIColor.white
vibrancyView.contentView.addSubview(placeholderView)
self.dataSource.placeholderView = vibrancyView
self.dataSource.rowAnimation = .automatic
self.dataSource.cellConfigurationHandler = { [unowned self] (cell, item, indexPath) in
self.configure(cell, for: indexPath)
}
self.tableView.dataSource = self.dataSource
self.tableView.separatorEffect = vibrancyEffect
self.registerForPreviewing(with: self, sourceView: self.tableView)
}
override func viewWillAppear(_ animated: Bool)
{
self.fetchedResultsController.performFetchIfNeeded()
self.updateBackgroundView()
super.viewWillAppear(animated)
}
override func didReceiveMemoryWarning()
{
@ -90,29 +82,14 @@ private extension CheatsViewController
//MARK: - Update -
private extension CheatsViewController
{
func updateFetchedResultsController()
func updateDataSource()
{
let fetchRequest = Cheat.rst_fetchRequest()
let fetchRequest: NSFetchRequest<Cheat> = Cheat.fetchRequest()
fetchRequest.returnsObjectsAsFaults = false
fetchRequest.predicate = NSPredicate(format: "%K == %@", #keyPath(Cheat.game), self.game)
fetchRequest.sortDescriptors = [NSSortDescriptor(key: #keyPath(Cheat.name), ascending: true)]
self.fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: DatabaseManager.shared.viewContext, sectionNameKeyPath: nil, cacheName: nil)
self.fetchedResultsController.delegate = self
}
func updateBackgroundView()
{
if let fetchedObjects = self.fetchedResultsController.fetchedObjects, fetchedObjects.count > 0
{
self.tableView.separatorStyle = .singleLine
self.backgroundView.isHidden = true
}
else
{
self.tableView.separatorStyle = .none
self.backgroundView.isHidden = false
}
self.dataSource.fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: DatabaseManager.shared.viewContext, sectionNameKeyPath: nil, cacheName: nil)
}
}
@ -142,9 +119,9 @@ private extension CheatsViewController
/// Convenience
private extension CheatsViewController
{
func configure(_ cell: UITableViewCell, forIndexPath indexPath: IndexPath)
func configure(_ cell: UITableViewCell, for indexPath: IndexPath)
{
let cheat = self.fetchedResultsController.object(at: indexPath) as! Cheat
let cheat = self.dataSource.item(at: indexPath)
cell.textLabel?.text = cheat.name
cell.textLabel?.font = UIFont.boldSystemFont(ofSize: cell.textLabel!.font.pointSize)
cell.textLabel?.textColor = UIColor.white
@ -162,35 +139,11 @@ private extension CheatsViewController
}
}
extension CheatsViewController
{
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int
{
let numberOfSections = self.fetchedResultsController.sections!.count
return numberOfSections
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
let section = self.fetchedResultsController.sections![section]
return section.numberOfObjects
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCell(withIdentifier: RSTCellContentGenericCellIdentifier, for: indexPath)
self.configure(cell, forIndexPath: indexPath)
return cell
}
}
extension CheatsViewController
{
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
{
let cheat = self.fetchedResultsController.object(at: indexPath) as! Cheat
let cheat = self.dataSource.item(at: indexPath)
let backgroundContext = DatabaseManager.shared.newBackgroundContext()
backgroundContext.performAndWait {
@ -214,7 +167,7 @@ extension CheatsViewController
override func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]?
{
let cheat = self.fetchedResultsController.object(at: indexPath) as! Cheat
let cheat = self.dataSource.item(at: indexPath)
let deleteAction = UITableViewRowAction(style: .destructive, title: NSLocalizedString("Delete", comment: "")) { (action, indexPath) in
self.deleteCheat(cheat)
@ -244,7 +197,7 @@ extension CheatsViewController: UIViewControllerPreviewingDelegate
let frame = self.tableView.rectForRow(at: indexPath)
previewingContext.sourceRect = frame
let cheat = self.fetchedResultsController.object(at: indexPath) as! Cheat
let cheat = self.dataSource.item(at: indexPath)
let editCheatViewController = self.makeEditCheatViewController(cheat: cheat)
editCheatViewController.isPreviewing = true
@ -284,13 +237,3 @@ extension CheatsViewController: EditCheatViewControllerDelegate
self.delegate?.cheatsViewController(self, deactivateCheat: cheat)
}
}
//MARK: - <NSFetchedResultsControllerDelegate> -
extension CheatsViewController: NSFetchedResultsControllerDelegate
{
func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>)
{
self.tableView.reloadData()
self.updateBackgroundView()
}
}

View File

@ -8,7 +8,8 @@
import UIKit
struct PauseItem: Equatable
// Must be class for use with Objective-C generics :(
class PauseItem: Equatable
{
var image: UIImage
var text: String

View File

@ -21,7 +21,7 @@ class PauseMenuViewController: UICollectionViewController
fatalError("PauseViewController only supports up to 8 items (for my sanity when laying out on a landscape iPhone 4s")
}
self.collectionView?.reloadData()
self.dataSource.items = self.items
}
}
@ -30,6 +30,8 @@ class PauseMenuViewController: UICollectionViewController
get { return self.collectionView?.contentSize ?? CGSize.zero }
}
fileprivate let dataSource = RSTArrayCollectionViewDataSource<PauseItem>(items: [])
fileprivate var prototypeCell = GridCollectionViewCell()
fileprivate var previousIndexPath: IndexPath? = nil
}
@ -39,6 +41,11 @@ extension PauseMenuViewController
override func viewDidLoad()
{
super.viewDidLoad()
self.dataSource.cellConfigurationHandler = { [unowned self] (cell, item, indexPath) in
self.configure(cell as! GridCollectionViewCell, for: indexPath)
}
self.collectionView?.dataSource = self.dataSource
let collectionViewLayout = self.collectionViewLayout as! GridCollectionViewLayout
collectionViewLayout.itemWidth = 90
@ -63,7 +70,7 @@ extension PauseMenuViewController
private extension PauseMenuViewController
{
func configureCollectionViewCell(_ cell: GridCollectionViewCell, forIndexPath indexPath: IndexPath)
func configure(_ cell: GridCollectionViewCell, for indexPath: IndexPath)
{
let pauseItem = self.items[(indexPath as NSIndexPath).item]
@ -95,27 +102,11 @@ private extension PauseMenuViewController
func toggleSelectedStateForPauseItemAtIndexPath(_ indexPath: IndexPath)
{
var pauseItem = self.items[(indexPath as NSIndexPath).item]
let pauseItem = self.items[indexPath.item]
pauseItem.selected = !pauseItem.selected
self.items[(indexPath as NSIndexPath).item] = pauseItem
let cell = self.collectionView!.cellForItem(at: indexPath) as! GridCollectionViewCell
self.configureCollectionViewCell(cell, forIndexPath: indexPath)
}
}
extension PauseMenuViewController
{
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
{
return self.items.count
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
{
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: RSTCellContentGenericCellIdentifier, for: indexPath) as! GridCollectionViewCell
self.configureCollectionViewCell(cell, forIndexPath: indexPath)
return cell
self.configure(cell, for: indexPath)
}
}
@ -123,7 +114,7 @@ extension PauseMenuViewController: UICollectionViewDelegateFlowLayout
{
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize
{
self.configureCollectionViewCell(self.prototypeCell, forIndexPath: indexPath)
self.configure(self.prototypeCell, for: indexPath)
let size = self.prototypeCell.contentView.systemLayoutSizeFitting(UILayoutFittingCompressedSize)
return size
@ -148,7 +139,7 @@ extension PauseMenuViewController
self.toggleSelectedStateForPauseItemAtIndexPath(indexPath)
let pauseItem = self.items[(indexPath as NSIndexPath).item]
let pauseItem = self.items[indexPath.item]
pauseItem.action(pauseItem)
}
}

View File

@ -38,7 +38,7 @@ class SaveStatesViewController: UICollectionViewController
{
var game: Game! {
didSet {
self.updateFetchedResultsController()
self.updateDataSource()
}
}
@ -59,13 +59,13 @@ class SaveStatesViewController: UICollectionViewController
}
fileprivate var vibrancyView: UIVisualEffectView!
fileprivate var backgroundView: RSTBackgroundView!
fileprivate var placeholderView: RSTPlaceholderView!
fileprivate var prototypeCell = GridCollectionViewCell()
fileprivate var prototypeCellWidthConstraint: NSLayoutConstraint!
fileprivate var prototypeHeader = SaveStatesCollectionHeaderView()
fileprivate var fetchedResultsController: NSFetchedResultsController<NSFetchRequestResult>!
fileprivate let dataSource = RSTFetchedResultsCollectionViewDataSource<SaveState>(fetchedResultsController: NSFetchedResultsController())
fileprivate let imageOperationQueue = RSTOperationQueue()
fileprivate let imageCache = NSCache<NSURL, UIImage>()
@ -91,17 +91,20 @@ extension SaveStatesViewController
super.viewDidLoad()
self.vibrancyView = UIVisualEffectView(effect: nil)
self.vibrancyView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
self.vibrancyView.frame = CGRect(x: 0, y: 0, width: self.view.bounds.width, height: self.view.bounds.height)
self.view.insertSubview(self.vibrancyView, at: 0)
self.backgroundView = RSTBackgroundView(frame: CGRect(x: 0, y: 0, width: vibrancyView.bounds.width, height: vibrancyView.bounds.height))
self.backgroundView.isHidden = true
self.backgroundView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
self.backgroundView.textLabel.text = NSLocalizedString("No Save States", comment: "")
self.backgroundView.textLabel.textColor = UIColor.white
self.backgroundView.detailTextLabel.textColor = UIColor.white
self.vibrancyView.contentView.addSubview(self.backgroundView)
self.placeholderView = RSTPlaceholderView(frame: CGRect(x: 0, y: 0, width: self.vibrancyView.bounds.width, height: self.vibrancyView.bounds.height))
self.placeholderView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
self.placeholderView.textLabel.text = NSLocalizedString("No Save States", comment: "")
self.placeholderView.textLabel.textColor = UIColor.white
self.placeholderView.detailTextLabel.textColor = UIColor.white
self.vibrancyView.contentView.addSubview(self.placeholderView)
self.dataSource.proxy = self
self.dataSource.placeholderView = self.vibrancyView
self.dataSource.cellConfigurationHandler = { [unowned self] (cell, item, indexPath) in
self.configure(cell as! GridCollectionViewCell, for: indexPath)
}
self.collectionView?.dataSource = self.dataSource
let collectionViewLayout = self.collectionViewLayout as! GridCollectionViewLayout
let averageHorizontalInset = (collectionViewLayout.sectionInset.left + collectionViewLayout.sectionInset.right) / 2
@ -115,11 +118,11 @@ extension SaveStatesViewController
{
case .saving:
self.title = NSLocalizedString("Save State", comment: "")
self.backgroundView.detailTextLabel.text = NSLocalizedString("You can create a new save state by pressing the + button in the top right.", comment: "")
placeholderView.detailTextLabel.text = NSLocalizedString("You can create a new save state by pressing the + button in the top right.", comment: "")
case .loading:
self.title = NSLocalizedString("Load State", comment: "")
self.backgroundView.detailTextLabel.text = NSLocalizedString("You can create a new save state by pressing the Save State option in the pause menu.", comment: "")
placeholderView.detailTextLabel.text = NSLocalizedString("You can create a new save state by pressing the Save State option in the pause menu.", comment: "")
self.navigationItem.rightBarButtonItem = nil
}
@ -137,19 +140,9 @@ extension SaveStatesViewController
self.navigationController?.navigationBar.barStyle = .blackTranslucent
self.navigationController?.toolbar.barStyle = .blackTranslucent
self.updateBackgroundView()
self.updateTheme()
}
override func viewWillAppear(_ animated: Bool)
{
self.fetchedResultsController.performFetchIfNeeded()
self.updateBackgroundView()
super.viewWillAppear(animated)
}
override func viewDidDisappear(_ animated: Bool)
{
super.viewDidDisappear(animated)
@ -167,27 +160,14 @@ private extension SaveStatesViewController
{
//MARK: - Update -
func updateFetchedResultsController()
func updateDataSource()
{
let fetchRequest = SaveState.rst_fetchRequest()
let fetchRequest: NSFetchRequest<SaveState> = SaveState.fetchRequest()
fetchRequest.returnsObjectsAsFaults = false
fetchRequest.predicate = NSPredicate(format: "%K == %@", #keyPath(SaveState.game), self.game)
fetchRequest.sortDescriptors = [NSSortDescriptor(key: #keyPath(SaveState.type), ascending: true), NSSortDescriptor(key: #keyPath(SaveState.creationDate), ascending: true)]
self.fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: DatabaseManager.shared.viewContext, sectionNameKeyPath: #keyPath(SaveState.type), cacheName: nil)
self.fetchedResultsController.delegate = self
}
func updateBackgroundView()
{
if let fetchedObjects = self.fetchedResultsController.fetchedObjects, fetchedObjects.count > 0
{
self.backgroundView.isHidden = true
}
else
{
self.backgroundView.isHidden = false
}
self.dataSource.fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: DatabaseManager.shared.viewContext, sectionNameKeyPath: #keyPath(SaveState.type), cacheName: nil)
}
func updateTheme()
@ -199,24 +179,24 @@ private extension SaveStatesViewController
self.vibrancyView.effect = nil
self.backgroundView.textLabel.textColor = UIColor.gray
self.backgroundView.detailTextLabel.textColor = UIColor.gray
self.placeholderView.textLabel.textColor = UIColor.gray
self.placeholderView.detailTextLabel.textColor = UIColor.gray
case .translucent:
self.view.backgroundColor = nil
self.vibrancyView.effect = UIVibrancyEffect(blurEffect: UIBlurEffect(style: .dark))
self.backgroundView.textLabel.textColor = UIColor.white
self.backgroundView.detailTextLabel.textColor = UIColor.white
self.placeholderView.textLabel.textColor = UIColor.white
self.placeholderView.detailTextLabel.textColor = UIColor.white
}
}
//MARK: - Configure Views -
func configureCollectionViewCell(_ cell: GridCollectionViewCell, forIndexPath indexPath: IndexPath, ignoreExpensiveOperations ignoreOperations: Bool = false)
func configure(_ cell: GridCollectionViewCell, for indexPath: IndexPath, ignoreExpensiveOperations ignoreOperations: Bool = false)
{
let saveState = self.fetchedResultsController.object(at: indexPath) as! SaveState
let saveState = self.dataSource.item(at: indexPath)
cell.imageView.backgroundColor = UIColor.white
cell.imageView.image = UIImage(named: "DeltaPlaceholder")
@ -241,10 +221,12 @@ private extension SaveStatesViewController
if let image = image
{
cell.imageView.backgroundColor = nil
cell.imageView.image = image
cell.isImageViewVibrancyEnabled = false
DispatchQueue.main.async {
cell.imageView.backgroundColor = nil
cell.imageView.image = image
cell.isImageViewVibrancyEnabled = false
}
}
}
@ -268,7 +250,7 @@ private extension SaveStatesViewController
cell.textLabel.text = name
}
func configureCollectionViewHeaderView(_ headerView: SaveStatesCollectionHeaderView, forSection section: Int)
func configure(_ headerView: SaveStatesCollectionHeaderView, forSection section: Int)
{
let section = self.correctedSectionForSectionIndex(section)
@ -299,7 +281,7 @@ private extension SaveStatesViewController
guard let indexPath = self.collectionView?.indexPathForItem(at: gestureRecognizer.location(in: self.collectionView)) else { return }
let saveState = self.fetchedResultsController.object(at: indexPath) as! SaveState
let saveState = self.dataSource.item(at: indexPath)
guard let actions = self.actionsForSaveState(saveState) else { return }
@ -447,7 +429,7 @@ private extension SaveStatesViewController
func correctedSectionForSectionIndex(_ section: Int) -> Section
{
let sectionInfo = self.fetchedResultsController.sections![section]
let sectionInfo = self.dataSource.fetchedResultsController.sections![section]
let sectionIndex = Int(sectionInfo.name)!
let section = Section(rawValue: sectionIndex)!
@ -593,7 +575,7 @@ extension SaveStatesViewController: UIViewControllerPreviewingDelegate
previewingContext.sourceRect = layoutAttributes.frame
let saveState = self.fetchedResultsController.object(at: indexPath) as! SaveState
let saveState = self.dataSource.item(at: indexPath)
let actions = self.actionsForSaveState(saveState)?.previewActions ?? []
let previewImage = self.imageCache.object(forKey: saveState.imageFileURL as NSURL) ?? UIImage(contentsOfFile: saveState.imageFileURL.path)
@ -633,29 +615,10 @@ extension SaveStatesViewController: UIViewControllerPreviewingDelegate
//MARK: - <UICollectionViewDataSource> -
extension SaveStatesViewController
{
override func numberOfSections(in collectionView: UICollectionView) -> Int
{
let numberOfSections = self.fetchedResultsController.sections!.count
return numberOfSections
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
{
let section = self.fetchedResultsController.sections![section]
return section.numberOfObjects
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
{
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: RSTCellContentGenericCellIdentifier, for: indexPath) as! GridCollectionViewCell
self.configureCollectionViewCell(cell, forIndexPath: indexPath)
return cell
}
override func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView
{
let headerView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "Header", for: indexPath) as! SaveStatesCollectionHeaderView
self.configureCollectionViewHeaderView(headerView, forSection: (indexPath as NSIndexPath).section)
self.configure(headerView, forSection: indexPath.section)
return headerView
}
}
@ -665,7 +628,7 @@ extension SaveStatesViewController
{
override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath)
{
let saveState = self.fetchedResultsController.object(at: indexPath) as! SaveState
let saveState = self.dataSource.item(at: indexPath)
switch self.mode
{
@ -706,7 +669,7 @@ extension SaveStatesViewController: UICollectionViewDelegateFlowLayout
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize
{
// No need to load images from disk just to determine size, so we pass true for ignoreExpensiveOperations
self.configureCollectionViewCell(self.prototypeCell, forIndexPath: indexPath, ignoreExpensiveOperations: true)
self.configure(self.prototypeCell, for: indexPath, ignoreExpensiveOperations: true)
let size = self.prototypeCell.contentView.systemLayoutSizeFitting(UILayoutFittingCompressedSize)
return size
@ -714,19 +677,9 @@ extension SaveStatesViewController: UICollectionViewDelegateFlowLayout
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize
{
self.configureCollectionViewHeaderView(self.prototypeHeader, forSection: section)
self.configure(self.prototypeHeader, forSection: section)
let size = self.prototypeHeader.systemLayoutSizeFitting(UILayoutFittingCompressedSize)
return size
}
}
//MARK: - <NSFetchedResultsControllerDelegate> -
extension SaveStatesViewController: NSFetchedResultsControllerDelegate
{
func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>)
{
self.collectionView?.reloadData()
self.updateBackgroundView()
}
}

View File

@ -35,7 +35,7 @@ class ControllerSkinsViewController: UITableViewController
}
}
fileprivate var dataSource: RSTFetchedResultsTableViewDataSource<ControllerSkin>!
fileprivate let dataSource = RSTFetchedResultsTableViewDataSource<ControllerSkin>(fetchedResultsController: NSFetchedResultsController())
fileprivate let imageOperationQueue = RSTOperationQueue()
@ -47,13 +47,12 @@ extension ControllerSkinsViewController
override func viewDidLoad()
{
super.viewDidLoad()
}
override func viewWillAppear(_ animated: Bool)
{
self.dataSource.fetchedResultsController.performFetchIfNeeded()
super.viewWillAppear(animated)
self.dataSource.proxy = self
self.dataSource.cellConfigurationHandler = { [unowned self] (cell, item, indexPath) in
self.configure(cell as! ControllerSkinTableViewCell, for: indexPath)
}
self.tableView.dataSource = self.dataSource
}
override func didReceiveMemoryWarning()
@ -76,18 +75,13 @@ private extension ControllerSkinsViewController
fetchRequest.predicate = NSPredicate(format: "%K == %@ AND (%K & %d) == %d", #keyPath(ControllerSkin.gameType), gameType.rawValue, #keyPath(ControllerSkin.supportedConfigurations), configuration.rawValue, configuration.rawValue)
fetchRequest.sortDescriptors = [NSSortDescriptor(key: #keyPath(ControllerSkin.isStandard), ascending: false), NSSortDescriptor(key: #keyPath(ControllerSkin.name), ascending: true)]
let fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: DatabaseManager.shared.viewContext, sectionNameKeyPath: #keyPath(ControllerSkin.name), cacheName: nil)
self.dataSource = RSTFetchedResultsTableViewDataSource(fetchedResultsController: fetchedResultsController)
self.dataSource.cellConfigurationHandler = { [unowned self] (cell, item, indexPath) in
self.configure(cell as! ControllerSkinTableViewCell, for: indexPath)
}
self.dataSource.fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: DatabaseManager.shared.viewContext, sectionNameKeyPath: #keyPath(ControllerSkin.name), cacheName: nil)
}
//MARK: - Configure Cells
func configure(_ cell: ControllerSkinTableViewCell, for indexPath: IndexPath)
{
let controllerSkin = self.dataSource.fetchedResultsController.object(at: indexPath)
let controllerSkin = self.dataSource.item(at: indexPath)
cell.controllerSkinImageView.image = nil
cell.activityIndicatorView.startAnimating()
@ -126,24 +120,9 @@ private extension ControllerSkinsViewController
extension ControllerSkinsViewController
{
override func numberOfSections(in tableView: UITableView) -> Int
{
return self.dataSource.numberOfSections(in: tableView)
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return self.dataSource.tableView(tableView, numberOfRowsInSection: section)
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
return self.dataSource.tableView(tableView, cellForRowAt: indexPath)
}
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String?
{
let controllerSkin = self.dataSource.fetchedResultsController.object(at: IndexPath(row: 0, section: section))
let controllerSkin = self.dataSource.item(at: IndexPath(row: 0, section: section))
return controllerSkin.name
}
}
@ -154,7 +133,7 @@ extension ControllerSkinsViewController: UITableViewDataSourcePrefetching
{
for indexPath in indexPaths
{
let controllerSkin = self.dataSource.fetchedResultsController.object(at: indexPath)
let controllerSkin = self.dataSource.item(at: indexPath)
let size = UIScreen.main.defaultControllerSkinSize
@ -179,7 +158,7 @@ extension ControllerSkinsViewController
{
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
{
let controllerSkin = self.dataSource.fetchedResultsController.object(at: indexPath)
let controllerSkin = self.dataSource.item(at: indexPath)
Settings.setPreferredControllerSkin(controllerSkin, for: self.gameType, traits: self.traits)
_ = self.navigationController?.popViewController(animated: true)
@ -187,7 +166,7 @@ extension ControllerSkinsViewController
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
{
let controllerSkin = self.dataSource.fetchedResultsController.object(at: indexPath)
let controllerSkin = self.dataSource.item(at: indexPath)
guard let size = controllerSkin.aspectRatio(for: self.traits) else { return 150 }

2
External/Roxas vendored

@ -1 +1 @@
Subproject commit 0057bde6337f90b5747eec1baf94a1360e78c23e
Subproject commit 9143d01afa25f07da8f1cdb5390b49f4efb1a75f