Adds custom transition when launching games + returning to Main Menu

The entire architecture had to change so GameViewController presented GamesViewController, instead of vice versa which was previously the case
This commit is contained in:
Riley Testut 2016-08-09 01:18:42 -05:00
parent 44b36d7ace
commit 26a6a3c1b3
15 changed files with 672 additions and 165 deletions

View File

@ -1,55 +0,0 @@
//
// BoxArtImageView.swift
// Delta
//
// Created by Riley Testut on 10/27/15.
// Copyright © 2015 Riley Testut. All rights reserved.
//
import UIKit
class BoxArtImageView: UIImageView
{
override var image: UIImage? {
didSet
{
if image == nil
{
image = UIImage(named: "BoxArt")
}
}
}
init()
{
super.init(image: nil)
self.initialize()
}
override init(frame: CGRect)
{
super.init(frame: frame)
self.image = nil
self.initialize()
}
required init?(coder aDecoder: NSCoder)
{
super.init(coder: aDecoder)
self.initialize()
}
private func initialize()
{
#if os(tvOS)
self.adjustsImageWhenAncestorFocused = true
#endif
self.contentMode = .scaleAspectFit
}
}

View File

@ -53,16 +53,20 @@
BFB141181BE46934004FBF46 /* GameCollectionViewDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFB141171BE46934004FBF46 /* GameCollectionViewDataSource.swift */; }; BFB141181BE46934004FBF46 /* GameCollectionViewDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFB141171BE46934004FBF46 /* GameCollectionViewDataSource.swift */; };
BFC2731A1BE6152200D22B05 /* GameCollection.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFC273171BE6152200D22B05 /* GameCollection.swift */; }; BFC2731A1BE6152200D22B05 /* GameCollection.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFC273171BE6152200D22B05 /* GameCollection.swift */; };
BFC9B7391CEFCD34008629BB /* CheatsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFC9B7381CEFCD34008629BB /* CheatsViewController.swift */; }; BFC9B7391CEFCD34008629BB /* CheatsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFC9B7381CEFCD34008629BB /* CheatsViewController.swift */; };
BFCEA67E1D56FF640061A534 /* UIViewControllerContextTransitioning+Conveniences.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFCEA67D1D56FF640061A534 /* UIViewControllerContextTransitioning+Conveniences.swift */; };
BFD097211D3A01B8005A44C2 /* SaveStatesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF3540041C5DA70400C1184C /* SaveStatesViewController.swift */; }; BFD097211D3A01B8005A44C2 /* SaveStatesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF3540041C5DA70400C1184C /* SaveStatesViewController.swift */; };
BFDB28451BC9DA7B001D0C83 /* GamePickerController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFDB28441BC9DA7B001D0C83 /* GamePickerController.swift */; }; BFDB28451BC9DA7B001D0C83 /* GamePickerController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFDB28441BC9DA7B001D0C83 /* GamePickerController.swift */; };
BFDE393C1BC0CEDF003F72E8 /* Game.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFDE39391BC0CEDF003F72E8 /* Game.swift */; }; BFDE393C1BC0CEDF003F72E8 /* Game.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFDE39391BC0CEDF003F72E8 /* Game.swift */; };
BFE704F51CEA426E0058BAC8 /* Pods.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 22506DA00971C4300AF90A35 /* Pods.framework */; }; BFE704F51CEA426E0058BAC8 /* Pods.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 22506DA00971C4300AF90A35 /* Pods.framework */; };
BFEC732D1AAECC4A00650035 /* Roxas.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BFEC732C1AAECC4A00650035 /* Roxas.framework */; }; BFEC732D1AAECC4A00650035 /* Roxas.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BFEC732C1AAECC4A00650035 /* Roxas.framework */; };
BFEC732E1AAECC4A00650035 /* Roxas.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = BFEC732C1AAECC4A00650035 /* Roxas.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; BFEC732E1AAECC4A00650035 /* Roxas.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = BFEC732C1AAECC4A00650035 /* Roxas.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
BFF1E5641BE04CAF000E9EF6 /* BoxArtImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF1E5631BE04CAF000E9EF6 /* BoxArtImageView.swift */; };
BFFA71DD1AAC406100EE9DD1 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFFA71DC1AAC406100EE9DD1 /* AppDelegate.swift */; }; BFFA71DD1AAC406100EE9DD1 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFFA71DC1AAC406100EE9DD1 /* AppDelegate.swift */; };
BFFA71E21AAC406100EE9DD1 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = BFFA71E01AAC406100EE9DD1 /* Main.storyboard */; }; BFFA71E21AAC406100EE9DD1 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = BFFA71E01AAC406100EE9DD1 /* Main.storyboard */; };
BFFA71E71AAC406100EE9DD1 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = BFFA71E51AAC406100EE9DD1 /* LaunchScreen.xib */; }; BFFC461E1D59823500AF2CC6 /* GamesPresentationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFFC461B1D59823500AF2CC6 /* GamesPresentationController.swift */; };
BFFC461F1D59823500AF2CC6 /* GamesStoryboardSegue.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFFC461C1D59823500AF2CC6 /* GamesStoryboardSegue.swift */; };
BFFC46201D59823500AF2CC6 /* InitialGamesStoryboardSegue.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFFC461D1D59823500AF2CC6 /* InitialGamesStoryboardSegue.swift */; };
BFFC46231D5984A000AF2CC6 /* LaunchViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFFC46221D5984A000AF2CC6 /* LaunchViewController.swift */; };
BFFC46461D59861000AF2CC6 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = BFFC46441D59861000AF2CC6 /* LaunchScreen.storyboard */; };
BFFC464C1D5998D600AF2CC6 /* CheatTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFFC464B1D5998D600AF2CC6 /* CheatTableViewCell.swift */; }; BFFC464C1D5998D600AF2CC6 /* CheatTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFFC464B1D5998D600AF2CC6 /* CheatTableViewCell.swift */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
@ -137,15 +141,19 @@
BFC134E01AAD82460087AD7B /* SNESDeltaCore.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = SNESDeltaCore.framework; sourceTree = BUILT_PRODUCTS_DIR; }; BFC134E01AAD82460087AD7B /* SNESDeltaCore.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = SNESDeltaCore.framework; sourceTree = BUILT_PRODUCTS_DIR; };
BFC273171BE6152200D22B05 /* GameCollection.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GameCollection.swift; sourceTree = "<group>"; }; BFC273171BE6152200D22B05 /* GameCollection.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GameCollection.swift; sourceTree = "<group>"; };
BFC9B7381CEFCD34008629BB /* CheatsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = CheatsViewController.swift; path = "Pause Menu/Cheats/CheatsViewController.swift"; sourceTree = "<group>"; }; BFC9B7381CEFCD34008629BB /* CheatsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = CheatsViewController.swift; path = "Pause Menu/Cheats/CheatsViewController.swift"; sourceTree = "<group>"; };
BFCEA67D1D56FF640061A534 /* UIViewControllerContextTransitioning+Conveniences.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIViewControllerContextTransitioning+Conveniences.swift"; sourceTree = "<group>"; };
BFDB28441BC9DA7B001D0C83 /* GamePickerController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GamePickerController.swift; sourceTree = "<group>"; }; BFDB28441BC9DA7B001D0C83 /* GamePickerController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GamePickerController.swift; sourceTree = "<group>"; };
BFDE39391BC0CEDF003F72E8 /* Game.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Game.swift; sourceTree = "<group>"; }; BFDE39391BC0CEDF003F72E8 /* Game.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Game.swift; sourceTree = "<group>"; };
BFEC732C1AAECC4A00650035 /* Roxas.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = Roxas.framework; sourceTree = BUILT_PRODUCTS_DIR; }; BFEC732C1AAECC4A00650035 /* Roxas.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = Roxas.framework; sourceTree = BUILT_PRODUCTS_DIR; };
BFF1E5631BE04CAF000E9EF6 /* BoxArtImageView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = BoxArtImageView.swift; path = Components/BoxArtImageView.swift; sourceTree = "<group>"; };
BFFA71D71AAC406100EE9DD1 /* Delta.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Delta.app; sourceTree = BUILT_PRODUCTS_DIR; }; BFFA71D71AAC406100EE9DD1 /* Delta.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Delta.app; sourceTree = BUILT_PRODUCTS_DIR; };
BFFA71DB1AAC406100EE9DD1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; BFFA71DB1AAC406100EE9DD1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
BFFA71DC1AAC406100EE9DD1 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; }; BFFA71DC1AAC406100EE9DD1 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
BFFA71E11AAC406100EE9DD1 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; }; BFFA71E11AAC406100EE9DD1 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
BFFA71E61AAC406100EE9DD1 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = "<group>"; }; BFFC461B1D59823500AF2CC6 /* GamesPresentationController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = GamesPresentationController.swift; path = Segues/GamesPresentationController.swift; sourceTree = "<group>"; };
BFFC461C1D59823500AF2CC6 /* GamesStoryboardSegue.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = GamesStoryboardSegue.swift; path = Segues/GamesStoryboardSegue.swift; sourceTree = "<group>"; };
BFFC461D1D59823500AF2CC6 /* InitialGamesStoryboardSegue.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = InitialGamesStoryboardSegue.swift; path = Segues/InitialGamesStoryboardSegue.swift; sourceTree = "<group>"; };
BFFC46221D5984A000AF2CC6 /* LaunchViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = LaunchViewController.swift; path = Launch/LaunchViewController.swift; sourceTree = "<group>"; };
BFFC46451D59861000AF2CC6 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
BFFC464B1D5998D600AF2CC6 /* CheatTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = CheatTableViewCell.swift; path = "Pause Menu/Cheats/CheatTableViewCell.swift"; sourceTree = "<group>"; }; BFFC464B1D5998D600AF2CC6 /* CheatTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = CheatTableViewCell.swift; path = "Pause Menu/Cheats/CheatTableViewCell.swift"; sourceTree = "<group>"; };
/* End PBXFileReference section */ /* End PBXFileReference section */
@ -183,6 +191,7 @@
BF797A2C1C2D339F00F1A000 /* UILabel+FontSize.swift */, BF797A2C1C2D339F00F1A000 /* UILabel+FontSize.swift */,
BF7AE8091C2E8C7600B1B5BC /* UIColor+Delta.swift */, BF7AE8091C2E8C7600B1B5BC /* UIColor+Delta.swift */,
BF04A5A21CF8E61C00B4A267 /* UIViewController+PeekPop.swift */, BF04A5A21CF8E61C00B4A267 /* UIViewController+PeekPop.swift */,
BFCEA67D1D56FF640061A534 /* UIViewControllerContextTransitioning+Conveniences.swift */,
); );
path = Extensions; path = Extensions;
sourceTree = "<group>"; sourceTree = "<group>";
@ -243,6 +252,7 @@
children = ( children = (
BF107EC31BF413F000E0C32C /* GamesViewController.swift */, BF107EC31BF413F000E0C32C /* GamesViewController.swift */,
BF27CC961BCC890700A20D89 /* GamesCollectionViewController.swift */, BF27CC961BCC890700A20D89 /* GamesCollectionViewController.swift */,
BFFC461A1D59820F00AF2CC6 /* Segues */,
); );
path = "Game Selection"; path = "Game Selection";
sourceTree = "<group>"; sourceTree = "<group>";
@ -350,7 +360,6 @@
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
BFA2315B1CED10BE0011E35A /* Action.swift */, BFA2315B1CED10BE0011E35A /* Action.swift */,
BFF1E5631BE04CAF000E9EF6 /* BoxArtImageView.swift */,
BF0CDDAC1C8155D200640168 /* LoadImageOperation.swift */, BF0CDDAC1C8155D200640168 /* LoadImageOperation.swift */,
); );
name = Components; name = Components;
@ -381,6 +390,7 @@
children = ( children = (
BFFA71DC1AAC406100EE9DD1 /* AppDelegate.swift */, BFFA71DC1AAC406100EE9DD1 /* AppDelegate.swift */,
BFFA71E01AAC406100EE9DD1 /* Main.storyboard */, BFFA71E01AAC406100EE9DD1 /* Main.storyboard */,
BFFC46211D59848000AF2CC6 /* Launch */,
BF46894D1AAC469800A2586D /* Game Selection */, BF46894D1AAC469800A2586D /* Game Selection */,
BFFB709D1AF99ACA00DE56FE /* Emulation */, BFFB709D1AF99ACA00DE56FE /* Emulation */,
BF7AE7FA1C2E851F00B1B5BC /* Pause Menu */, BF7AE7FA1C2E851F00B1B5BC /* Pause Menu */,
@ -397,7 +407,6 @@
BF090CF11B490D8300DCAB45 /* Delta-Bridging-Header.h */, BF090CF11B490D8300DCAB45 /* Delta-Bridging-Header.h */,
BF27CC861BC9E3C600A20D89 /* Delta.entitlements */, BF27CC861BC9E3C600A20D89 /* Delta.entitlements */,
BFFA71DB1AAC406100EE9DD1 /* Info.plist */, BFFA71DB1AAC406100EE9DD1 /* Info.plist */,
BFFA71E51AAC406100EE9DD1 /* LaunchScreen.xib */,
); );
path = "Supporting Files"; path = "Supporting Files";
sourceTree = "<group>"; sourceTree = "<group>";
@ -410,6 +419,25 @@
path = Emulation; path = Emulation;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
BFFC461A1D59820F00AF2CC6 /* Segues */ = {
isa = PBXGroup;
children = (
BFFC461D1D59823500AF2CC6 /* InitialGamesStoryboardSegue.swift */,
BFFC461C1D59823500AF2CC6 /* GamesStoryboardSegue.swift */,
BFFC461B1D59823500AF2CC6 /* GamesPresentationController.swift */,
);
name = Segues;
sourceTree = "<group>";
};
BFFC46211D59848000AF2CC6 /* Launch */ = {
isa = PBXGroup;
children = (
BFFC46441D59861000AF2CC6 /* LaunchScreen.storyboard */,
BFFC46221D5984A000AF2CC6 /* LaunchViewController.swift */,
);
name = Launch;
sourceTree = "<group>";
};
/* End PBXGroup section */ /* End PBXGroup section */
/* Begin PBXNativeTarget section */ /* Begin PBXNativeTarget section */
@ -481,8 +509,8 @@
files = ( files = (
BFFA71E21AAC406100EE9DD1 /* Main.storyboard in Resources */, BFFA71E21AAC406100EE9DD1 /* Main.storyboard in Resources */,
BF3540001C5DA3C500C1184C /* PausePresentationControllerContentView.xib in Resources */, BF3540001C5DA3C500C1184C /* PausePresentationControllerContentView.xib in Resources */,
BFFA71E71AAC406100EE9DD1 /* LaunchScreen.xib in Resources */,
BF5E7F461B9A652600AE44F8 /* Settings.storyboard in Resources */, BF5E7F461B9A652600AE44F8 /* Settings.storyboard in Resources */,
BFFC46461D59861000AF2CC6 /* LaunchScreen.storyboard in Resources */,
BF353FF61C5D837600C1184C /* PauseMenu.storyboard in Resources */, BF353FF61C5D837600C1184C /* PauseMenu.storyboard in Resources */,
BF27CC8E1BC9FEA200A20D89 /* Assets.xcassets in Resources */, BF27CC8E1BC9FEA200A20D89 /* Assets.xcassets in Resources */,
); );
@ -550,6 +578,7 @@
BFA0D1271D3AE1F600565894 /* GameViewController.swift in Sources */, BFA0D1271D3AE1F600565894 /* GameViewController.swift in Sources */,
BF31878B1D489AAA00BD020D /* CheatValidator.swift in Sources */, BF31878B1D489AAA00BD020D /* CheatValidator.swift in Sources */,
BFB141181BE46934004FBF46 /* GameCollectionViewDataSource.swift in Sources */, BFB141181BE46934004FBF46 /* GameCollectionViewDataSource.swift in Sources */,
BFFC46201D59823500AF2CC6 /* InitialGamesStoryboardSegue.swift in Sources */,
BFA2315C1CED10BE0011E35A /* Action.swift in Sources */, BFA2315C1CED10BE0011E35A /* Action.swift in Sources */,
BFAA1FF41B8AD7F900495943 /* ControllersSettingsViewController.swift in Sources */, BFAA1FF41B8AD7F900495943 /* ControllersSettingsViewController.swift in Sources */,
BF353FF91C5D870B00C1184C /* PauseItem.swift in Sources */, BF353FF91C5D870B00C1184C /* PauseItem.swift in Sources */,
@ -557,12 +586,13 @@
BFFA71DD1AAC406100EE9DD1 /* AppDelegate.swift in Sources */, BFFA71DD1AAC406100EE9DD1 /* AppDelegate.swift in Sources */,
BF7AE81E1C2E984300B1B5BC /* GridCollectionViewCell.swift in Sources */, BF7AE81E1C2E984300B1B5BC /* GridCollectionViewCell.swift in Sources */,
BF34FA111CF1899D006624C7 /* CheatTextView.swift in Sources */, BF34FA111CF1899D006624C7 /* CheatTextView.swift in Sources */,
BFFC46231D5984A000AF2CC6 /* LaunchViewController.swift in Sources */,
BF04A5A31CF8E61C00B4A267 /* UIViewController+PeekPop.swift in Sources */, BF04A5A31CF8E61C00B4A267 /* UIViewController+PeekPop.swift in Sources */,
BF4566E81BC090B6007BFA1A /* Model.xcdatamodeld in Sources */, BF4566E81BC090B6007BFA1A /* Model.xcdatamodeld in Sources */,
BFDE393C1BC0CEDF003F72E8 /* Game.swift in Sources */, BFDE393C1BC0CEDF003F72E8 /* Game.swift in Sources */,
BF34FA071CF0F510006624C7 /* EditCheatViewController.swift in Sources */, BF34FA071CF0F510006624C7 /* EditCheatViewController.swift in Sources */,
BFC2731A1BE6152200D22B05 /* GameCollection.swift in Sources */, BFC2731A1BE6152200D22B05 /* GameCollection.swift in Sources */,
BFF1E5641BE04CAF000E9EF6 /* BoxArtImageView.swift in Sources */, BFFC461F1D59823500AF2CC6 /* GamesStoryboardSegue.swift in Sources */,
BF2B98E61C97E32F00F6D57D /* SaveStatesCollectionHeaderView.swift in Sources */, BF2B98E61C97E32F00F6D57D /* SaveStatesCollectionHeaderView.swift in Sources */,
BF762EAB1BC1B076002C8866 /* NSManagedObject+Conveniences.swift in Sources */, BF762EAB1BC1B076002C8866 /* NSManagedObject+Conveniences.swift in Sources */,
BFC9B7391CEFCD34008629BB /* CheatsViewController.swift in Sources */, BFC9B7391CEFCD34008629BB /* CheatsViewController.swift in Sources */,
@ -579,6 +609,8 @@
BF0CDDAD1C8155D200640168 /* LoadImageOperation.swift in Sources */, BF0CDDAD1C8155D200640168 /* LoadImageOperation.swift in Sources */,
BF107EC41BF413F000E0C32C /* GamesViewController.swift in Sources */, BF107EC41BF413F000E0C32C /* GamesViewController.swift in Sources */,
BF172AEB1C68986300C26774 /* NSManagedObjectContext+Conveniences.swift in Sources */, BF172AEB1C68986300C26774 /* NSManagedObjectContext+Conveniences.swift in Sources */,
BFCEA67E1D56FF640061A534 /* UIViewControllerContextTransitioning+Conveniences.swift in Sources */,
BFFC461E1D59823500AF2CC6 /* GamesPresentationController.swift in Sources */,
BF5E7F441B9A650B00AE44F8 /* SettingsViewController.swift in Sources */, BF5E7F441B9A650B00AE44F8 /* SettingsViewController.swift in Sources */,
BF353FF21C5D7FB000C1184C /* PauseViewController.swift in Sources */, BF353FF21C5D7FB000C1184C /* PauseViewController.swift in Sources */,
BFDB28451BC9DA7B001D0C83 /* GamePickerController.swift in Sources */, BFDB28451BC9DA7B001D0C83 /* GamePickerController.swift in Sources */,
@ -606,13 +638,12 @@
path = .; path = .;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
BFFA71E51AAC406100EE9DD1 /* LaunchScreen.xib */ = { BFFC46441D59861000AF2CC6 /* LaunchScreen.storyboard */ = {
isa = PBXVariantGroup; isa = PBXVariantGroup;
children = ( children = (
BFFA71E61AAC406100EE9DD1 /* Base */, BFFC46451D59861000AF2CC6 /* Base */,
); );
name = LaunchScreen.xib; name = LaunchScreen.storyboard;
path = .;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
/* End PBXVariantGroup section */ /* End PBXVariantGroup section */

View File

@ -0,0 +1,67 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="11185.3" systemVersion="15G31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="dkK-ii-Bx4">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11151.4"/>
<capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--Launch View Controller-->
<scene sceneID="DQQ-Kb-RwE">
<objects>
<viewController id="dkK-ii-Bx4" customClass="LaunchViewController" customModule="Delta" customModuleProvider="target" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="qMb-3x-uIu"/>
<viewControllerLayoutGuide type="bottom" id="FUd-UF-5dT"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="8Uu-wz-ps8">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text=" Copyright (c) 2015 Riley Testut. All rights reserved." textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="9" translatesAutoresizingMaskIntoConstraints="NO" id="jkf-0n-Uvb">
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Delta" textAlignment="center" lineBreakMode="middleTruncation" baselineAdjustment="alignBaselines" minimumFontSize="18" translatesAutoresizingMaskIntoConstraints="NO" id="6Gs-zO-Os2">
<fontDescription key="fontDescription" type="boldSystem" pointSize="36"/>
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
<nil key="highlightedColor"/>
</label>
<containerView hidden="YES" opaque="NO" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="8cb-35-6fJ">
<frame key="frameInset"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<connections>
<segue destination="t20-MI-odl" kind="embed" identifier="embedGameViewController" id="idv-a8-BL2"/>
</connections>
</containerView>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="6Gs-zO-Os2" firstAttribute="leading" secondItem="8Uu-wz-ps8" secondAttribute="leading" constant="20" symbolic="YES" id="5Eu-HV-q7D"/>
<constraint firstItem="jkf-0n-Uvb" firstAttribute="leading" secondItem="8Uu-wz-ps8" secondAttribute="leading" constant="20" symbolic="YES" id="FQi-iY-rOW"/>
<constraint firstItem="6Gs-zO-Os2" firstAttribute="centerY" secondItem="8Uu-wz-ps8" secondAttribute="bottom" multiplier="1/3" constant="1" id="Fna-Iv-pD2"/>
<constraint firstAttribute="bottom" secondItem="jkf-0n-Uvb" secondAttribute="bottom" constant="20" id="JNc-Vw-b2y"/>
<constraint firstAttribute="centerX" secondItem="6Gs-zO-Os2" secondAttribute="centerX" id="ZLv-eF-yHv"/>
<constraint firstAttribute="centerX" secondItem="jkf-0n-Uvb" secondAttribute="centerX" id="b8Z-N5-Fne"/>
</constraints>
</view>
<connections>
<outlet property="containerView" destination="8cb-35-6fJ" id="C1R-S6-fWD"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="5Q3-eM-p3F" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="-226.40000000000001" y="146.17691154422789"/>
</scene>
<!--Main-->
<scene sceneID="4GO-dC-G5v">
<objects>
<viewControllerPlaceholder storyboardName="Main" id="t20-MI-odl" sceneMemberID="viewController"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="Kwk-ha-eS6" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="371" y="146"/>
</scene>
</scenes>
</document>

View File

@ -1,9 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="11163.2" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="wKV-3d-NIY"> <document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="11185.3" systemVersion="15G31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="yhz-fF-D91">
<dependencies> <dependencies>
<deployment identifier="iOS"/> <deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11133"/> <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11151.4"/>
<capability name="Segues with Peek and Pop" minToolsVersion="7.1"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies> </dependencies>
<scenes> <scenes>
@ -48,7 +47,7 @@
</viewController> </viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="JYx-xE-nis" userLabel="First Responder" sceneMemberID="firstResponder"/> <placeholder placeholderIdentifier="IBFirstResponder" id="JYx-xE-nis" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects> </objects>
<point key="canvasLocation" x="1054" y="1002"/> <point key="canvasLocation" x="1036" y="1002"/>
</scene> </scene>
<!--Games Collection View Controller--> <!--Games Collection View Controller-->
<scene sceneID="qNA-NP-TiF"> <scene sceneID="qNA-NP-TiF">
@ -73,10 +72,7 @@
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
</view> </view>
<connections> <connections>
<segue destination="yhz-fF-D91" kind="presentation" identifier="presentGameViewController" id="4ws-DY-L4D"> <segue destination="X2o-q6-XD5" kind="unwind" unwindAction="unwindFromGamesViewControllerWith:" id="Cxx-73-8KV"/>
<segue key="commit" inheritsFrom="parent" id="sub-e4-fpl"/>
<segue key="preview" inheritsFrom="commit" id="WKY-hV-sn0"/>
</segue>
</connections> </connections>
</collectionViewCell> </collectionViewCell>
</cells> </cells>
@ -87,8 +83,9 @@
</collectionView> </collectionView>
</collectionViewController> </collectionViewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="bW1-t8-idm" userLabel="First Responder" sceneMemberID="firstResponder"/> <placeholder placeholderIdentifier="IBFirstResponder" id="bW1-t8-idm" userLabel="First Responder" sceneMemberID="firstResponder"/>
<exit id="X2o-q6-XD5" userLabel="Exit" sceneMemberID="exit"/>
</objects> </objects>
<point key="canvasLocation" x="1727" y="1002"/> <point key="canvasLocation" x="1764" y="1719"/>
</scene> </scene>
<!--Game View Controller--> <!--Game View Controller-->
<scene sceneID="ASV-Uk-0aP"> <scene sceneID="ASV-Uk-0aP">
@ -105,11 +102,13 @@
</view> </view>
<connections> <connections>
<segue destination="Yrw-9v-Pcr" kind="presentation" identifier="pause" customClass="PauseStoryboardSegue" customModule="Delta" customModuleProvider="target" id="FLq-Zt-HDv"/> <segue destination="Yrw-9v-Pcr" kind="presentation" identifier="pause" customClass="PauseStoryboardSegue" customModule="Delta" customModuleProvider="target" id="FLq-Zt-HDv"/>
<segue destination="wKV-3d-NIY" kind="presentation" identifier="showGamesViewController" customClass="GamesStoryboardSegue" customModule="Delta" customModuleProvider="target" id="Tey-6Z-UHp"/>
<segue destination="wKV-3d-NIY" kind="presentation" identifier="showInitialGamesViewController" customClass="InitialGamesStoryboardSegue" customModule="Delta" customModuleProvider="target" id="eR2-0c-0Rv"/>
</connections> </connections>
</viewController> </viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="gxI-00-NlJ" userLabel="First Responder" sceneMemberID="firstResponder"/> <placeholder placeholderIdentifier="IBFirstResponder" id="gxI-00-NlJ" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects> </objects>
<point key="canvasLocation" x="2472" y="1002"/> <point key="canvasLocation" x="-490" y="1002"/>
</scene> </scene>
<!--Page View Controller--> <!--Page View Controller-->
<scene sceneID="35q-Io-64T"> <scene sceneID="35q-Io-64T">
@ -117,7 +116,7 @@
<pageViewController autoresizesArchivedViewToFullSize="NO" transitionStyle="scroll" navigationOrientation="horizontal" spineLocation="none" id="tpK-ou-yEA" sceneMemberID="viewController"/> <pageViewController autoresizesArchivedViewToFullSize="NO" transitionStyle="scroll" navigationOrientation="horizontal" spineLocation="none" id="tpK-ou-yEA" sceneMemberID="viewController"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="TZS-QE-4Yg" userLabel="First Responder" sceneMemberID="firstResponder"/> <placeholder placeholderIdentifier="IBFirstResponder" id="TZS-QE-4Yg" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects> </objects>
<point key="canvasLocation" x="1054" y="1681"/> <point key="canvasLocation" x="1036" y="1719"/>
</scene> </scene>
<!--Settings--> <!--Settings-->
<scene sceneID="L3X-MM-hJL"> <scene sceneID="L3X-MM-hJL">
@ -125,7 +124,7 @@
<viewControllerPlaceholder storyboardName="Settings" id="xMK-Cs-fAS" sceneMemberID="viewController"/> <viewControllerPlaceholder storyboardName="Settings" id="xMK-Cs-fAS" sceneMemberID="viewController"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="2N5-3k-beA" userLabel="First Responder" sceneMemberID="firstResponder"/> <placeholder placeholderIdentifier="IBFirstResponder" id="2N5-3k-beA" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects> </objects>
<point key="canvasLocation" x="795.5" y="534"/> <point key="canvasLocation" x="1036" y="605"/>
</scene> </scene>
<!--Navigation Controller--> <!--Navigation Controller-->
<scene sceneID="zJI-sC-1sm"> <scene sceneID="zJI-sC-1sm">
@ -148,7 +147,7 @@
</navigationController> </navigationController>
<placeholder placeholderIdentifier="IBFirstResponder" id="0Br-8t-jcG" userLabel="First Responder" sceneMemberID="firstResponder"/> <placeholder placeholderIdentifier="IBFirstResponder" id="0Br-8t-jcG" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects> </objects>
<point key="canvasLocation" x="400" y="1002"/> <point key="canvasLocation" x="292" y="1002"/>
</scene> </scene>
<!--PauseMenu--> <!--PauseMenu-->
<scene sceneID="97k-By-dJD"> <scene sceneID="97k-By-dJD">
@ -156,13 +155,13 @@
<viewControllerPlaceholder storyboardName="PauseMenu" id="Yrw-9v-Pcr" sceneMemberID="viewController"/> <viewControllerPlaceholder storyboardName="PauseMenu" id="Yrw-9v-Pcr" sceneMemberID="viewController"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="BDU-Ql-OgK" userLabel="First Responder" sceneMemberID="firstResponder"/> <placeholder placeholderIdentifier="IBFirstResponder" id="BDU-Ql-OgK" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects> </objects>
<point key="canvasLocation" x="2470" y="1441"/> <point key="canvasLocation" x="-491" y="1431"/>
</scene> </scene>
</scenes> </scenes>
<resources> <resources>
<image name="Settings_Button" width="22" height="22"/> <image name="Settings_Button" width="22" height="22"/>
</resources> </resources>
<inferredMetricsTieBreakers> <inferredMetricsTieBreakers>
<segue reference="4ws-DY-L4D"/> <segue reference="Tey-6Z-UHp"/>
</inferredMetricsTieBreakers> </inferredMetricsTieBreakers>
</document> </document>

View File

@ -108,12 +108,12 @@
<barButtonItem key="leftBarButtonItem" title="Main Menu" style="done" id="2yt-vB-uMF"> <barButtonItem key="leftBarButtonItem" title="Main Menu" style="done" id="2yt-vB-uMF">
<color key="tintColor" red="1" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> <color key="tintColor" red="1" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<connections> <connections>
<segue destination="WU3-gG-BA5" kind="unwind" unwindAction="unwindFromEmulationViewController:" id="SdW-CX-n27"/> <segue destination="WU3-gG-BA5" kind="unwind" identifier="unwindToGames" unwindAction="unwindFromPauseViewController:" id="SdW-CX-n27"/>
</connections> </connections>
</barButtonItem> </barButtonItem>
<barButtonItem key="rightBarButtonItem" title="Resume" style="done" id="Wfq-I3-437"> <barButtonItem key="rightBarButtonItem" title="Resume" style="done" id="Wfq-I3-437">
<connections> <connections>
<segue destination="WU3-gG-BA5" kind="unwind" unwindAction="unwindFromPauseViewController:" id="RHb-pF-trg"/> <segue destination="WU3-gG-BA5" kind="unwind" identifier="unwindFromPauseMenu" unwindAction="unwindFromPauseViewController:" id="RHb-pF-trg"/>
</connections> </connections>
</barButtonItem> </barButtonItem>
</navigationItem> </navigationItem>

View File

@ -185,39 +185,49 @@ extension GameViewController
override func prepare(for segue: UIStoryboardSegue, sender: AnyObject?) override func prepare(for segue: UIStoryboardSegue, sender: AnyObject?)
{ {
guard let identifier = segue.identifier, identifier == "pause" else { return } guard let identifier = segue.identifier else { return }
guard let gameController = sender as? GameController else { switch identifier
fatalError("sender for pauseSegue must be the game controller that pressed the Menu button") {
} case "showGamesViewController":
let gamesViewController = (segue.destination as! UINavigationController).topViewController as! GamesViewController
gamesViewController.theme = .dark
self.pausingGameController = gameController case "pause":
guard let gameController = sender as? GameController else {
let pauseViewController = segue.destination as! PauseViewController fatalError("sender for pauseSegue must be the game controller that pressed the Menu button")
pauseViewController.pauseText = (self.game as? Game)?.name ?? NSLocalizedString("Delta", comment: "")
pauseViewController.emulatorCore = self.emulatorCore
pauseViewController.saveStatesViewControllerDelegate = self
pauseViewController.cheatsViewControllerDelegate = self
pauseViewController.fastForwardItem?.selected = (self.emulatorCore?.rate != self.emulatorCore?.configuration.supportedRates.lowerBound)
pauseViewController.fastForwardItem?.action = { [unowned self] item in
guard let emulatorCore = self.emulatorCore else { return }
emulatorCore.rate = item.selected ? emulatorCore.configuration.supportedRates.upperBound : emulatorCore.configuration.supportedRates.lowerBound
}
pauseViewController.sustainButtonsItem?.selected = (self.sustainedInputs[ObjectIdentifier(gameController)]?.count ?? 0) > 0
pauseViewController.sustainButtonsItem?.action = { [unowned self] item in
self.resetSustainedInputs(for: gameController)
if item.selected
{
self.showSustainButtonView()
pauseViewController.dismiss()
} }
}
self.pauseViewController = pauseViewController self.pausingGameController = gameController
let pauseViewController = segue.destination as! PauseViewController
pauseViewController.pauseText = (self.game as? Game)?.name ?? NSLocalizedString("Delta", comment: "")
pauseViewController.emulatorCore = self.emulatorCore
pauseViewController.saveStatesViewControllerDelegate = self
pauseViewController.cheatsViewControllerDelegate = self
pauseViewController.fastForwardItem?.selected = (self.emulatorCore?.rate != self.emulatorCore?.configuration.supportedRates.lowerBound)
pauseViewController.fastForwardItem?.action = { [unowned self] item in
guard let emulatorCore = self.emulatorCore else { return }
emulatorCore.rate = item.selected ? emulatorCore.configuration.supportedRates.upperBound : emulatorCore.configuration.supportedRates.lowerBound
}
pauseViewController.sustainButtonsItem?.selected = (self.sustainedInputs[ObjectIdentifier(gameController)]?.count ?? 0) > 0
pauseViewController.sustainButtonsItem?.action = { [unowned self] item in
self.resetSustainedInputs(for: gameController)
if item.selected
{
self.showSustainButtonView()
pauseViewController.dismiss()
}
}
self.pauseViewController = pauseViewController
default: break
}
} }
@IBAction private func unwindFromPauseViewController(_ segue: UIStoryboardSegue) @IBAction private func unwindFromPauseViewController(_ segue: UIStoryboardSegue)
@ -225,19 +235,56 @@ extension GameViewController
self.pauseViewController = nil self.pauseViewController = nil
self.pausingGameController = nil self.pausingGameController = nil
if self.resumeEmulation() guard let identifier = segue.identifier else { return }
switch identifier
{ {
// Temporarily disable audioManager to prevent delayed audio bug when using 3D Touch Peek & Pop case "unwindFromPauseMenu":
self.emulatorCore?.audioManager.enabled = false DispatchQueue.main.async {
if
let transitionCoordinator = self.transitionCoordinator,
let navigationController = segue.source.navigationController,
navigationController.viewControllers.count == 1
{
// If user pressed "Resume" from Pause Menu, we wait for the transition to complete before resuming emulation
transitionCoordinator.animate(alongsideTransition: nil, completion: { (context) in
self.resumeEmulation()
})
}
else
{
// Otherwise, we resume emulation immediately (such as when loading save states and the game view needs to be updated ASAP)
// Re-enable after delay if self.resumeEmulation()
{
// Temporarily disable audioManager to prevent delayed audio bug when using 3D Touch Peek & Pop
self.emulatorCore?.audioManager.enabled = false
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { // Re-enable after delay
self.emulatorCore?.audioManager.enabled = true
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
self.emulatorCore?.audioManager.enabled = true
}
}
}
} }
case "unwindToGames":
DispatchQueue.main.async {
self.transitionCoordinator?.animate(alongsideTransition: nil, completion: { (context) in
self.performSegue(withIdentifier: "showGamesViewController", sender: nil)
})
}
default: break
} }
} }
@IBAction private func unwindFromGamesViewController(with segue: UIStoryboardSegue)
{
self.emulatorCore?.resume()
}
// MARK: - KVO // MARK: - KVO
/// KVO /// KVO
override func observeValue(forKeyPath keyPath: String?, of object: AnyObject?, change: [NSKeyValueChangeKey : AnyObject]?, context: UnsafeMutablePointer<Void>?) override func observeValue(forKeyPath keyPath: String?, of object: AnyObject?, change: [NSKeyValueChangeKey : AnyObject]?, context: UnsafeMutablePointer<Void>?)
@ -552,7 +599,6 @@ private extension GameViewController
self.reactivateSustainedInputsQueue.waitUntilAllOperationsAreFinished() self.reactivateSustainedInputsQueue.waitUntilAllOperationsAreFinished()
gameController.addReceiver(self) gameController.addReceiver(self)
} }
} }
} }
@ -575,7 +621,7 @@ extension GameViewController: GameViewControllerDelegate
func gameViewControllerShouldResumeEmulation(_ gameViewController: DeltaCore.GameViewController) -> Bool func gameViewControllerShouldResumeEmulation(_ gameViewController: DeltaCore.GameViewController) -> Bool
{ {
return self.pauseViewController == nil && !self.selectingSustainedButtons return (self.presentedViewController == nil || self.presentedViewController?.isDisappearing == true) && !self.selectingSustainedButtons
} }
func gameViewControllerDidUpdate(_ gameViewController: DeltaCore.GameViewController) func gameViewControllerDidUpdate(_ gameViewController: DeltaCore.GameViewController)

