Added basic PauseViewController implementation
Also, happy Boxing Day! Hope you're enjoying your new iPad Pro future Riley :)
This commit is contained in:
parent
755266f393
commit
8f572fd1c8
@ -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;
|
||||
};
|
||||
|
||||
@ -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"/>
|
||||
|
||||
@ -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)
|
||||
|
||||
28
Delta/Extensions/UILabel+FontSize.swift
Normal file
28
Delta/Extensions/UILabel+FontSize.swift
Normal 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
|
||||
}
|
||||
}
|
||||
|
||||
105
Delta/Pause Menu/Collection View/GridCollectionViewCell.swift
Normal file
105
Delta/Pause Menu/Collection View/GridCollectionViewCell.swift
Normal 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
|
||||
}
|
||||
}
|
||||
51
Delta/Pause Menu/Collection View/GridCollectionViewCell.xib
Normal file
51
Delta/Pause Menu/Collection View/GridCollectionViewCell.xib
Normal 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>
|
||||
121
Delta/Pause Menu/Collection View/GridCollectionViewLayout.swift
Normal file
121
Delta/Pause Menu/Collection View/GridCollectionViewLayout.swift
Normal 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
|
||||
}
|
||||
}
|
||||
}
|
||||
178
Delta/Pause Menu/PausePresentationController.swift
Normal file
178
Delta/Pause Menu/PausePresentationController.swift
Normal 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()
|
||||
}
|
||||
}
|
||||
54
Delta/Pause Menu/PausePresentationControllerContentView.xib
Normal file
54
Delta/Pause Menu/PausePresentationControllerContentView.xib
Normal 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>
|
||||
79
Delta/Pause Menu/PauseStoryboardSegue.swift
Normal file
79
Delta/Pause Menu/PauseStoryboardSegue.swift
Normal 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)
|
||||
})
|
||||
}
|
||||
}
|
||||
111
Delta/Pause Menu/PauseViewController.swift
Normal file
111
Delta/Pause Menu/PauseViewController.swift
Normal 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
2
External/Roxas
vendored
@ -1 +1 @@
|
||||
Subproject commit 12973b60eeddd6e5b3b398d5ec5b2dadd461810d
|
||||
Subproject commit 325d2c786bcb9cc61389257023399282e1d8071d
|
||||
26
Resources/Assets.xcassets/Pause.imageset/Contents.json
vendored
Normal file
26
Resources/Assets.xcassets/Pause.imageset/Contents.json
vendored
Normal 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"
|
||||
}
|
||||
}
|
||||
BIN
Resources/Assets.xcassets/Pause.imageset/Pause.png
vendored
Normal file
BIN
Resources/Assets.xcassets/Pause.imageset/Pause.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 330 B |
BIN
Resources/Assets.xcassets/Pause.imageset/Pause@2x.png
vendored
Normal file
BIN
Resources/Assets.xcassets/Pause.imageset/Pause@2x.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 941 B |
BIN
Resources/Assets.xcassets/Pause.imageset/Pause@3x.png
vendored
Normal file
BIN
Resources/Assets.xcassets/Pause.imageset/Pause@3x.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.6 KiB |
Loading…
Reference in New Issue
Block a user