Presents empty SaveStatesViewController for Save/Load State Pause Item

This commit is contained in:
Riley Testut 2016-01-29 20:00:36 -08:00
parent b8b46f00a6
commit 9dcec258c1
9 changed files with 210 additions and 11 deletions

View File

@ -31,6 +31,10 @@
BF353FFF1C5DA3C500C1184C /* PausePresentationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF353FFD1C5DA3C500C1184C /* PausePresentationController.swift */; };
BF3540001C5DA3C500C1184C /* PausePresentationControllerContentView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BF353FFE1C5DA3C500C1184C /* PausePresentationControllerContentView.xib */; };
BF3540021C5DA3D500C1184C /* PauseStoryboardSegue.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF3540011C5DA3D500C1184C /* PauseStoryboardSegue.swift */; };
BF3540051C5DA70400C1184C /* SaveStatesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF3540041C5DA70400C1184C /* SaveStatesViewController.swift */; };
BF3540061C5DA70400C1184C /* SaveStatesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF3540041C5DA70400C1184C /* SaveStatesViewController.swift */; };
BF3540081C5DAFAD00C1184C /* PauseTransitionCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF3540071C5DAFAD00C1184C /* PauseTransitionCoordinator.swift */; };
BF3540091C5DAFAD00C1184C /* PauseTransitionCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF3540071C5DAFAD00C1184C /* PauseTransitionCoordinator.swift */; };
BF4566E81BC090B6007BFA1A /* Model.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = BF4566E61BC090B6007BFA1A /* Model.xcdatamodeld */; };
BF4566E91BC090B6007BFA1A /* Model.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = BF4566E61BC090B6007BFA1A /* Model.xcdatamodeld */; };
BF5E7F441B9A650B00AE44F8 /* SettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF5E7F431B9A650B00AE44F8 /* SettingsViewController.swift */; };
@ -134,6 +138,8 @@
BF353FFD1C5DA3C500C1184C /* PausePresentationController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = PausePresentationController.swift; path = "Pause Menu/Presentation Controller/PausePresentationController.swift"; sourceTree = "<group>"; };
BF353FFE1C5DA3C500C1184C /* PausePresentationControllerContentView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = PausePresentationControllerContentView.xib; path = "Pause Menu/Presentation Controller/PausePresentationControllerContentView.xib"; sourceTree = "<group>"; };
BF3540011C5DA3D500C1184C /* PauseStoryboardSegue.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = PauseStoryboardSegue.swift; path = "Pause Menu/Segues/PauseStoryboardSegue.swift"; sourceTree = "<group>"; };
BF3540041C5DA70400C1184C /* SaveStatesViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SaveStatesViewController.swift; path = "Pause Menu/Save States/SaveStatesViewController.swift"; sourceTree = "<group>"; };
BF3540071C5DAFAD00C1184C /* PauseTransitionCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = PauseTransitionCoordinator.swift; path = "Pause Menu/Segues/PauseTransitionCoordinator.swift"; sourceTree = "<group>"; };
BF4566E71BC090B6007BFA1A /* Model.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = Model.xcdatamodel; sourceTree = "<group>"; };
BF5E7F431B9A650B00AE44F8 /* SettingsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SettingsViewController.swift; sourceTree = "<group>"; };
BF5E7F451B9A652600AE44F8 /* Settings.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Settings.storyboard; sourceTree = "<group>"; };
@ -230,6 +236,14 @@
name = "Presentation Controller";
sourceTree = "<group>";
};
BF3540031C5DA6D800C1184C /* Save States */ = {
isa = PBXGroup;
children = (
BF3540041C5DA70400C1184C /* SaveStatesViewController.swift */,
);
name = "Save States";
sourceTree = "<group>";
};
BF4566E31BC09026007BFA1A /* Common */ = {
isa = PBXGroup;
children = (
@ -299,6 +313,7 @@
BF353FF11C5D7FB000C1184C /* PauseViewController.swift */,
BF7AE8041C2E858400B1B5BC /* PauseMenuViewController.swift */,
BF353FF81C5D870B00C1184C /* PauseItem.swift */,
BF3540031C5DA6D800C1184C /* Save States */,
BF353FFB1C5DA2F600C1184C /* Presentation Controller */,
BF912E481C5CB5D50041527C /* Segues */,
);
@ -317,6 +332,7 @@
isa = PBXGroup;
children = (
BF3540011C5DA3D500C1184C /* PauseStoryboardSegue.swift */,
BF3540071C5DAFAD00C1184C /* PauseTransitionCoordinator.swift */,
);
name = Segues;
sourceTree = "<group>";
@ -667,9 +683,11 @@
BFB141191BE46934004FBF46 /* GameCollectionViewDataSource.swift in Sources */,
BFF1E5651BE04CAF000E9EF6 /* BoxArtImageView.swift in Sources */,
BF353FFA1C5D870B00C1184C /* PauseItem.swift in Sources */,
BF3540061C5DA70400C1184C /* SaveStatesViewController.swift in Sources */,
BF353FF31C5D7FB000C1184C /* PauseViewController.swift in Sources */,
BF6BB23F1BB73FE800CCF94A /* AppDelegate.swift in Sources */,
BF4566E91BC090B6007BFA1A /* Model.xcdatamodeld in Sources */,
BF3540091C5DAFAD00C1184C /* PauseTransitionCoordinator.swift in Sources */,
BF762EAC1BC1B076002C8866 /* NSManagedObject+Conveniences.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -678,6 +696,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
BF3540081C5DAFAD00C1184C /* PauseTransitionCoordinator.swift in Sources */,
BFAA1FED1B8AA4FA00495943 /* Settings.swift in Sources */,
BF7AE8241C2E984300B1B5BC /* GridCollectionViewLayout.swift in Sources */,
BFB141181BE46934004FBF46 /* GameCollectionViewDataSource.swift in Sources */,
@ -705,6 +724,7 @@
BFDB28451BC9DA7B001D0C83 /* GamePickerController.swift in Sources */,
BFDE393A1BC0CEDF003F72E8 /* Game+CoreDataProperties.swift in Sources */,
BF7AE8081C2E858400B1B5BC /* PauseMenuViewController.swift in Sources */,
BF3540051C5DA70400C1184C /* SaveStatesViewController.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View File

@ -66,12 +66,13 @@
</view>
<connections>
<segue destination="kQK-P0-mVu" kind="unwind" identifier="unwindFromPauseMenu" unwindAction="unwindFromPauseViewController:" id="2DE-Nv-qaq"/>
<segue destination="OOk-k7-INg" kind="show" identifier="saveState" id="iKc-6q-unN"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="PWj-WH-rlB" userLabel="First Responder" sceneMemberID="firstResponder"/>
<exit id="kQK-P0-mVu" userLabel="Exit" sceneMemberID="exit"/>
</objects>
<point key="canvasLocation" x="1026" y="657"/>
<point key="canvasLocation" x="992" y="657"/>
</scene>
<!--Navigation Controller-->
<scene sceneID="Kva-gK-ERA">
@ -139,5 +140,42 @@
</objects>
<point key="canvasLocation" x="2385" y="657"/>
</scene>
<!--Save State-->
<scene sceneID="9Fi-Ti-W8T">
<objects>
<collectionViewController storyboardIdentifier="saveStatesViewController" id="OOk-k7-INg" customClass="SaveStatesViewController" customModule="Delta" customModuleProvider="target" sceneMemberID="viewController">
<collectionView key="view" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" dataMode="prototypes" id="XgF-OF-CVf">
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<collectionViewFlowLayout key="collectionViewLayout" minimumLineSpacing="10" minimumInteritemSpacing="10" id="tvW-q1-PD8" customClass="GridCollectionViewLayout" customModule="Delta" customModuleProvider="target">
<size key="itemSize" width="50" height="50"/>
<size key="headerReferenceSize" width="0.0" height="0.0"/>
<size key="footerReferenceSize" width="0.0" height="0.0"/>
<inset key="sectionInset" minX="20" minY="20" maxX="20" maxY="20"/>
</collectionViewFlowLayout>
<cells>
<collectionViewCell opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" reuseIdentifier="Cell" id="c3N-1A-ryV" customClass="GridCollectionViewCell" customModule="Delta" customModuleProvider="target">
<rect key="frame" x="20" y="84" width="50" height="50"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
<rect key="frame" x="0.0" y="0.0" width="50" height="50"/>
<autoresizingMask key="autoresizingMask"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
</view>
</collectionViewCell>
</cells>
<connections>
<outlet property="dataSource" destination="OOk-k7-INg" id="8l7-6Q-tQp"/>
<outlet property="delegate" destination="OOk-k7-INg" id="aLg-5i-MAd"/>
</connections>
</collectionView>
<navigationItem key="navigationItem" title="Save State" id="BoG-k2-aR2"/>
<simulatedNavigationBarMetrics key="simulatedTopBarMetrics" barStyle="black" prompted="NO"/>
</collectionViewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="cL5-DH-K3b" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="992" y="1377"/>
</scene>
</scenes>
</document>

View File

@ -147,14 +147,20 @@ class EmulationViewController: UIViewController
pauseViewController.dismiss()
}
let saveStateItem = PauseItem(image: UIImage(named: "SmallPause")!, text: NSLocalizedString("Save State", comment: ""), action: dismissAction)
let loadStateItem = PauseItem(image: UIImage(named: "SmallPause")!, text: NSLocalizedString("Load State", comment: ""), action: dismissAction)
let saveStateItem = PauseItem(image: UIImage(named: "SmallPause")!, text: NSLocalizedString("Save State", comment: ""), action: { _ in
pauseViewController.presentSaveStateViewController()
})
let loadStateItem = PauseItem(image: UIImage(named: "SmallPause")!, text: NSLocalizedString("Load State", comment: ""), action: { _ in
pauseViewController.presentSaveStateViewController()
})
let cheatCodesItem = PauseItem(image: UIImage(named: "SmallPause")!, text: NSLocalizedString("Cheat Codes", comment: ""), action: dismissAction)
let sustainButtonItem = PauseItem(image: UIImage(named: "SmallPause")!, text: NSLocalizedString("Sustain Button", comment: ""), action: dismissAction)
var fastForwardItem = PauseItem(image: UIImage(named: "FastForward")!, text: NSLocalizedString("Fast Forward", comment: ""), action: { [weak self] item in
self?.emulatorCore.fastForwarding = item.selected
})
})
fastForwardItem.selected = self.emulatorCore.fastForwarding
pauseViewController.items = [saveStateItem, loadStateItem, cheatCodesItem, fastForwardItem, sustainButtonItem]

View File

@ -31,11 +31,15 @@ class PauseMenuViewController: UICollectionViewController
}
private var prototypeCell = GridCollectionViewCell()
private var previousIndexPath: NSIndexPath? = nil
}
extension PauseMenuViewController
{
override func viewDidLoad()
{
super.viewDidLoad()
let collectionViewLayout = self.collectionViewLayout as! GridCollectionViewLayout
collectionViewLayout.itemWidth = 90
collectionViewLayout.usesEqualHorizontalSpacingDistributionForSingleRow = true
@ -43,6 +47,18 @@ class PauseMenuViewController: UICollectionViewController
// Manually update prototype cell properties
self.prototypeCell.contentView.widthAnchor.constraintEqualToConstant(collectionViewLayout.itemWidth).active = true
}
override func viewDidAppear(animated: Bool)
{
super.viewDidAppear(animated)
if let indexPath = self.previousIndexPath
{
UIView.animateWithDuration(0.2) {
self.toggleSelectedStateForPauseItemAtIndexPath(indexPath)
}
}
}
}
private extension PauseMenuViewController
@ -125,6 +141,8 @@ extension PauseMenuViewController
override func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath)
{
self.previousIndexPath = indexPath
self.toggleSelectedStateForPauseItemAtIndexPath(indexPath)
let pauseItem = self.items[indexPath.item]

View File

@ -31,6 +31,10 @@ class PauseViewController: UIViewController, PauseInfoProvidable
}
}
override var navigationController: UINavigationController? {
return self.pauseNavigationController
}
private var pauseNavigationController: UINavigationController!
}
@ -59,11 +63,16 @@ extension PauseViewController
self.pauseNavigationController.navigationBar.frame = CGRect(x: 0, y: 0, width: self.view.bounds.width, height: self.pauseNavigationController.navigationBar.bounds.height)
}
override func targetViewControllerForAction(action: Selector, sender: AnyObject?) -> UIViewController? {
return self.pauseNavigationController
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
{
if segue.identifier == "embedNavigationController"
{
self.pauseNavigationController = segue.destinationViewController as! UINavigationController
self.pauseNavigationController.delegate = self
self.pauseNavigationController.navigationBar.tintColor = UIColor.deltaLightPurpleColor()
self.pauseNavigationController.view.backgroundColor = UIColor.clearColor()
@ -82,4 +91,19 @@ extension PauseViewController
{
self.performSegueWithIdentifier("unwindFromPauseMenu", sender: self)
}
func presentSaveStateViewController()
{
self.performSegueWithIdentifier("saveState", sender: self)
}
}
extension PauseViewController: UINavigationControllerDelegate
{
func navigationController(navigationController: UINavigationController, animationControllerForOperation operation: UINavigationControllerOperation, fromViewController fromVC: UIViewController, toViewController toVC: UIViewController) -> UIViewControllerAnimatedTransitioning?
{
let transitionCoordinator = PauseTransitionCoordinator(presentationController: self.presentationController!)
transitionCoordinator.presenting = (operation == .Push)
return transitionCoordinator
}
}

View File

@ -111,6 +111,12 @@ class PausePresentationController: UIPresentationController
let currentY = self.contentView.frame.minY
self.contentView.frame = self.containerView!.bounds
self.contentView.frame.origin.y = currentY
if self.presentedView()!.frame.minY == 0
{
// Temporarily offset top of presentedView by a small amount to prevent navigation bar from growing when rotating from landscape to portrait
self.presentedView()?.frame.origin.y = 0.5
}
}
override func containerViewDidLayoutSubviews()

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="9531" systemVersion="15C50" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="9531" systemVersion="15D21" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="9529"/>
</dependencies>
@ -17,7 +17,7 @@
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="15" translatesAutoresizingMaskIntoConstraints="NO" id="qFz-hB-77X">
<rect key="frame" x="15" y="236" width="570" height="128"/>
<rect key="frame" x="15" y="236" width="570" height="127.5"/>
<subviews>
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" verticalCompressionResistancePriority="500" image="Pause" translatesAutoresizingMaskIntoConstraints="NO" id="cWa-Ht-i5m">
<rect key="frame" x="0.0" y="0.0" width="570" height="80"/>
@ -28,7 +28,7 @@
</constraints>
</imageView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="center" horizontalHuggingPriority="251" verticalHuggingPriority="251" verticalCompressionResistancePriority="800" text="Super Mario World" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" translatesAutoresizingMaskIntoConstraints="NO" id="ZcT-qE-aES">
<rect key="frame" x="0.0" y="95" width="570" height="33"/>
<rect key="frame" x="0.0" y="95" width="570" height="32.5"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleTitle1"/>
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<nil key="highlightedColor"/>
@ -39,10 +39,10 @@
<constraints>
<constraint firstItem="qFz-hB-77X" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="15" id="O4d-vf-HNQ"/>
<constraint firstAttribute="trailing" secondItem="qFz-hB-77X" secondAttribute="trailing" constant="15" id="UPY-jb-YBJ"/>
<constraint firstItem="qFz-hB-77X" firstAttribute="top" relation="greaterThanOrEqual" secondItem="iN0-l3-epB" secondAttribute="top" constant="15" id="Xjv-XS-rUO"/>
<constraint firstItem="qFz-hB-77X" firstAttribute="top" relation="greaterThanOrEqual" secondItem="iN0-l3-epB" secondAttribute="top" priority="999" constant="15" id="Xjv-XS-rUO"/>
<constraint firstItem="qFz-hB-77X" firstAttribute="centerX" secondItem="iN0-l3-epB" secondAttribute="centerX" id="ayR-oW-5T2"/>
<constraint firstItem="qFz-hB-77X" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="centerY" id="b6K-Qu-AAG"/>
<constraint firstAttribute="bottom" relation="greaterThanOrEqual" secondItem="qFz-hB-77X" secondAttribute="bottom" constant="15" id="wwI-EY-TVj"/>
<constraint firstAttribute="bottom" relation="greaterThanOrEqual" secondItem="qFz-hB-77X" secondAttribute="bottom" priority="999" constant="15" id="wwI-EY-TVj"/>
</constraints>
<nil key="simulatedStatusBarMetrics"/>
<point key="canvasLocation" x="393" y="426"/>

View File

@ -0,0 +1,34 @@
//
// SaveStatesViewController.swift
// Delta
//
// Created by Riley Testut on 1/23/16.
// Copyright © 2016 Riley Testut. All rights reserved.
//
import UIKit
import Roxas
class SaveStatesViewController: UICollectionViewController
{
private var backgroundView: RSTBackgroundView!
override func viewDidLoad()
{
super.viewDidLoad()
self.backgroundView = RSTBackgroundView(frame: self.view.bounds)
self.backgroundView.autoresizingMask = [.FlexibleWidth, .FlexibleHeight]
self.backgroundView.textLabel.text = NSLocalizedString("No Save States", comment: "")
self.backgroundView.textLabel.textColor = UIColor.whiteColor()
self.backgroundView.detailTextLabel.text = NSLocalizedString("You can create a new save state by pressing the + button in the top right.", comment: "")
self.backgroundView.detailTextLabel.textColor = UIColor.whiteColor()
self.view.insertSubview(self.backgroundView, atIndex: 0)
}
override func didReceiveMemoryWarning()
{
super.didReceiveMemoryWarning()
}
}

View File

@ -0,0 +1,53 @@
//
// PauseTransitionCoordinator.swift
// Delta
//
// Created by Riley Testut on 1/30/16.
// Copyright © 2016 Riley Testut. All rights reserved.
//
import UIKit
import Roxas
class PauseTransitionCoordinator: NSObject, UIViewControllerAnimatedTransitioning
{
let presentationController: UIPresentationController
var presenting = false
init(presentationController: UIPresentationController)
{
self.presentationController = presentationController
super.init()
}
func transitionDuration(transitionContext: UIViewControllerContextTransitioning?) -> NSTimeInterval
{
return 0.4
}
func animateTransition(transitionContext: UIViewControllerContextTransitioning)
{
let destinationViewController = transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey)!
let sourceViewController = transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey)!
destinationViewController.view.frame = transitionContext.finalFrameForViewController(destinationViewController)
destinationViewController.view.frame.origin.y = self.presenting ? transitionContext.containerView()!.bounds.height : -destinationViewController.view.bounds.height
transitionContext.containerView()!.addSubview(destinationViewController.view)
destinationViewController.view.layoutIfNeeded()
UIView.animateWithDuration(self.transitionDuration(transitionContext), delay:0, options:RSTSystemTransitionAnimationCurve, animations: {
sourceViewController.view.frame.origin.y = self.presenting ? -sourceViewController.view.bounds.height : transitionContext.containerView()!.bounds.height
destinationViewController.view.frame.origin.y = 0
self.presentationController.containerView?.setNeedsLayout()
self.presentationController.containerView?.layoutIfNeeded()
}) { finished in
transitionContext.completeTransition(finished)
}
}
}