View File

@ -0,0 +1,52 @@
//
// UIViewControllerContextTransitioning+Conveniences.swift
// Delta
//
// Created by Riley Testut on 7/28/16.
// Copyright © 2016 Riley Testut. All rights reserved.
//
import UIKit
extension UIViewControllerContextTransitioning
{
/// UIViewControllers
var sourceViewController: UIViewController {
return self.viewController(forKey: UITransitionContextFromViewControllerKey)!
}
var destinationViewController: UIViewController {
return self.viewController(forKey: UITransitionContextToViewControllerKey)!
}
/// UIViews
var sourceView: UIView {
return self.sourceViewController.view
}
var destinationView: UIView {
return self.destinationViewController.view
}
/// Frames
var sourceViewInitialFrame: CGRect? {
let frame = self.initialFrame(for: self.sourceViewController)
return frame.isEmpty ? nil : frame
}
var sourceViewFinalFrame: CGRect? {
let frame = self.finalFrame(for: self.sourceViewController)
return frame.isEmpty ? nil : frame
}
var destinationViewInitialFrame: CGRect? {
let frame = self.initialFrame(for: self.destinationViewController)
return frame.isEmpty ? nil : frame
}
var destinationViewFinalFrame: CGRect? {
let frame = self.finalFrame(for: self.destinationViewController)
return frame.isEmpty ? nil : frame
}
}

View File

@ -13,6 +13,12 @@ import DeltaCore
class GamesCollectionViewController: UICollectionViewController class GamesCollectionViewController: UICollectionViewController
{ {
var theme: GamesViewController.Theme = .light {
didSet {
self.collectionView?.reloadData()
}
}
weak var segueHandler: UIViewController? weak var segueHandler: UIViewController?
var gameCollection: GameCollection! { var gameCollection: GameCollection! {
@ -74,6 +80,19 @@ class GamesCollectionViewController: UICollectionViewController
cell.maximumImageSize = CGSize(width: 90, height: 90) cell.maximumImageSize = CGSize(width: 90, height: 90)
cell.textLabel.text = game.name cell.textLabel.text = game.name
cell.imageView.image = UIImage(named: "BoxArt") cell.imageView.image = UIImage(named: "BoxArt")
switch self.theme
{
case .light:
cell.textLabel.textColor = UIColor.darkText
cell.isTextLabelVibrancyEnabled = false
cell.isImageViewVibrancyEnabled = false
case .dark:
cell.textLabel.textColor = UIColor.white
cell.isTextLabelVibrancyEnabled = true
cell.isImageViewVibrancyEnabled = true
}
} }
} }

View File

@ -13,8 +13,23 @@ import DeltaCore
import Roxas import Roxas
extension GamesViewController
{
enum Theme
{
case light
case dark
}
}
class GamesViewController: UIViewController class GamesViewController: UIViewController
{ {
var theme: Theme = .light {
didSet {
self.updateTheme()
}
}
private var pageViewController: UIPageViewController! private var pageViewController: UIPageViewController!
private var backgroundView: RSTBackgroundView! private var backgroundView: RSTBackgroundView!
private var pageControl: UIPageControl! private var pageControl: UIPageControl!
@ -133,6 +148,32 @@ class GamesViewController: UIViewController
} }
} }
// MARK: - UI -
/// UI
private extension GamesViewController
{
func updateTheme()
{
switch self.theme
{
case .light:
self.view.backgroundColor = UIColor.white
self.navigationController?.navigationBar.barStyle = .default
self.navigationController?.toolbar.barStyle = .default
case .dark:
self.view.backgroundColor = nil
self.navigationController?.navigationBar.barStyle = .blackTranslucent
self.navigationController?.toolbar.barStyle = .blackTranslucent
}
if let collectionViewController = self.pageViewController.viewControllers?.first as? UICollectionViewController
{
collectionViewController.collectionView?.reloadData()
}
}
}
private extension GamesViewController private extension GamesViewController
{ {
func viewControllerForIndex(_ index: Int) -> GamesCollectionViewController? func viewControllerForIndex(_ index: Int) -> GamesCollectionViewController?
@ -154,6 +195,7 @@ private extension GamesViewController
viewController.gameCollection = self.fetchedResultsController.object(at: indexPath) as! GameCollection viewController.gameCollection = self.fetchedResultsController.object(at: indexPath) as! GameCollection
viewController.collectionView?.contentInset.top = self.topLayoutGuide.length viewController.collectionView?.contentInset.top = self.topLayoutGuide.length
viewController.segueHandler = self viewController.segueHandler = self
viewController.theme = self.theme
return viewController return viewController
} }

