Added basic PauseViewController implementation

Also, happy Boxing Day! Hope you're enjoying your new iPad Pro future Riley :)
This commit is contained in:
Riley Testut 2015-12-26 02:19:37 -06:00
parent 755266f393
commit 8f572fd1c8
16 changed files with 974 additions and 19 deletions

View File

@ -38,6 +38,14 @@
BF762E9F1BC19D31002C8866 /* DatabaseManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF762E9D1BC19D31002C8866 /* DatabaseManager.swift */; };
BF762EAB1BC1B076002C8866 /* NSManagedObject+Conveniences.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF762EAA1BC1B076002C8866 /* NSManagedObject+Conveniences.swift */; };
BF762EAC1BC1B076002C8866 /* NSManagedObject+Conveniences.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF762EAA1BC1B076002C8866 /* NSManagedObject+Conveniences.swift */; };
BF797A2D1C2D339F00F1A000 /* UILabel+FontSize.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF797A2C1C2D339F00F1A000 /* UILabel+FontSize.swift */; };
BF7AE7FE1C2E857A00B1B5BC /* GridCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF7AE7FB1C2E857A00B1B5BC /* GridCollectionViewCell.swift */; };
BF7AE7FF1C2E857A00B1B5BC /* GridCollectionViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = BF7AE7FC1C2E857A00B1B5BC /* GridCollectionViewCell.xib */; };
BF7AE8001C2E857A00B1B5BC /* GridCollectionViewLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF7AE7FD1C2E857A00B1B5BC /* GridCollectionViewLayout.swift */; };
BF7AE8051C2E858400B1B5BC /* PausePresentationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF7AE8011C2E858400B1B5BC /* PausePresentationController.swift */; };
BF7AE8061C2E858400B1B5BC /* PausePresentationControllerContentView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BF7AE8021C2E858400B1B5BC /* PausePresentationControllerContentView.xib */; };
BF7AE8071C2E858400B1B5BC /* PauseStoryboardSegue.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF7AE8031C2E858400B1B5BC /* PauseStoryboardSegue.swift */; };
BF7AE8081C2E858400B1B5BC /* PauseViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF7AE8041C2E858400B1B5BC /* PauseViewController.swift */; };
BF8624881BB743FE00C12EEE /* Roxas.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BFEC732C1AAECC4A00650035 /* Roxas.framework */; };
BF8624891BB743FE00C12EEE /* Roxas.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = BFEC732C1AAECC4A00650035 /* Roxas.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
BF8624A91BB7464B00C12EEE /* DeltaCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BF9F4FCE1AAD7B87004C9500 /* DeltaCore.framework */; };
@ -131,6 +139,14 @@
BF70798B1B6B464B0019077C /* ZipZap.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = ZipZap.framework; sourceTree = BUILT_PRODUCTS_DIR; };
BF762E9D1BC19D31002C8866 /* DatabaseManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DatabaseManager.swift; sourceTree = "<group>"; };
BF762EAA1BC1B076002C8866 /* NSManagedObject+Conveniences.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSManagedObject+Conveniences.swift"; sourceTree = "<group>"; };
BF797A2C1C2D339F00F1A000 /* UILabel+FontSize.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UILabel+FontSize.swift"; sourceTree = "<group>"; };
BF7AE7FB1C2E857A00B1B5BC /* GridCollectionViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = GridCollectionViewCell.swift; path = "Delta/Pause Menu/Collection View/GridCollectionViewCell.swift"; sourceTree = SOURCE_ROOT; };
BF7AE7FC1C2E857A00B1B5BC /* GridCollectionViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = GridCollectionViewCell.xib; path = "Delta/Pause Menu/Collection View/GridCollectionViewCell.xib"; sourceTree = SOURCE_ROOT; };
BF7AE7FD1C2E857A00B1B5BC /* GridCollectionViewLayout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = GridCollectionViewLayout.swift; path = "Delta/Pause Menu/Collection View/GridCollectionViewLayout.swift"; sourceTree = SOURCE_ROOT; };
BF7AE8011C2E858400B1B5BC /* PausePresentationController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = PausePresentationController.swift; path = "Pause Menu/PausePresentationController.swift"; sourceTree = "<group>"; };
BF7AE8021C2E858400B1B5BC /* PausePresentationControllerContentView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = PausePresentationControllerContentView.xib; path = "Pause Menu/PausePresentationControllerContentView.xib"; sourceTree = "<group>"; };
BF7AE8031C2E858400B1B5BC /* PauseStoryboardSegue.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = PauseStoryboardSegue.swift; path = "Pause Menu/PauseStoryboardSegue.swift"; sourceTree = "<group>"; };
BF7AE8041C2E858400B1B5BC /* PauseViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = PauseViewController.swift; path = "Pause Menu/PauseViewController.swift"; sourceTree = "<group>"; };
BF9F4FCE1AAD7B87004C9500 /* DeltaCore.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = DeltaCore.framework; sourceTree = BUILT_PRODUCTS_DIR; };
BFA534291BDC6B520088F1BE /* GameCollectionViewLayout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = GameCollectionViewLayout.swift; path = "Collection View/GameCollectionViewLayout.swift"; sourceTree = "<group>"; };
BFAA1FEC1B8AA4FA00495943 /* Settings.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Settings.swift; sourceTree = "<group>"; };
@ -197,6 +213,7 @@
children = (
BF090CF21B490D8300DCAB45 /* UIDevice+Vibration.h */,
BF090CF31B490D8300DCAB45 /* UIDevice+Vibration.m */,
BF797A2C1C2D339F00F1A000 /* UILabel+FontSize.swift */,
);
path = Extensions;
sourceTree = "<group>";
@ -263,6 +280,18 @@
path = Extensions;
sourceTree = "<group>";
};
BF7AE7FA1C2E851F00B1B5BC /* Pause Menu */ = {
isa = PBXGroup;
children = (
BF7AE8041C2E858400B1B5BC /* PauseViewController.swift */,
BF7AE8031C2E858400B1B5BC /* PauseStoryboardSegue.swift */,
BF7AE8011C2E858400B1B5BC /* PausePresentationController.swift */,
BF7AE8021C2E858400B1B5BC /* PausePresentationControllerContentView.xib */,
BF9CB2261C2A025700E7D6C8 /* Collection View */,
);
name = "Pause Menu";
sourceTree = "<group>";
};
BF8624621BB7400E00C12EEE /* Supporting Files */ = {
isa = PBXGroup;
children = (
@ -282,6 +311,17 @@
name = "Collection View";
sourceTree = "<group>";
};
BF9CB2261C2A025700E7D6C8 /* Collection View */ = {
isa = PBXGroup;
children = (
BF7AE7FB1C2E857A00B1B5BC /* GridCollectionViewCell.swift */,
BF7AE7FC1C2E857A00B1B5BC /* GridCollectionViewCell.xib */,
BF7AE7FD1C2E857A00B1B5BC /* GridCollectionViewLayout.swift */,
);
name = "Collection View";
path = Emulation;
sourceTree = "<group>";
};
BF9F4FCD1AAD7B25004C9500 /* Frameworks */ = {
isa = PBXGroup;
children = (
@ -360,6 +400,7 @@
BFFA71E01AAC406100EE9DD1 /* Main.storyboard */,
BF46894D1AAC469800A2586D /* Game Selection */,
BFFB709D1AF99ACA00DE56FE /* Emulation */,
BF7AE7FA1C2E851F00B1B5BC /* Pause Menu */,
BFAA1FEB1B8AA4E800495943 /* Settings */,
BF090CEE1B490C1A00DCAB45 /* Extensions */,
BFFA71DA1AAC406100EE9DD1 /* Supporting Files */,
@ -495,8 +536,10 @@
buildActionMask = 2147483647;
files = (
BFFA71E21AAC406100EE9DD1 /* Main.storyboard in Resources */,
BF7AE8061C2E858400B1B5BC /* PausePresentationControllerContentView.xib in Resources */,
BFFA71E71AAC406100EE9DD1 /* LaunchScreen.xib in Resources */,
BF5E7F461B9A652600AE44F8 /* Settings.storyboard in Resources */,
BF7AE7FF1C2E857A00B1B5BC /* GridCollectionViewCell.xib in Resources */,
BF27CC8E1BC9FEA200A20D89 /* Assets.xcassets in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -628,8 +671,10 @@
BFAA1FED1B8AA4FA00495943 /* Settings.swift in Sources */,
BF50DC421BD851740024C720 /* GameCollectionViewCell.swift in Sources */,
BFB141181BE46934004FBF46 /* GameCollectionViewDataSource.swift in Sources */,
BF7AE8001C2E857A00B1B5BC /* GridCollectionViewLayout.swift in Sources */,
BFFB709F1AF99B1700DE56FE /* EmulationViewController.swift in Sources */,
BFAA1FF41B8AD7F900495943 /* ControllersSettingsViewController.swift in Sources */,
BF7AE8071C2E858400B1B5BC /* PauseStoryboardSegue.swift in Sources */,
BF27CC971BCC890700A20D89 /* GamesCollectionViewController.swift in Sources */,
BFFA71DD1AAC406100EE9DD1 /* AppDelegate.swift in Sources */,
BF4566E81BC090B6007BFA1A /* Model.xcdatamodeld in Sources */,
@ -641,10 +686,14 @@
BFA5342A1BDC6B520088F1BE /* GameCollectionViewLayout.swift in Sources */,
BF762E9E1BC19D31002C8866 /* DatabaseManager.swift in Sources */,
BF090CF41B490D8300DCAB45 /* UIDevice+Vibration.m in Sources */,
BF797A2D1C2D339F00F1A000 /* UILabel+FontSize.swift in Sources */,
BF107EC41BF413F000E0C32C /* GamesViewController.swift in Sources */,
BF5E7F441B9A650B00AE44F8 /* SettingsViewController.swift in Sources */,
BFDB28451BC9DA7B001D0C83 /* GamePickerController.swift in Sources */,
BF7AE8051C2E858400B1B5BC /* PausePresentationController.swift in Sources */,
BF7AE7FE1C2E857A00B1B5BC /* GridCollectionViewCell.swift in Sources */,
BFDE393A1BC0CEDF003F72E8 /* Game+CoreDataProperties.swift in Sources */,
BF7AE8081C2E858400B1B5BC /* PauseViewController.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View File

@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="9531" systemVersion="15B42" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="wKV-3d-NIY">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="9531" systemVersion="15C50" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="wKV-3d-NIY">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="9529"/>
<capability name="Constraints to layout margins" minToolsVersion="6.0"/>
<capability name="Segues with Peek and Pop" minToolsVersion="7.1"/>
</dependencies>
<scenes>
@ -151,12 +152,117 @@
<outlet property="controllerView" destination="2W1-IT-Y2l" id="WCa-LM-fXF"/>
<outlet property="controllerViewHeightConstraint" destination="PEV-zv-Buo" id="1jo-Kg-HpO"/>
<outlet property="gameView" destination="GfI-Mx-CQT" id="HmP-OA-mci"/>
<segue destination="YH4-Dy-8Mz" kind="presentation" identifier="pauseSegue" customClass="PauseStoryboardSegue" customModule="Delta" customModuleProvider="target" id="9cz-mr-lTk"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="ZYd-It-2t0" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="2361" y="1002"/>
</scene>
<!--Paused-->
<scene sceneID="upW-21-c6e">
<objects>
<viewController id="fjf-Kd-NY2" customClass="PauseViewController" customModule="Delta" customModuleProvider="target" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="T5g-dU-mk3"/>
<viewControllerLayoutGuide type="bottom" id="2VR-he-PMF"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="NYe-l8-jSy">
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<visualEffectView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="BTf-mZ-pVi" userLabel="Primary Blur View">
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
<view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" id="ahz-4E-cKV" userLabel="Content View">
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
</view>
<blurEffect style="dark"/>
</visualEffectView>
<visualEffectView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="t3G-Xl-Py3" userLabel="Secondary Blur View">
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
<view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" id="L1l-tg-4su" userLabel="Content View">
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
</view>
<blurEffect style="dark"/>
</visualEffectView>
<visualEffectView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Upx-pN-cZS" userLabel="Vibrancy View">
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
<view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" id="uto-dW-PGz" userLabel="Content View">
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<collectionView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" bounces="NO" scrollEnabled="NO" dataMode="prototypes" translatesAutoresizingMaskIntoConstraints="NO" id="Jf9-Zr-SU1">
<rect key="frame" x="0.0" y="64" width="600" height="536"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<collectionViewFlowLayout key="collectionViewLayout" minimumLineSpacing="20" minimumInteritemSpacing="10" id="0ze-Nw-POW" customClass="GridCollectionViewLayout" customModule="Delta" customModuleProvider="target">
<size key="itemSize" width="60" height="80"/>
<size key="headerReferenceSize" width="0.0" height="0.0"/>
<size key="footerReferenceSize" width="0.0" height="0.0"/>
<inset key="sectionInset" minX="0.0" minY="20" maxX="0.0" maxY="20"/>
</collectionViewFlowLayout>
<cells>
<collectionViewCell opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" reuseIdentifier="Cell" id="CkY-Fc-ejC" customClass="GridCollectionViewCell" customModule="Delta" customModuleProvider="target">
<rect key="frame" x="0.0" y="20" width="60" height="80"/>
<autoresizingMask key="autoresizingMask"/>
<view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
<rect key="frame" x="0.0" y="0.0" width="60" height="80"/>
<autoresizingMask key="autoresizingMask"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
</view>
</collectionViewCell>
</cells>
<connections>
<outlet property="dataSource" destination="fjf-Kd-NY2" id="NRE-Ov-Wbg"/>
<outlet property="delegate" destination="fjf-Kd-NY2" id="QvV-VK-NvJ"/>
</connections>
</collectionView>
</subviews>
<constraints>
<constraint firstAttribute="trailing" secondItem="Jf9-Zr-SU1" secondAttribute="trailing" id="7h7-Xl-xbW"/>
<constraint firstAttribute="bottom" secondItem="Jf9-Zr-SU1" secondAttribute="bottom" id="IgH-PB-Yzm"/>
<constraint firstItem="Jf9-Zr-SU1" firstAttribute="leading" secondItem="uto-dW-PGz" secondAttribute="leading" id="i9D-1X-Yhj"/>
</constraints>
</view>
<vibrancyEffect>
<blurEffect style="dark"/>
</vibrancyEffect>
</visualEffectView>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<constraints>
<constraint firstItem="2VR-he-PMF" firstAttribute="top" secondItem="Upx-pN-cZS" secondAttribute="bottom" id="8W2-gK-LrU"/>
<constraint firstAttribute="trailing" secondItem="t3G-Xl-Py3" secondAttribute="trailing" id="BQm-tm-M9Y"/>
<constraint firstAttribute="trailing" secondItem="BTf-mZ-pVi" secondAttribute="trailing" id="JsO-WV-IPw"/>
<constraint firstItem="2VR-he-PMF" firstAttribute="top" secondItem="t3G-Xl-Py3" secondAttribute="bottom" id="Km2-jS-OMy"/>
<constraint firstAttribute="trailing" secondItem="Upx-pN-cZS" secondAttribute="trailing" id="PH2-3f-qvK"/>
<constraint firstItem="t3G-Xl-Py3" firstAttribute="top" secondItem="NYe-l8-jSy" secondAttribute="top" id="Pkn-IN-rIR"/>
<constraint firstItem="2VR-he-PMF" firstAttribute="top" secondItem="BTf-mZ-pVi" secondAttribute="bottom" id="Se6-cn-A1N"/>
<constraint firstItem="BTf-mZ-pVi" firstAttribute="top" secondItem="NYe-l8-jSy" secondAttribute="topMargin" id="XDR-Tz-YCv"/>
<constraint firstItem="Upx-pN-cZS" firstAttribute="top" secondItem="NYe-l8-jSy" secondAttribute="top" id="cJx-jw-3g2"/>
<constraint firstItem="t3G-Xl-Py3" firstAttribute="leading" secondItem="NYe-l8-jSy" secondAttribute="leading" id="ep2-LW-5zZ"/>
<constraint firstItem="Upx-pN-cZS" firstAttribute="leading" secondItem="NYe-l8-jSy" secondAttribute="leading" id="gSn-qK-jOM"/>
<constraint firstItem="BTf-mZ-pVi" firstAttribute="leading" secondItem="NYe-l8-jSy" secondAttribute="leading" id="nNM-74-jgo"/>
<constraint firstItem="Jf9-Zr-SU1" firstAttribute="top" secondItem="T5g-dU-mk3" secondAttribute="bottom" id="xj3-As-as0"/>
</constraints>
</view>
<navigationItem key="navigationItem" title="Paused" id="hbg-6F-GRq">
<barButtonItem key="rightBarButtonItem" style="done" systemItem="done" id="ye0-Nk-K1X">
<connections>
<segue destination="mTB-5a-Mdf" kind="unwind" unwindAction="unwindFromPauseViewController:" id="OIW-2I-L70"/>
</connections>
</barButtonItem>
</navigationItem>
<connections>
<outlet property="collectionView" destination="Jf9-Zr-SU1" id="TIj-CV-wIi"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="LbR-MM-KOb" userLabel="First Responder" sceneMemberID="firstResponder"/>
<exit id="mTB-5a-Mdf" userLabel="Exit" sceneMemberID="exit"/>
</objects>
<point key="canvasLocation" x="3024" y="1717"/>
</scene>
<!--Page View Controller-->
<scene sceneID="35q-Io-64T">
<objects>
@ -196,6 +302,24 @@
</objects>
<point key="canvasLocation" x="400" y="1002"/>
</scene>
<!--Navigation Controller-->
<scene sceneID="Xcw-k0-Icf">
<objects>
<navigationController automaticallyAdjustsScrollViewInsets="NO" id="YH4-Dy-8Mz" sceneMemberID="viewController">
<toolbarItems/>
<navigationBar key="navigationBar" contentMode="scaleToFill" barStyle="black" id="wGs-6t-cPo">
<rect key="frame" x="0.0" y="0.0" width="320" height="44"/>
<autoresizingMask key="autoresizingMask"/>
</navigationBar>
<nil name="viewControllers"/>
<connections>
<segue destination="fjf-Kd-NY2" kind="relationship" relationship="rootViewController" id="Oi6-bM-ZSf"/>
</connections>
</navigationController>
<placeholder placeholderIdentifier="IBFirstResponder" id="GG6-6X-waQ" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="2361" y="1717"/>
</scene>
</scenes>
<resources>
<image name="Settings_Button" width="22" height="22"/>

View File

@ -121,8 +121,47 @@ class EmulationViewController: UIViewController
}
}
//MARK: - Controllers -
/// Controllers
// MARK: - Navigation -
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
{
self.emulatorCore.pauseEmulation()
if segue.identifier == "pauseSegue"
{
if let destinationViewController = segue.destinationViewController as? UINavigationController, pauseViewController = destinationViewController.topViewController as? PauseViewController
{
pauseViewController.pauseText = self.game.name
}
}
}
@IBAction func unwindFromPauseViewController(segue: UIStoryboardSegue)
{
self.emulatorCore.resumeEmulation()
}
//MARK: - 3D Touch -
/// 3D Touch
override func previewActionItems() -> [UIPreviewActionItem]
{
let presentingViewController = self.presentingViewController
let launchGameAction = UIPreviewAction(title: NSLocalizedString("Launch \(self.game.name)", comment: ""), style: .Default) { (action, viewController) in
// Delaying until next run loop prevents self from being dismissed immediately
dispatch_async(dispatch_get_main_queue()) {
presentingViewController?.presentViewController(viewController, animated: true, completion: nil)
}
}
return [launchGameAction]
}
}
//MARK: - Controllers -
/// Controllers
private extension EmulationViewController
{
func updateControllers()
{
self.emulatorCore.removeAllGameControllers()
@ -142,21 +181,6 @@ class EmulationViewController: UIViewController
self.view.setNeedsLayout()
}
//MARK: - 3D Touch -
/// 3D Touch
override func previewActionItems() -> [UIPreviewActionItem]
{
let presentingViewController = self.presentingViewController
let launchGameAction = UIPreviewAction(title: NSLocalizedString("Launch \(self.game.name)", comment: ""), style: .Default) { (action, viewController) in
// Delaying until next run loop prevents self from being dismissed immediately
dispatch_async(dispatch_get_main_queue()) {
presentingViewController?.presentViewController(viewController, animated: true, completion: nil)
}
}
return [launchGameAction]
}
}
//MARK: - <GameControllerReceiver> -
@ -173,6 +197,11 @@ extension EmulationViewController: GameControllerReceiverType
guard let input = input as? ControllerInput else { return }
print("Activated \(input)")
switch input
{
case ControllerInput.Menu: self.performSegueWithIdentifier("pauseSegue", sender: gameController)
}
}
func gameController(gameController: GameControllerType, didDeactivateInput input: InputType)

View File

@ -0,0 +1,28 @@
//
// UILabel+FontSize.swift
// Delta
//
// Created by Riley Testut on 12/25/15.
// Copyright © 2015 Riley Testut. All rights reserved.
//
import UIKit
internal extension UILabel
{
var currentScaleFactor: CGFloat
{
guard let text = self.text else { return 1.0 }
let context = NSStringDrawingContext()
context.minimumScaleFactor = self.minimumScaleFactor
// Using self.attributedString returns incorrect calculations, so we create our own attributed string
let attributedString = NSAttributedString(string: text, attributes: [NSFontAttributeName: self.font])
attributedString.boundingRectWithSize(self.bounds.size, options: [.UsesLineFragmentOrigin, .UsesFontLeading], context: context)
let scaleFactor = context.actualScaleFactor
return scaleFactor
}
}

View File

@ -0,0 +1,105 @@
//
// GridCollectionViewCell.swift
// Delta
//
// Created by Riley Testut on 10/21/15.
// Copyright © 2015 Riley Testut. All rights reserved.
//
import UIKit
class GridCollectionViewCell: UICollectionViewCell
{
@IBOutlet private(set) var imageView: UIImageView!
@IBOutlet private(set) var textLabel: UILabel!
var maximumImageSize: CGSize = CGSize(width: 100, height: 100) {
didSet {
self.updateMaximumImageSize()
}
}
@IBOutlet private var imageViewWidthConstraint: NSLayoutConstraint!
@IBOutlet private var imageViewHeightConstraint: NSLayoutConstraint!
@IBOutlet private var textLabelBottomAnchorConstraint: NSLayoutConstraint!
@IBOutlet private var textLabelVerticalSpacingConstraint: NSLayoutConstraint!
private var textLabelFocusedVerticalSpacingConstraint: NSLayoutConstraint?
override func awakeFromNib()
{
super.awakeFromNib()
// Fix super annoying Unsatisfiable Constraints message in debugger by setting autoresizingMask
self.contentView.autoresizingMask = [.FlexibleWidth, .FlexibleHeight]
self.imageView.translatesAutoresizingMaskIntoConstraints = false
#if os(tvOS)
self.imageView.adjustsImageWhenAncestorFocused = true
#endif
self.contentView.addSubview(self.imageView)
self.textLabel.translatesAutoresizingMaskIntoConstraints = false
self.textLabel.font = UIFont.boldSystemFontOfSize(12)
self.textLabel.textAlignment = .Center
self.textLabel.numberOfLines = 0
self.contentView.addSubview(self.textLabel)
// Auto Layout
#if os(tvOS)
self.textLabelVerticalSpacingConstraint.active = false
self.textLabelFocusedVerticalSpacingConstraint = self.textLabel.topAnchor.constraintEqualToAnchor(self.imageView.focusedFrameGuide.bottomAnchor, constant: verticalSpacingConstant)
self.textLabelFocusedVerticalSpacingConstraint?.active = true
#else
self.textLabelVerticalSpacingConstraint.active = true
#endif
self.updateMaximumImageSize()
}
override func didUpdateFocusInContext(context: UIFocusUpdateContext, withAnimationCoordinator coordinator: UIFocusAnimationCoordinator)
{
super.didUpdateFocusInContext(context, withAnimationCoordinator: coordinator)
coordinator.addCoordinatedAnimations({
if context.nextFocusedView == self
{
self.textLabelBottomAnchorConstraint?.active = false
self.textLabelVerticalSpacingConstraint.active = false
self.textLabelFocusedVerticalSpacingConstraint?.active = true
self.textLabel.textColor = UIColor.whiteColor()
}
else
{
self.textLabelFocusedVerticalSpacingConstraint?.active = false
self.textLabelBottomAnchorConstraint?.active = true
self.textLabelVerticalSpacingConstraint.active = true
self.textLabel.textColor = UIColor.blackColor()
}
self.layoutIfNeeded()
}, completion: nil)
}
}
private extension GridCollectionViewCell
{
func updateMaximumImageSize()
{
self.imageViewWidthConstraint.constant = self.maximumImageSize.width
self.imageViewHeightConstraint.constant = self.maximumImageSize.height
self.textLabelVerticalSpacingConstraint.constant = self.maximumImageSize.height / 10.0
self.textLabelFocusedVerticalSpacingConstraint?.constant = self.maximumImageSize.height / 10.0
}
}

View File

@ -0,0 +1,51 @@
<?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">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="9529"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<collectionViewCell opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" id="n6R-hD-aNv" customClass="GridCollectionViewCell" customModule="Delta" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="150" height="115"/>
<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="150" height="115"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="lky-CJ-5CM">
<rect key="frame" x="25" y="0.0" width="100" height="100"/>
<constraints>
<constraint firstAttribute="height" constant="100" id="PiQ-26-wMh"/>
<constraint firstAttribute="width" constant="100" id="xR5-SN-due"/>
</constraints>
</imageView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Test Label" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="M6I-0c-ddJ">
<rect key="frame" x="0.0" y="100" width="150" height="15"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="12"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
</view>
<constraints>
<constraint firstAttribute="trailing" secondItem="M6I-0c-ddJ" secondAttribute="trailing" id="1QY-4w-9Ye"/>
<constraint firstItem="M6I-0c-ddJ" firstAttribute="leading" secondItem="n6R-hD-aNv" secondAttribute="leading" id="3wf-gY-fwo"/>
<constraint firstAttribute="bottom" secondItem="M6I-0c-ddJ" secondAttribute="bottom" id="DKB-Hm-thj"/>
<constraint firstAttribute="trailing" secondItem="M6I-0c-ddJ" secondAttribute="trailing" id="K2f-LJ-dAT"/>
<constraint firstItem="lky-CJ-5CM" firstAttribute="top" secondItem="n6R-hD-aNv" secondAttribute="top" id="MaM-Sw-igX"/>
<constraint firstItem="M6I-0c-ddJ" firstAttribute="leading" secondItem="n6R-hD-aNv" secondAttribute="leading" id="O91-X2-BeC"/>
<constraint firstItem="lky-CJ-5CM" firstAttribute="centerX" secondItem="n6R-hD-aNv" secondAttribute="centerX" id="VLv-hn-k8b"/>
<constraint firstItem="M6I-0c-ddJ" firstAttribute="top" secondItem="lky-CJ-5CM" secondAttribute="bottom" id="mdf-No-2YV"/>
</constraints>
<connections>
<outlet property="imageView" destination="lky-CJ-5CM" id="ITm-Jd-Mjd"/>
<outlet property="imageViewHeightConstraint" destination="PiQ-26-wMh" id="Oeb-Pb-Vfs"/>
<outlet property="imageViewWidthConstraint" destination="xR5-SN-due" id="Igw-6S-zjZ"/>
<outlet property="textLabel" destination="M6I-0c-ddJ" id="JqT-rT-YCa"/>
<outlet property="textLabelBottomAnchorConstraint" destination="DKB-Hm-thj" id="zr7-PW-0op"/>
<outlet property="textLabelVerticalSpacingConstraint" destination="mdf-No-2YV" id="46C-fS-uDm"/>
</connections>
</collectionViewCell>
</objects>
</document>

View File

@ -0,0 +1,121 @@
//
// GridCollectionViewLayout.swift
// Delta
//
// Created by Riley Testut on 10/24/15.
// Copyright © 2015 Riley Testut. All rights reserved.
//
import UIKit
class GridCollectionViewLayout: UICollectionViewFlowLayout
{
var itemWidth: CGFloat = 150 {
didSet {
self.invalidateLayout()
}
}
// If only one row, distribute the items equally horizontally
var usesEqualHorizontalSpacingDistributionForSingleRow = false
override var estimatedItemSize: CGSize {
didSet {
fatalError("GridCollectionViewLayout does not support self-sizing cells.")
}
}
override func layoutAttributesForElementsInRect(rect: CGRect) -> [UICollectionViewLayoutAttributes]?
{
guard let collectionView = self.collectionView else { return nil }
let maximumItemsPerRow = floor((collectionView.bounds.width - self.minimumInteritemSpacing) / (self.itemWidth + self.minimumInteritemSpacing))
let interitemSpacing = (collectionView.bounds.width - maximumItemsPerRow * self.itemWidth) / (maximumItemsPerRow + 1)
self.sectionInset.left = interitemSpacing
self.sectionInset.right = interitemSpacing
let layoutAttributes = super.layoutAttributesForElementsInRect(rect)?.map({ $0.copy() }) as! [UICollectionViewLayoutAttributes]
var minimumY: CGFloat? = nil
var maximumY: CGFloat? = nil
var tempLayoutAttributes: [UICollectionViewLayoutAttributes] = []
var isSingleRow = true
for (index, attributes) in layoutAttributes.enumerate()
{
// Ensure equal spacing between items (that also match the section insets)
if index > 0
{
let previousLayoutAttributes = layoutAttributes[index - 1]
if abs(attributes.frame.minX - self.sectionInset.left) > 1
{
attributes.frame.origin.x = previousLayoutAttributes.frame.maxX + interitemSpacing
}
}
if let maxY = maximumY, minY = minimumY
{
// If attributes.frame.minY is greater than maximumY, then it is a new row
// In this case, we need to align all the previous tempLayoutAttributes to the same Y-value
if attributes.frame.minY > maxY
{
isSingleRow = false
self.alignLayoutAttributes(tempLayoutAttributes, toMinimumY: minY)
// Reset tempLayoutAttributes
tempLayoutAttributes.removeAll()
minimumY = nil
maximumY = nil
}
}
// Update minimumY value if needed
if minimumY == nil || attributes.frame.minY < minimumY!
{
minimumY = attributes.frame.minY
}
// Update maximumY value if needed
if maximumY == nil || attributes.frame.maxY > maximumY!
{
maximumY = attributes.frame.maxY
}
tempLayoutAttributes.append(attributes)
}
// Handle the remaining tempLayoutAttributes
if let minimumY = minimumY
{
self.alignLayoutAttributes(tempLayoutAttributes, toMinimumY: minimumY)
if isSingleRow && self.usesEqualHorizontalSpacingDistributionForSingleRow
{
let spacing = (collectionView.bounds.width - (self.itemWidth * CGFloat(tempLayoutAttributes.count))) / (CGFloat(tempLayoutAttributes.count) + 1.0)
for (index, layoutAttributes) in tempLayoutAttributes.enumerate()
{
layoutAttributes.frame.origin.x = spacing + (spacing + self.itemWidth) * CGFloat(index)
}
}
}
return layoutAttributes
}
}
private extension GridCollectionViewLayout
{
func alignLayoutAttributes(layoutAttributes: [UICollectionViewLayoutAttributes], toMinimumY minimumY: CGFloat)
{
for attributes in layoutAttributes
{
attributes.frame.origin.y = minimumY
}
}
}

View File

@ -0,0 +1,178 @@
//
// PausePresentationController.swift
// Delta
//
// Created by Riley Testut on 12/21/15.
// Copyright © 2015 Riley Testut. All rights reserved.
//
import UIKit
import Roxas
protocol PauseInfoProvidable
{
var pauseText: String? { get }
}
class PausePresentationController: UIPresentationController
{
private let blurringView: UIVisualEffectView
private let vibrancyView: UIVisualEffectView
private var contentView: UIView!
@IBOutlet private weak var pauseLabel: UILabel!
@IBOutlet private weak var pauseIconImageView: UIImageView!
@IBOutlet private weak var stackView: UIStackView!
override init(presentedViewController: UIViewController, presentingViewController: UIViewController)
{
self.blurringView = UIVisualEffectView(effect: nil)
self.vibrancyView = UIVisualEffectView(effect: nil)
super.init(presentedViewController: presentedViewController, presentingViewController: presentingViewController)
self.contentView = NSBundle.mainBundle().loadNibNamed("PausePresentationControllerContentView", owner: self, options: nil).first as! UIView
}
override func frameOfPresentedViewInContainerView() -> CGRect
{
guard let containerView = self.containerView else { return super.frameOfPresentedViewInContainerView() }
let contentHeight: CGFloat
if let navigationController = self.presentedViewController as? UINavigationController, topViewController = navigationController.topViewController
{
contentHeight = topViewController.preferredContentSize.height + navigationController.navigationBar.bounds.height
}
else
{
contentHeight = self.presentedViewController.preferredContentSize.height
}
let frame = CGRect(x: 0, y: containerView.bounds.height - contentHeight, width: containerView.bounds.width, height: containerView.bounds.height)
return frame
}
override func presentationTransitionWillBegin()
{
if let provider = self.presentedViewController as? PauseInfoProvidable
{
self.pauseLabel.text = provider.pauseText
}
else if let navigationController = self.presentedViewController as? UINavigationController, provider = navigationController.topViewController as? PauseInfoProvidable
{
self.pauseLabel.text = provider.pauseText
}
else
{
self.pauseLabel.text = nil
}
self.blurringView.frame = self.containerView!.frame
self.blurringView.autoresizingMask = [.FlexibleWidth, .FlexibleHeight]
self.containerView?.addSubview(self.blurringView)
self.vibrancyView.frame = self.containerView!.frame
self.vibrancyView.autoresizingMask = [.FlexibleWidth, .FlexibleHeight]
self.containerView?.addSubview(self.vibrancyView)
self.contentView.alpha = 0.0
self.vibrancyView.contentView.addSubview(self.contentView)
self.presentingViewController.transitionCoordinator()?.animateAlongsideTransition({ context in
let blurEffect = UIBlurEffect(style: .Dark)
self.blurringView.effect = blurEffect
self.vibrancyView.effect = UIVibrancyEffect(forBlurEffect: blurEffect)
self.contentView.alpha = 1.0
}, completion: nil)
}
override func dismissalTransitionWillBegin()
{
self.presentingViewController.transitionCoordinator()?.animateAlongsideTransition({ context in
self.blurringView.effect = nil
self.vibrancyView.effect = nil
self.contentView.alpha = 0.0
}, completion: nil)
}
override func dismissalTransitionDidEnd(completed: Bool)
{
self.blurringView.removeFromSuperview()
self.vibrancyView.removeFromSuperview()
}
override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator)
{
super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator)
// Super super hacky, but the system for some reason tries to layout the view in a (slightly) smaller space, which sometimes breaks constraints
// To fix this, we ensure there is enough room for the constraints to be valid temporarily, and then the frame will be fixed in containerViewDidLayoutSubviews()
let currentY = self.contentView.frame.minY
self.contentView.frame = self.containerView!.bounds
self.contentView.frame.origin.y = currentY
}
override func containerViewDidLayoutSubviews()
{
super.containerViewDidLayoutSubviews()
// Magical calculations. If you edit ANY of them, you have to make sure everything still lays out correctly on *all* devices
// So, I'd recommend that you not touch this :)
/* Hacky Layout Bug Workaround */
// For some reason, attempting to calculate the layout while contentView is in the view hierarchy doesn't properly follow constraint priorities exactly
// Specifically, on 5s with long pause label text, it will sometimes resize the text before the image, or it will not resize the image enough for the size class
self.contentView.removeFromSuperview()
// Temporarily match the bounds of self.containerView (accounting for the status bar)
let statusBarHeight = UIApplication.sharedApplication().statusBarFrame.height
self.contentView.frame = CGRect(x: 0, y: statusBarHeight, width: self.containerView!.bounds.width, height: self.containerView!.bounds.height - statusBarHeight)
// Layout content view
self.contentView.setNeedsLayout()
self.contentView.layoutIfNeeded()
// Add back to the view hierarchy
self.vibrancyView.contentView.addSubview(self.contentView)
/* Resume Normal Calculations */
// Ensure width is correct
self.presentedView()?.bounds.size.width = self.containerView!.bounds.width
self.presentedView()?.layoutIfNeeded()
self.presentedView()?.frame = self.frameOfPresentedViewInContainerView()
// Unhide pauseIconImageView so its height is involved with layout calculations
self.pauseIconImageView.hidden = false
self.contentView.frame = CGRect(x: 0, y: statusBarHeight, width: self.containerView!.bounds.width, height: self.frameOfPresentedViewInContainerView().minY - statusBarHeight)
self.contentView.setNeedsLayout() // Ensures that layout will actually occur (sometimes the system thinks a layout is not needed, which messes up calculations)
self.contentView.layoutIfNeeded()
let currentScaleFactor = self.pauseLabel.currentScaleFactor
if currentScaleFactor < self.pauseLabel.minimumScaleFactor || CGFloatEqualToFloat(currentScaleFactor, self.pauseLabel.minimumScaleFactor)
{
self.pauseIconImageView.hidden = true
}
else
{
self.pauseIconImageView.hidden = false
}
self.contentView.setNeedsLayout() // Ensures that layout will actually occur (sometimes the system thinks a layout is not needed, which messes up calculations)
self.contentView.layoutIfNeeded()
}
}

View File

@ -0,0 +1,54 @@
<?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">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="9529"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="PausePresentationController" customModule="Delta" customModuleProvider="target">
<connections>
<outlet property="pauseIconImageView" destination="cWa-Ht-i5m" id="fBb-zu-cQ6"/>
<outlet property="pauseLabel" destination="ZcT-qE-aES" id="kvN-V0-xNs"/>
<outlet property="stackView" destination="qFz-hB-77X" id="iFf-RU-KVB"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="iN0-l3-epB">
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
<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"/>
<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"/>
<constraints>
<constraint firstAttribute="height" relation="greaterThanOrEqual" priority="900" constant="44" id="xki-9P-sHi">
<variation key="heightClass=compact" constant="25"/>
</constraint>
</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"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleTitle1"/>
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</stackView>
</subviews>
<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="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"/>
</constraints>
<nil key="simulatedStatusBarMetrics"/>
<point key="canvasLocation" x="393" y="426"/>
</view>
</objects>
<resources>
<image name="Pause" width="64" height="80"/>
</resources>
</document>

View File

@ -0,0 +1,79 @@
//
// PauseStoryboardSegue.swift
// Delta
//
// Created by Riley Testut on 12/21/15.
// Copyright © 2015 Riley Testut. All rights reserved.
//
import UIKit
class PauseStoryboardSegue: UIStoryboardSegue
{
private let presentationController: PausePresentationController
override init(identifier: String?, source: UIViewController, destination: UIViewController)
{
self.presentationController = PausePresentationController(presentedViewController: destination, presentingViewController: source)
super.init(identifier: identifier, source: source, destination: destination)
}
override func perform()
{
self.destinationViewController.transitioningDelegate = self
self.destinationViewController.modalPresentationStyle = .Custom
self.destinationViewController.modalPresentationCapturesStatusBarAppearance = true
super.perform()
}
}
extension PauseStoryboardSegue: UIViewControllerTransitioningDelegate
{
func animationControllerForPresentedController(presented: UIViewController, presentingController presenting: UIViewController, sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning?
{
return self
}
func animationControllerForDismissedController(dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning?
{
return nil
}
func presentationControllerForPresentedViewController(presentedViewController: UIViewController, presentingViewController: UIViewController, sourceViewController source: UIViewController) -> UIPresentationController?
{
return self.presentationController
}
}
extension PauseStoryboardSegue: UIViewControllerAnimatedTransitioning
{
func transitionDuration(transitionContext: UIViewControllerContextTransitioning?) -> NSTimeInterval
{
return 0.65
}
func animateTransition(transitionContext: UIViewControllerContextTransitioning)
{
let destinationViewController = transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey) as! UINavigationController
destinationViewController.view.frame = transitionContext.finalFrameForViewController(destinationViewController)
destinationViewController.view.frame.origin.y = transitionContext.containerView()!.bounds.height
transitionContext.containerView()!.addSubview(destinationViewController.view)
UIView.animateWithDuration(self.transitionDuration(transitionContext), delay: 0.0, usingSpringWithDamping: 0.7, initialSpringVelocity: 0.0, options: [], animations: {
// Calling layoutIfNeeded before the animation block for some reason prevents the blur from fading in
// Additionally, if it's animated, it looks weird
// So we need to wrap it in a no-animation block, inside an animation block. Blech.
UIView.performWithoutAnimation({
destinationViewController.view.layoutIfNeeded()
})
destinationViewController.view.frame = self.presentationController.frameOfPresentedViewInContainerView()
}, completion: { finished in
transitionContext.completeTransition(finished)
})
}
}

View File

@ -0,0 +1,111 @@
//
// PauseViewController.swift
// Delta
//
// Created by Riley Testut on 12/21/15.
// Copyright © 2015 Riley Testut. All rights reserved.
//
import UIKit
struct PauseItem
{
let image: UIImage
let text: String
let action: (PauseItem -> Void)
}
class PauseViewController: UIViewController, PauseInfoProvidable
{
var items = [PauseItem]() {
didSet {
if self.items.count > 8
{
fatalError("PauseViewController only supports up to 8 items (for my sanity when laying out on a landscape iPhone 4s")
}
self.collectionView?.reloadData()
}
}
var pauseText: String? = nil
override var preferredContentSize: CGSize {
set { }
get { return self.collectionView.contentSize }
}
@IBOutlet private(set) var collectionView: UICollectionView!
private var collectionViewLayout: GridCollectionViewLayout {
return self.collectionView.collectionViewLayout as! GridCollectionViewLayout
}
private var prototypeCell: GridCollectionViewCell = {
let nib = UINib(nibName: "GridCollectionViewCell", bundle: nil)
return nib.instantiateWithOwner(nil, options: nil).first as! GridCollectionViewCell
}()
override func preferredStatusBarStyle() -> UIStatusBarStyle
{
return .LightContent
}
override func viewDidLoad()
{
super.viewDidLoad()
let nib = UINib(nibName: "GridCollectionViewCell", bundle: nil)
self.collectionView.registerNib(nib, forCellWithReuseIdentifier: "Cell")
self.collectionViewLayout.itemWidth = 90
self.collectionViewLayout.usesEqualHorizontalSpacingDistributionForSingleRow = true
// Manually update prototype cell properties
self.prototypeCell.contentView.widthAnchor.constraintEqualToConstant(self.collectionViewLayout.itemWidth).active = true
let pauseItem = PauseItem(image: UIImage(named: "Pause")!, text: "Resume", action: { _ in })
self.items = [pauseItem, pauseItem, pauseItem, pauseItem, pauseItem, pauseItem]
}
}
private extension PauseViewController
{
func configureCollectionViewCell(cell: GridCollectionViewCell, forIndexPath indexPath: NSIndexPath)
{
let array = ["Save State", "Load State", "Cheat Codes", "Fast Forward", "Sustain Button", "Event Distribution"]
cell.maximumImageSize = CGSize(width: 60, height: 60)
cell.imageView.layer.borderWidth = 2
cell.imageView.layer.borderColor = UIColor.whiteColor().CGColor
cell.imageView.layer.cornerRadius = 10
cell.textLabel.text = array[indexPath.item]
cell.textLabel.textColor = UIColor.whiteColor()
}
}
extension PauseViewController: UICollectionViewDataSource, UICollectionViewDelegateFlowLayout
{
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
{
return self.items.count
}
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell
{
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("Cell", forIndexPath: indexPath) as! GridCollectionViewCell
self.configureCollectionViewCell(cell, forIndexPath: indexPath)
return cell
}
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize
{
self.configureCollectionViewCell(self.prototypeCell, forIndexPath: indexPath)
let size = self.prototypeCell.contentView.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize)
return size
}
}

2
External/Roxas vendored

@ -1 +1 @@
Subproject commit 12973b60eeddd6e5b3b398d5ec5b2dadd461810d
Subproject commit 325d2c786bcb9cc61389257023399282e1d8071d

View File

@ -0,0 +1,26 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "Pause.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "Pause@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "Pause@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
},
"properties" : {
"template-rendering-intent" : "template"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 330 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 941 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB