mirror of
https://github.com/SideStore/SideStore.git
synced 2026-02-09 06:43:25 +01:00
Revises Browse UI
This commit is contained in:
@@ -1,9 +1,9 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14868" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="wKh-xq-NuP">
|
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="15400" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="wKh-xq-NuP">
|
||||||
<device id="retina4_7" orientation="portrait" appearance="light"/>
|
<device id="retina4_7" orientation="portrait" appearance="light"/>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<deployment identifier="iOS"/>
|
<deployment identifier="iOS"/>
|
||||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14824"/>
|
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15404"/>
|
||||||
<capability name="Named colors" minToolsVersion="9.0"/>
|
<capability name="Named colors" minToolsVersion="9.0"/>
|
||||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||||
<capability name="Stack View standard spacing" minToolsVersion="9.0"/>
|
<capability name="Stack View standard spacing" minToolsVersion="9.0"/>
|
||||||
@@ -56,11 +56,11 @@
|
|||||||
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||||
<collectionViewFlowLayout key="collectionViewLayout" minimumLineSpacing="0.0" minimumInteritemSpacing="10" id="e0H-IH-rng">
|
<collectionViewFlowLayout key="collectionViewLayout" minimumLineSpacing="50" minimumInteritemSpacing="10" id="e0H-IH-rng">
|
||||||
<size key="itemSize" width="375" height="400"/>
|
<size key="itemSize" width="375" height="400"/>
|
||||||
<size key="headerReferenceSize" width="0.0" height="0.0"/>
|
<size key="headerReferenceSize" width="0.0" height="0.0"/>
|
||||||
<size key="footerReferenceSize" width="0.0" height="0.0"/>
|
<size key="footerReferenceSize" width="0.0" height="0.0"/>
|
||||||
<inset key="sectionInset" minX="0.0" minY="0.0" maxX="0.0" maxY="0.0"/>
|
<inset key="sectionInset" minX="0.0" minY="8" maxX="0.0" maxY="20"/>
|
||||||
</collectionViewFlowLayout>
|
</collectionViewFlowLayout>
|
||||||
<cells/>
|
<cells/>
|
||||||
<connections>
|
<connections>
|
||||||
@@ -703,24 +703,24 @@ World</string>
|
|||||||
</constraints>
|
</constraints>
|
||||||
</imageView>
|
</imageView>
|
||||||
<stackView opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="100" axis="vertical" alignment="top" spacing="2" translatesAutoresizingMaskIntoConstraints="NO" id="7iy-Zp-LEj">
|
<stackView opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="100" axis="vertical" alignment="top" spacing="2" translatesAutoresizingMaskIntoConstraints="NO" id="7iy-Zp-LEj">
|
||||||
<rect key="frame" x="71" y="12" width="203" height="36"/>
|
<rect key="frame" x="71" y="4" width="203" height="52"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<stackView opaque="NO" contentMode="scaleToFill" spacing="6" translatesAutoresizingMaskIntoConstraints="NO" id="MRz-3W-aTM">
|
<stackView opaque="NO" contentMode="scaleToFill" spacing="6" translatesAutoresizingMaskIntoConstraints="NO" id="MRz-3W-aTM">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="85" height="18"/>
|
<rect key="frame" x="0.0" y="0.0" width="126" height="34"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="100" verticalHuggingPriority="251" horizontalCompressionResistancePriority="500" text="Short" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Nhl-6I-9gW">
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="100" verticalHuggingPriority="251" horizontalCompressionResistancePriority="500" text="Short" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Nhl-6I-9gW">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="38" height="18"/>
|
<rect key="frame" x="0.0" y="0.0" width="38" height="34"/>
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="15"/>
|
<fontDescription key="fontDescription" type="system" pointSize="15"/>
|
||||||
<nil key="textColor"/>
|
<nil key="textColor"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="BetaBadge" translatesAutoresizingMaskIntoConstraints="NO" id="mtL-iA-JnD">
|
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="BetaBadge" translatesAutoresizingMaskIntoConstraints="NO" id="mtL-iA-JnD">
|
||||||
<rect key="frame" x="44" y="0.0" width="41" height="18"/>
|
<rect key="frame" x="44" y="0.0" width="82" height="34"/>
|
||||||
</imageView>
|
</imageView>
|
||||||
</subviews>
|
</subviews>
|
||||||
</stackView>
|
</stackView>
|
||||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="100" verticalHuggingPriority="251" text="Developer" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Hp4-uP-55T">
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="100" verticalHuggingPriority="251" text="Developer" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Hp4-uP-55T">
|
||||||
<rect key="frame" x="0.0" y="20" width="62" height="16"/>
|
<rect key="frame" x="0.0" y="36" width="62" height="16"/>
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="13"/>
|
<fontDescription key="fontDescription" type="system" pointSize="13"/>
|
||||||
<color key="textColor" white="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
<color key="textColor" white="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
|
|||||||
@@ -20,40 +20,24 @@ import Nuke
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
private lazy var dataSource = self.makeDataSource()
|
private lazy var dataSource = self.makeDataSource()
|
||||||
|
|
||||||
@IBOutlet var nameLabel: UILabel!
|
@IBOutlet var bannerView: AppBannerView!
|
||||||
@IBOutlet var developerLabel: UILabel!
|
|
||||||
@IBOutlet var appIconImageView: UIImageView!
|
|
||||||
@IBOutlet var actionButton: PillButton!
|
|
||||||
@IBOutlet var subtitleLabel: UILabel!
|
@IBOutlet var subtitleLabel: UILabel!
|
||||||
|
|
||||||
@IBOutlet var screenshotsCollectionView: UICollectionView!
|
@IBOutlet private(set) var screenshotsCollectionView: UICollectionView!
|
||||||
@IBOutlet var betaBadgeView: UIImageView!
|
|
||||||
|
|
||||||
@IBOutlet private var screenshotsContentView: UIView!
|
|
||||||
|
|
||||||
override func awakeFromNib()
|
override func awakeFromNib()
|
||||||
{
|
{
|
||||||
super.awakeFromNib()
|
super.awakeFromNib()
|
||||||
|
|
||||||
|
self.contentView.preservesSuperviewLayoutMargins = true
|
||||||
|
|
||||||
// Must be registered programmatically, not in BrowseCollectionViewCell.xib, or else it'll throw an exception 🤷♂️.
|
// Must be registered programmatically, not in BrowseCollectionViewCell.xib, or else it'll throw an exception 🤷♂️.
|
||||||
self.screenshotsCollectionView.register(ScreenshotCollectionViewCell.self, forCellWithReuseIdentifier: RSTCellContentGenericCellIdentifier)
|
self.screenshotsCollectionView.register(ScreenshotCollectionViewCell.self, forCellWithReuseIdentifier: RSTCellContentGenericCellIdentifier)
|
||||||
|
|
||||||
self.screenshotsCollectionView.delegate = self
|
self.screenshotsCollectionView.delegate = self
|
||||||
self.screenshotsCollectionView.dataSource = self.dataSource
|
self.screenshotsCollectionView.dataSource = self.dataSource
|
||||||
self.screenshotsCollectionView.prefetchDataSource = self.dataSource
|
self.screenshotsCollectionView.prefetchDataSource = self.dataSource
|
||||||
|
|
||||||
self.screenshotsContentView.layer.cornerRadius = 20
|
|
||||||
self.screenshotsContentView.layer.masksToBounds = true
|
|
||||||
|
|
||||||
self.update()
|
|
||||||
}
|
|
||||||
|
|
||||||
override func tintColorDidChange()
|
|
||||||
{
|
|
||||||
super.tintColorDidChange()
|
|
||||||
|
|
||||||
self.update()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,12 +80,6 @@ private extension BrowseCollectionViewCell
|
|||||||
|
|
||||||
return dataSource
|
return dataSource
|
||||||
}
|
}
|
||||||
|
|
||||||
private func update()
|
|
||||||
{
|
|
||||||
self.subtitleLabel.textColor = self.tintColor
|
|
||||||
self.screenshotsContentView.backgroundColor = self.tintColor.withAlphaComponent(0.1)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extension BrowseCollectionViewCell: UICollectionViewDelegateFlowLayout
|
extension BrowseCollectionViewCell: UICollectionViewDelegateFlowLayout
|
||||||
|
|||||||
@@ -1,131 +1,64 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
|
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="15400" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
|
||||||
<device id="retina6_1" orientation="portrait">
|
<device id="retina6_1" orientation="portrait" appearance="light"/>
|
||||||
<adaptation id="fullscreen"/>
|
|
||||||
</device>
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<deployment identifier="iOS"/>
|
<deployment identifier="iOS"/>
|
||||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14490.49"/>
|
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15404"/>
|
||||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
|
||||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<objects>
|
<objects>
|
||||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
|
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
|
||||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||||
<collectionViewCell opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" reuseIdentifier="Cell" id="ln4-pC-7KY" customClass="BrowseCollectionViewCell" customModule="AltStore" customModuleProvider="target">
|
<collectionViewCell opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" insetsLayoutMarginsFromSafeArea="NO" reuseIdentifier="Cell" id="ln4-pC-7KY" customClass="BrowseCollectionViewCell" customModule="AltStore" customModuleProvider="target">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="375" height="400"/>
|
<rect key="frame" x="0.0" y="0.0" width="375" height="369"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
<view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" insetsLayoutMarginsFromSafeArea="NO">
|
<view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" insetsLayoutMarginsFromSafeArea="NO">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="375" height="400"/>
|
<rect key="frame" x="0.0" y="0.0" width="375" height="369"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<stackView opaque="NO" contentMode="scaleToFill" alignment="center" spacing="11" translatesAutoresizingMaskIntoConstraints="NO" id="Y3g-Md-6xH" userLabel="App Info">
|
<stackView verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" ambiguous="YES" axis="vertical" spacing="15" translatesAutoresizingMaskIntoConstraints="NO" id="5gU-g3-Fsy">
|
||||||
<rect key="frame" x="20" y="20" width="335" height="79"/>
|
<rect key="frame" x="16" y="0.0" width="343" height="369"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="F2j-pX-09A" customClass="AppIconImageView" customModule="AltStore" customModuleProvider="target">
|
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="ziA-mP-AY2" customClass="AppBannerView" customModule="AltStore" customModuleProvider="target">
|
||||||
<rect key="frame" x="0.0" y="7" width="65" height="65"/>
|
<rect key="frame" x="0.0" y="0.0" width="343" height="88"/>
|
||||||
|
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
|
||||||
<constraints>
|
<constraints>
|
||||||
<constraint firstAttribute="width" secondItem="F2j-pX-09A" secondAttribute="height" multiplier="1:1" id="c2j-8O-Diw"/>
|
<constraint firstAttribute="height" constant="88" id="z3D-cI-jhp"/>
|
||||||
<constraint firstAttribute="height" constant="65" id="ufl-3d-nkT"/>
|
|
||||||
</constraints>
|
</constraints>
|
||||||
</imageView>
|
</view>
|
||||||
<stackView opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="100" axis="vertical" alignment="top" spacing="2" translatesAutoresizingMaskIntoConstraints="NO" id="zkp-KH-OyV">
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Classic Nintendo games in your pocket." textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" translatesAutoresizingMaskIntoConstraints="NO" id="Imx-Le-bcy">
|
||||||
<rect key="frame" x="76" y="21" width="176" height="37"/>
|
<rect key="frame" x="0.0" y="103" width="343" height="17"/>
|
||||||
<subviews>
|
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||||
<stackView opaque="NO" contentMode="scaleToFill" spacing="6" translatesAutoresizingMaskIntoConstraints="NO" id="Ykl-yo-ncv">
|
<nil key="textColor"/>
|
||||||
<rect key="frame" x="0.0" y="0.0" width="127.5" height="20.5"/>
|
<nil key="highlightedColor"/>
|
||||||
<subviews>
|
</label>
|
||||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="100" verticalHuggingPriority="251" horizontalCompressionResistancePriority="500" text="App Name" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" translatesAutoresizingMaskIntoConstraints="NO" id="xni-8I-ewW">
|
<collectionView clipsSubviews="YES" multipleTouchEnabled="YES" userInteractionEnabled="NO" contentMode="scaleToFill" scrollEnabled="NO" contentInsetAdjustmentBehavior="never" dataMode="none" translatesAutoresizingMaskIntoConstraints="NO" id="RFs-qp-Ca4">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="80.5" height="20.5"/>
|
<rect key="frame" x="0.0" y="135" width="343" height="234"/>
|
||||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||||
<nil key="textColor"/>
|
<collectionViewFlowLayout key="collectionViewLayout" minimumLineSpacing="0.0" minimumInteritemSpacing="15" id="jH9-Jo-IHA">
|
||||||
<nil key="highlightedColor"/>
|
<size key="itemSize" width="120" height="213"/>
|
||||||
</label>
|
<size key="headerReferenceSize" width="0.0" height="0.0"/>
|
||||||
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" horizontalCompressionResistancePriority="1000" image="BetaBadge" translatesAutoresizingMaskIntoConstraints="NO" id="5gN-I2-QOB">
|
<size key="footerReferenceSize" width="0.0" height="0.0"/>
|
||||||
<rect key="frame" x="86.5" y="0.0" width="41" height="20.5"/>
|
<inset key="sectionInset" minX="8" minY="0.0" maxX="8" maxY="0.0"/>
|
||||||
</imageView>
|
</collectionViewFlowLayout>
|
||||||
</subviews>
|
<cells/>
|
||||||
</stackView>
|
</collectionView>
|
||||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="100" verticalHuggingPriority="251" text="Developer" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="B5S-HI-tWJ">
|
|
||||||
<rect key="frame" x="0.0" y="22.5" width="57.5" height="14.5"/>
|
|
||||||
<fontDescription key="fontDescription" style="UICTFontTextStyleCaption1"/>
|
|
||||||
<color key="textColor" white="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
|
||||||
<nil key="highlightedColor"/>
|
|
||||||
</label>
|
|
||||||
</subviews>
|
|
||||||
</stackView>
|
|
||||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="DeC-Y2-fvR" customClass="PillButton" customModule="AltStore" customModuleProvider="target">
|
|
||||||
<rect key="frame" x="263" y="24" width="72" height="31"/>
|
|
||||||
<color key="backgroundColor" red="0.22352941179999999" green="0.4941176471" blue="0.39607843139999999" alpha="0.10000000000000001" colorSpace="custom" customColorSpace="sRGB"/>
|
|
||||||
<constraints>
|
|
||||||
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="72" id="X7D-DN-WnD"/>
|
|
||||||
<constraint firstAttribute="height" constant="31" id="svo-Sc-wpR"/>
|
|
||||||
</constraints>
|
|
||||||
<fontDescription key="fontDescription" type="boldSystem" pointSize="14"/>
|
|
||||||
<state key="normal" title="OPEN"/>
|
|
||||||
</button>
|
|
||||||
</subviews>
|
</subviews>
|
||||||
</stackView>
|
</stackView>
|
||||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="w1r-LJ-TDs" userLabel="Screenshots">
|
|
||||||
<rect key="frame" x="15" y="114" width="345" height="266"/>
|
|
||||||
<subviews>
|
|
||||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="15" translatesAutoresizingMaskIntoConstraints="NO" id="hRR-84-Owd">
|
|
||||||
<rect key="frame" x="0.0" y="0.0" width="345" height="266"/>
|
|
||||||
<subviews>
|
|
||||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Classic Nintendo games in your pocket." textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" translatesAutoresizingMaskIntoConstraints="NO" id="Imx-Le-bcy">
|
|
||||||
<rect key="frame" x="20" y="15" width="305" height="17"/>
|
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
|
||||||
<color key="textColor" red="1" green="0.14901960780000001" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
|
||||||
<nil key="highlightedColor"/>
|
|
||||||
</label>
|
|
||||||
<collectionView clipsSubviews="YES" multipleTouchEnabled="YES" userInteractionEnabled="NO" contentMode="scaleToFill" contentInsetAdjustmentBehavior="never" dataMode="prototypes" translatesAutoresizingMaskIntoConstraints="NO" id="RFs-qp-Ca4">
|
|
||||||
<rect key="frame" x="20" y="47" width="305" height="185"/>
|
|
||||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
|
||||||
<collectionViewFlowLayout key="collectionViewLayout" minimumLineSpacing="0.0" minimumInteritemSpacing="10" id="jH9-Jo-IHA">
|
|
||||||
<size key="itemSize" width="120" height="213"/>
|
|
||||||
<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="0.0" maxX="0.0" maxY="0.0"/>
|
|
||||||
</collectionViewFlowLayout>
|
|
||||||
<cells/>
|
|
||||||
</collectionView>
|
|
||||||
</subviews>
|
|
||||||
<edgeInsets key="layoutMargins" top="15" left="20" bottom="20" right="20"/>
|
|
||||||
</stackView>
|
|
||||||
</subviews>
|
|
||||||
<color key="backgroundColor" red="1" green="0.14901960780000001" blue="0.0" alpha="0.050000000000000003" colorSpace="custom" customColorSpace="sRGB"/>
|
|
||||||
<constraints>
|
|
||||||
<constraint firstItem="hRR-84-Owd" firstAttribute="leading" secondItem="w1r-LJ-TDs" secondAttribute="leading" id="3us-zR-peW"/>
|
|
||||||
<constraint firstItem="hRR-84-Owd" firstAttribute="top" secondItem="w1r-LJ-TDs" secondAttribute="top" id="HWW-aS-Scd"/>
|
|
||||||
<constraint firstAttribute="trailing" secondItem="hRR-84-Owd" secondAttribute="trailing" id="lbU-TC-jhJ"/>
|
|
||||||
<constraint firstAttribute="bottom" secondItem="hRR-84-Owd" secondAttribute="bottom" id="nOI-Qj-lbm"/>
|
|
||||||
</constraints>
|
|
||||||
</view>
|
|
||||||
</subviews>
|
</subviews>
|
||||||
</view>
|
</view>
|
||||||
<constraints>
|
<constraints>
|
||||||
<constraint firstAttribute="trailing" secondItem="w1r-LJ-TDs" secondAttribute="trailing" constant="15" id="4ns-Zq-D4j"/>
|
<constraint firstItem="5gU-g3-Fsy" firstAttribute="top" secondItem="ln4-pC-7KY" secondAttribute="top" id="DnT-vq-BOc"/>
|
||||||
<constraint firstItem="w1r-LJ-TDs" firstAttribute="leading" secondItem="ln4-pC-7KY" secondAttribute="leading" constant="15" id="G1K-up-08u"/>
|
<constraint firstItem="5gU-g3-Fsy" firstAttribute="leading" secondItem="ln4-pC-7KY" secondAttribute="leadingMargin" id="YPy-xL-iUn"/>
|
||||||
<constraint firstAttribute="bottom" secondItem="w1r-LJ-TDs" secondAttribute="bottom" constant="20" id="Kk0-dF-4OW"/>
|
<constraint firstAttribute="bottom" secondItem="5gU-g3-Fsy" secondAttribute="bottom" id="gRu-Hz-CNL"/>
|
||||||
<constraint firstItem="Y3g-Md-6xH" firstAttribute="top" secondItem="ln4-pC-7KY" secondAttribute="top" constant="20" id="PRR-aX-AiM"/>
|
<constraint firstAttribute="trailingMargin" secondItem="5gU-g3-Fsy" secondAttribute="trailing" id="vf4-ql-4Vq"/>
|
||||||
<constraint firstAttribute="trailing" secondItem="Y3g-Md-6xH" secondAttribute="trailing" constant="20" id="g1Q-lg-I9O"/>
|
|
||||||
<constraint firstItem="w1r-LJ-TDs" firstAttribute="top" secondItem="Y3g-Md-6xH" secondAttribute="bottom" constant="15" id="i9W-bl-J9R"/>
|
|
||||||
<constraint firstItem="Y3g-Md-6xH" firstAttribute="leading" secondItem="ln4-pC-7KY" secondAttribute="leading" constant="20" id="j6L-IY-ALs"/>
|
|
||||||
</constraints>
|
</constraints>
|
||||||
<viewLayoutGuide key="safeArea" id="btu-iP-81i"/>
|
|
||||||
<connections>
|
<connections>
|
||||||
<outlet property="actionButton" destination="DeC-Y2-fvR" id="VDk-4D-STy"/>
|
<outlet property="bannerView" destination="ziA-mP-AY2" id="yxo-ar-Cha"/>
|
||||||
<outlet property="appIconImageView" destination="F2j-pX-09A" id="COe-74-adn"/>
|
|
||||||
<outlet property="betaBadgeView" destination="5gN-I2-QOB" id="hu7-Ax-Wbc"/>
|
|
||||||
<outlet property="developerLabel" destination="B5S-HI-tWJ" id="QGh-1g-fFv"/>
|
|
||||||
<outlet property="nameLabel" destination="xni-8I-ewW" id="V56-ZT-vFa"/>
|
|
||||||
<outlet property="screenshotsCollectionView" destination="RFs-qp-Ca4" id="xfi-AN-l17"/>
|
<outlet property="screenshotsCollectionView" destination="RFs-qp-Ca4" id="xfi-AN-l17"/>
|
||||||
<outlet property="screenshotsContentView" destination="w1r-LJ-TDs" id="iWJ-52-rbA"/>
|
|
||||||
<outlet property="subtitleLabel" destination="Imx-Le-bcy" id="JVW-ZZ-51O"/>
|
<outlet property="subtitleLabel" destination="Imx-Le-bcy" id="JVW-ZZ-51O"/>
|
||||||
</connections>
|
</connections>
|
||||||
|
<point key="canvasLocation" x="136.95652173913044" y="152.67857142857142"/>
|
||||||
</collectionViewCell>
|
</collectionViewCell>
|
||||||
</objects>
|
</objects>
|
||||||
<resources>
|
|
||||||
<image name="BetaBadge" width="41" height="17"/>
|
|
||||||
</resources>
|
|
||||||
</document>
|
</document>
|
||||||
|
|||||||
@@ -72,47 +72,51 @@ private extension BrowseViewController
|
|||||||
let dataSource = RSTFetchedResultsCollectionViewPrefetchingDataSource<StoreApp, UIImage>(fetchRequest: fetchRequest, managedObjectContext: DatabaseManager.shared.viewContext)
|
let dataSource = RSTFetchedResultsCollectionViewPrefetchingDataSource<StoreApp, UIImage>(fetchRequest: fetchRequest, managedObjectContext: DatabaseManager.shared.viewContext)
|
||||||
dataSource.cellConfigurationHandler = { (cell, app, indexPath) in
|
dataSource.cellConfigurationHandler = { (cell, app, indexPath) in
|
||||||
let cell = cell as! BrowseCollectionViewCell
|
let cell = cell as! BrowseCollectionViewCell
|
||||||
cell.nameLabel.text = app.name
|
cell.layoutMargins.left = self.view.layoutMargins.left
|
||||||
cell.developerLabel.text = app.developerName
|
cell.layoutMargins.right = self.view.layoutMargins.right
|
||||||
|
|
||||||
cell.subtitleLabel.text = app.subtitle
|
cell.subtitleLabel.text = app.subtitle
|
||||||
cell.imageURLs = Array(app.screenshotURLs.prefix(2))
|
cell.imageURLs = Array(app.screenshotURLs.prefix(2))
|
||||||
cell.appIconImageView.image = nil
|
cell.bannerView.titleLabel.text = app.name
|
||||||
cell.appIconImageView.isIndicatingActivity = true
|
cell.bannerView.subtitleLabel.text = app.developerName
|
||||||
cell.betaBadgeView.isHidden = !app.isBeta
|
cell.bannerView.betaBadgeView.isHidden = !app.isBeta
|
||||||
|
|
||||||
cell.actionButton.addTarget(self, action: #selector(BrowseViewController.performAppAction(_:)), for: .primaryActionTriggered)
|
cell.bannerView.iconImageView.image = nil
|
||||||
cell.actionButton.activityIndicatorView.style = .white
|
cell.bannerView.iconImageView.isIndicatingActivity = true
|
||||||
|
|
||||||
|
cell.bannerView.button.addTarget(self, action: #selector(BrowseViewController.performAppAction(_:)), for: .primaryActionTriggered)
|
||||||
|
cell.bannerView.button.activityIndicatorView.style = .white
|
||||||
|
|
||||||
// Explicitly set to false to ensure we're starting from a non-activity indicating state.
|
// Explicitly set to false to ensure we're starting from a non-activity indicating state.
|
||||||
// Otherwise, cell reuse can mess up some cached values.
|
// Otherwise, cell reuse can mess up some cached values.
|
||||||
cell.actionButton.isIndicatingActivity = false
|
cell.bannerView.button.isIndicatingActivity = false
|
||||||
|
|
||||||
let tintColor = app.tintColor ?? .altPrimary
|
let tintColor = app.tintColor ?? .altPrimary
|
||||||
cell.tintColor = tintColor
|
cell.tintColor = tintColor
|
||||||
|
|
||||||
if app.installedApp == nil
|
if app.installedApp == nil
|
||||||
{
|
{
|
||||||
cell.actionButton.setTitle(NSLocalizedString("FREE", comment: ""), for: .normal)
|
cell.bannerView.button.setTitle(NSLocalizedString("FREE", comment: ""), for: .normal)
|
||||||
|
|
||||||
let progress = AppManager.shared.installationProgress(for: app)
|
let progress = AppManager.shared.installationProgress(for: app)
|
||||||
cell.actionButton.progress = progress
|
cell.bannerView.button.progress = progress
|
||||||
cell.actionButton.isInverted = false
|
cell.bannerView.button.isInverted = false
|
||||||
|
|
||||||
if Date() < app.versionDate
|
if Date() < app.versionDate
|
||||||
{
|
{
|
||||||
cell.actionButton.countdownDate = app.versionDate
|
cell.bannerView.button.countdownDate = app.versionDate
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cell.actionButton.countdownDate = nil
|
cell.bannerView.button.countdownDate = nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cell.actionButton.setTitle(NSLocalizedString("OPEN", comment: ""), for: .normal)
|
cell.bannerView.button.setTitle(NSLocalizedString("OPEN", comment: ""), for: .normal)
|
||||||
cell.actionButton.progress = nil
|
cell.bannerView.button.progress = nil
|
||||||
cell.actionButton.isInverted = true
|
cell.bannerView.button.isInverted = true
|
||||||
cell.actionButton.countdownDate = nil
|
cell.bannerView.button.countdownDate = nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dataSource.prefetchHandler = { (storeApp, indexPath, completionHandler) -> Foundation.Operation? in
|
dataSource.prefetchHandler = { (storeApp, indexPath, completionHandler) -> Foundation.Operation? in
|
||||||
@@ -135,8 +139,8 @@ private extension BrowseViewController
|
|||||||
}
|
}
|
||||||
dataSource.prefetchCompletionHandler = { (cell, image, indexPath, error) in
|
dataSource.prefetchCompletionHandler = { (cell, image, indexPath, error) in
|
||||||
let cell = cell as! BrowseCollectionViewCell
|
let cell = cell as! BrowseCollectionViewCell
|
||||||
cell.appIconImageView.isIndicatingActivity = false
|
cell.bannerView.iconImageView.isIndicatingActivity = false
|
||||||
cell.appIconImageView.image = image
|
cell.bannerView.iconImageView.image = image
|
||||||
|
|
||||||
if let error = error
|
if let error = error
|
||||||
{
|
{
|
||||||
@@ -286,8 +290,8 @@ extension BrowseViewController: UICollectionViewDelegateFlowLayout
|
|||||||
let maxVisibleScreenshots = 2 as CGFloat
|
let maxVisibleScreenshots = 2 as CGFloat
|
||||||
let aspectRatio: CGFloat = 16.0 / 9.0
|
let aspectRatio: CGFloat = 16.0 / 9.0
|
||||||
|
|
||||||
let layout = collectionViewLayout as! UICollectionViewFlowLayout
|
let layout = self.prototypeCell.screenshotsCollectionView.collectionViewLayout as! UICollectionViewFlowLayout
|
||||||
let padding = (layout.minimumInteritemSpacing * (maxVisibleScreenshots - 1))
|
let padding = (layout.minimumInteritemSpacing * (maxVisibleScreenshots - 1)) + layout.sectionInset.left + layout.sectionInset.right
|
||||||
|
|
||||||
self.dataSource.cellConfigurationHandler(self.prototypeCell, item, indexPath)
|
self.dataSource.cellConfigurationHandler(self.prototypeCell, item, indexPath)
|
||||||
|
|
||||||
@@ -295,6 +299,8 @@ extension BrowseViewController: UICollectionViewDelegateFlowLayout
|
|||||||
widthConstraint.isActive = true
|
widthConstraint.isActive = true
|
||||||
defer { widthConstraint.isActive = false }
|
defer { widthConstraint.isActive = false }
|
||||||
|
|
||||||
|
// Manually update cell width & layout so we can accurately calculate screenshot sizes.
|
||||||
|
self.prototypeCell.frame.size.width = widthConstraint.constant
|
||||||
self.prototypeCell.layoutIfNeeded()
|
self.prototypeCell.layoutIfNeeded()
|
||||||
|
|
||||||
let collectionViewWidth = self.prototypeCell.screenshotsCollectionView.bounds.width
|
let collectionViewWidth = self.prototypeCell.screenshotsCollectionView.bounds.width
|
||||||
@@ -302,6 +308,7 @@ extension BrowseViewController: UICollectionViewDelegateFlowLayout
|
|||||||
let screenshotHeight = screenshotWidth * aspectRatio
|
let screenshotHeight = screenshotWidth * aspectRatio
|
||||||
|
|
||||||
let heightConstraint = self.prototypeCell.screenshotsCollectionView.heightAnchor.constraint(equalToConstant: screenshotHeight)
|
let heightConstraint = self.prototypeCell.screenshotsCollectionView.heightAnchor.constraint(equalToConstant: screenshotHeight)
|
||||||
|
heightConstraint.priority = .defaultHigh // Prevent temporary unsatisfiable constraints error.
|
||||||
heightConstraint.isActive = true
|
heightConstraint.isActive = true
|
||||||
defer { heightConstraint.isActive = false }
|
defer { heightConstraint.isActive = false }
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user