View File

@ -0,0 +1,46 @@
//
// GamesPresentationController.swift
// Delta
//
// Created by Riley Testut on 8/7/16.
// Copyright © 2016 Riley Testut. All rights reserved.
//
import UIKit
class GamesPresentationController: UIPresentationController
{
private let blurView: UIVisualEffectView
override init(presentedViewController: UIViewController, presenting presentingViewController: UIViewController?)
{
self.blurView = UIVisualEffectView(effect: nil)
self.blurView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
super.init(presentedViewController: presentedViewController, presenting: presentingViewController)
}
override func presentationTransitionWillBegin()
{
guard let containerView = self.containerView else { return }
self.blurView.frame = CGRect(x: 0, y: 0, width: containerView.bounds.width, height: containerView.bounds.height)
containerView.addSubview(self.blurView)
self.presentedViewController.transitionCoordinator?.animate(alongsideTransition: { (context) in
self.blurView.effect = UIBlurEffect(style: .dark)
})
}
override func dismissalTransitionWillBegin()
{
self.presentedViewController.transitionCoordinator?.animate(alongsideTransition: { (context) in
self.blurView.effect = nil
})
}
override func dismissalTransitionDidEnd(_ completed: Bool)
{
self.blurView.removeFromSuperview()
}
}

View File

