Updates remaining UICollectionView/UITableView logic to use RSTCellContentDataSource
This commit is contained in:
parent
25eb70c5a6
commit
6b6be904b0
@ -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 == ""
|
||||
{
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
{
|
||||
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
2
External/Roxas
vendored
@ -1 +1 @@
|
||||
Subproject commit 0057bde6337f90b5747eec1baf94a1360e78c23e
|
||||
Subproject commit 9143d01afa25f07da8f1cdb5390b49f4efb1a75f
|
||||
Loading…
Reference in New Issue
Block a user