@ -0,0 +1,158 @@
//
// GamesStoryboardSegue.swift
// Delta
//
// Created by Riley Testut on 8/7/16.
// Copyright © 2016 Riley Testut. All rights reserved.
//
import UIKit
class GamesStoryboardSegue: UIStoryboardSegue
{
private let animator: UIViewPropertyAnimator
private var isPresenting: Bool = true
override init(identifier: String?, source: UIViewController, destination: UIViewController)
{
let timingParameters = UISpringTimingParameters(mass: 3.0, stiffness: 750, damping: 65, initialVelocity: CGVector(dx: 0, dy: 0))
self.animator = UIViewPropertyAnimator(duration: 0, timingParameters: timingParameters)
super.init(identifier: identifier, source: source, destination: destination)
}
override func perform()
{
self.destination.transitioningDelegate = self
self.destination.modalPresentationStyle = .custom
self.destination.modalPresentationCapturesStatusBarAppearance = true
super.perform()
}
}
extension GamesStoryboardSegue: UIViewControllerTransitioningDelegate
{
func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning?
{
self.isPresenting = true
return self
}
func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning?
{
self.isPresenting = false
return self
}
func presentationController(forPresented presentedViewController: UIViewController, presenting presentingViewController: UIViewController?, source: UIViewController) -> UIPresentationController?
{
let presentationController = GamesPresentationController(presentedViewController: presentedViewController, presenting: presentingViewController)
return presentationController
}
}
extension GamesStoryboardSegue: UIViewControllerAnimatedTransitioning
{
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval
{
return self.animator.duration
}
func animateTransition(using transitionContext: UIViewControllerContextTransitioning)
{
if self.isPresenting
{
self.animatePresentationTransition(using: transitionContext)
}
else
{
self.animateDismissalTransition(using: transitionContext)
}
}
func animatePresentationTransition(using transitionContext: UIViewControllerContextTransitioning)
{
transitionContext.destinationView.frame = transitionContext.destinationViewFinalFrame!
transitionContext.destinationView.transform = CGAffineTransform(scaleX: 2.0, y: 2.0)
transitionContext.containerView.addSubview(transitionContext.destinationView)
let snapshotView = transitionContext.sourceView.snapshotView(afterScreenUpdates: false)!
snapshotView.frame = transitionContext.sourceViewInitialFrame!
snapshotView.alpha = 1.0
transitionContext.containerView.addSubview(snapshotView)
// Ensures navigation controller toolbar (if visible) has been added to view heirachy, allowing us to add constraints
transitionContext.containerView.layoutIfNeeded()
// We add extra padding around the existing navigation bar and toolbar so they never appear to be detached from the edges of the screen during the overshooting of the spring animation
var topPaddingToolbar: UIToolbar? = nil
var bottomPaddingToolbar: UIToolbar? = nil
if let navigationController = transitionContext.destinationViewController as? UINavigationController
{
let padding: CGFloat = 44
if !navigationController.isNavigationBarHidden
{
let topToolbar = UIToolbar(frame: CGRect.zero)
topToolbar.translatesAutoresizingMaskIntoConstraints = false
topToolbar.barStyle = navigationController.toolbar.barStyle
transitionContext.destinationView.insertSubview(topToolbar, belowSubview: navigationController.navigationBar)
topToolbar.bottomAnchor.constraint(equalTo: navigationController.navigationBar.bottomAnchor).isActive = true
topToolbar.centerXAnchor.constraint(equalTo: navigationController.navigationBar.centerXAnchor).isActive = true
topToolbar.widthAnchor.constraint(equalTo: navigationController.navigationBar.widthAnchor, constant: padding * 2).isActive = true
topToolbar.heightAnchor.constraint(equalTo: navigationController.navigationBar.heightAnchor, constant: padding).isActive = true
topPaddingToolbar = topToolbar
}
if !navigationController.isToolbarHidden
{
let bottomToolbar = UIToolbar(frame: CGRect.zero)
bottomToolbar.translatesAutoresizingMaskIntoConstraints = false
bottomToolbar.barStyle = navigationController.toolbar.barStyle
transitionContext.destinationView.insertSubview(bottomToolbar, belowSubview: navigationController.navigationBar)
bottomToolbar.topAnchor.constraint(equalTo: navigationController.toolbar.topAnchor).isActive = true
bottomToolbar.centerXAnchor.constraint(equalTo: navigationController.toolbar.centerXAnchor).isActive = true
bottomToolbar.widthAnchor.constraint(equalTo: navigationController.toolbar.widthAnchor, constant: padding * 2).isActive = true
bottomToolbar.heightAnchor.constraint(equalTo: navigationController.toolbar.heightAnchor, constant: padding).isActive = true
bottomPaddingToolbar = bottomToolbar
}
}
self.animator.addAnimations {
snapshotView.alpha = 0.0
transitionContext.destinationView.transform = CGAffineTransform.identity
}
self.animator.addCompletion { (position) in
transitionContext.completeTransition(position == .end)
snapshotView.removeFromSuperview()
topPaddingToolbar?.removeFromSuperview()
bottomPaddingToolbar?.removeFromSuperview()
}
self.animator.startAnimation()
}
func animateDismissalTransition(using transitionContext: UIViewControllerContextTransitioning)
{
self.animator.addAnimations {
transitionContext.sourceView.alpha = 0.0
transitionContext.sourceView.transform = CGAffineTransform(scaleX: 2.0, y: 2.0)
}
self.animator.addCompletion { (position) in
transitionContext.completeTransition(position == .end)
}
self.animator.startAnimation()
}
}

View File

@ -0,0 +1,96 @@
//
// InitialGamesStoryboardSegue.swift
// Delta
//
// Created by Riley Testut on 8/7/16.
// Copyright © 2016 Riley Testut. All rights reserved.
//
import UIKit
class InitialGamesStoryboardSegue: UIStoryboardSegue
{
private let animator: UIViewPropertyAnimator
private var isPresenting: Bool = true
override init(identifier: String?, source: UIViewController, destination: UIViewController)
{
let timingParameters = UISpringTimingParameters(mass: 3.0, stiffness: 750, damping: 65, initialVelocity: CGVector(dx: 0, dy: 0))
self.animator = UIViewPropertyAnimator(duration: 0, timingParameters: timingParameters)
super.init(identifier: identifier, source: source, destination: destination)
}
override func perform()
{
self.destination.transitioningDelegate = self
self.destination.modalPresentationStyle = .custom
self.destination.modalPresentationCapturesStatusBarAppearance = true
super.perform()
}
}
extension InitialGamesStoryboardSegue: UIViewControllerTransitioningDelegate
{
func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning?
{
self.isPresenting = true
return self
}
func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning?
{
self.isPresenting = false
return self
}
}
extension InitialGamesStoryboardSegue: UIViewControllerAnimatedTransitioning
{
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval
{
return self.isPresenting ? 0.0 : self.animator.duration
}
func animateTransition(using transitionContext: UIViewControllerContextTransitioning)
{
if self.isPresenting
{
self.animatePresentationTransition(using: transitionContext)
}
else
{
self.animateDismissalTransition(using: transitionContext)
}
}
func animatePresentationTransition(using transitionContext: UIViewControllerContextTransitioning)
{
// No animation
transitionContext.destinationView.frame = transitionContext.destinationViewFinalFrame!
transitionContext.containerView.addSubview(transitionContext.destinationView)
transitionContext.completeTransition(true)
}
func animateDismissalTransition(using transitionContext: UIViewControllerContextTransitioning)
{
transitionContext.destinationView.transform = CGAffineTransform(scaleX: 0.5, y: 0.5)
transitionContext.destinationView.alpha = 0.0
self.animator.addAnimations {
transitionContext.sourceView.alpha = 0.0
transitionContext.sourceView.transform = CGAffineTransform(scaleX: 2.0, y: 2.0)
transitionContext.destinationView.alpha = 1.0
transitionContext.destinationView.transform = CGAffineTransform.identity
}
self.animator.addCompletion { (position) in
transitionContext.completeTransition(position == .end)
}
self.animator.startAnimation()
}
}

View File

@ -0,0 +1,47 @@
//
// LaunchViewController.swift
// Delta
//
// Created by Riley Testut on 8/8/16.
// Copyright © 2016 Riley Testut. All rights reserved.
//
import UIKit
class LaunchViewController: UIViewController
{
@IBOutlet private var containerView: UIView!
private var gameViewController: GameViewController!
private var presentedGameViewController: Bool = false
override var preferredStatusBarStyle: UIStatusBarStyle {
return self.gameViewController?.preferredStatusBarStyle ?? .default
}
override var prefersStatusBarHidden: Bool {
return self.gameViewController?.prefersStatusBarHidden ?? false
}
override func viewDidAppear(_ animated: Bool)
{
super.viewDidAppear(animated)
if !self.presentedGameViewController
{
self.presentedGameViewController = true
self.gameViewController.performSegue(withIdentifier: "showInitialGamesViewController", sender: nil)
self.transitionCoordinator?.animate(alongsideTransition: nil, completion: { (context) in
self.containerView.isHidden = false
})
}
}
override func prepare(for segue: UIStoryboardSegue, sender: AnyObject?)
{
guard segue.identifier == "embedGameViewController" else { return }
self.gameViewController = segue.destination as! GameViewController
}
}

View File

@ -1,41 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="6214" systemVersion="14A314h" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6207"/>
<capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="iN0-l3-epB">
<rect key="frame" x="0.0" y="0.0" width="480" height="480"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text=" Copyright (c) 2015 Riley Testut. All rights reserved." textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="9" translatesAutoresizingMaskIntoConstraints="NO" id="8ie-xW-0ye">
<rect key="frame" x="20" y="439" width="441" height="21"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Delta" textAlignment="center" lineBreakMode="middleTruncation" baselineAdjustment="alignBaselines" minimumFontSize="18" translatesAutoresizingMaskIntoConstraints="NO" id="kId-c2-rCX">
<rect key="frame" x="20" y="140" width="441" height="43"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="36"/>
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
<constraints>
<constraint firstItem="kId-c2-rCX" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="bottom" multiplier="1/3" constant="1" id="5cJ-9S-tgC"/>
<constraint firstAttribute="centerX" secondItem="kId-c2-rCX" secondAttribute="centerX" id="Koa-jz-hwk"/>
<constraint firstAttribute="bottom" secondItem="8ie-xW-0ye" secondAttribute="bottom" constant="20" id="Kzo-t9-V3l"/>
<constraint firstItem="8ie-xW-0ye" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" symbolic="YES" id="MfP-vx-nX0"/>
<constraint firstAttribute="centerX" secondItem="8ie-xW-0ye" secondAttribute="centerX" id="ZEH-qu-HZ9"/>
<constraint firstItem="kId-c2-rCX" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" symbolic="YES" id="fvb-Df-36g"/>
</constraints>
<nil key="simulatedStatusBarMetrics"/>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<point key="canvasLocation" x="548" y="455"/>
</view>
</objects>
</document>

View File

@ -42,7 +42,7 @@
<key>UILaunchStoryboardName</key> <key>UILaunchStoryboardName</key>
<string>LaunchScreen</string> <string>LaunchScreen</string>
<key>UIMainStoryboardFile</key> <key>UIMainStoryboardFile</key>
<string>Main</string> <string>LaunchScreen</string>
<key>UIRequiredDeviceCapabilities</key> <key>UIRequiredDeviceCapabilities</key>
<array> <array>
<string>armv7</string> <string>armv7</string>