diff --git a/AltStore/Base.lproj/Main.storyboard b/AltStore/Base.lproj/Main.storyboard index ccc65b52..0d7973d5 100644 --- a/AltStore/Base.lproj/Main.storyboard +++ b/AltStore/Base.lproj/Main.storyboard @@ -828,6 +828,9 @@ World + + + @@ -865,7 +868,7 @@ World - + diff --git a/AltStore/My Apps/MyAppsViewController.swift b/AltStore/My Apps/MyAppsViewController.swift index 4e7d9c82..65f3f66e 100644 --- a/AltStore/My Apps/MyAppsViewController.swift +++ b/AltStore/My Apps/MyAppsViewController.swift @@ -99,6 +99,8 @@ class MyAppsViewController: UICollectionViewController // Gestures self.longPressGestureRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(MyAppsViewController.handleLongPressGesture(_:))) self.collectionView.addGestureRecognizer(self.longPressGestureRecognizer) + + self.registerForPreviewing(with: self, sourceView: self.collectionView) } override func viewWillAppear(_ animated: Bool) @@ -110,14 +112,20 @@ class MyAppsViewController: UICollectionViewController override func prepare(for segue: UIStoryboardSegue, sender: Any?) { - guard segue.identifier == "showApp" else { return } + guard let identifier = segue.identifier else { return } - guard let cell = sender as? UICollectionViewCell, let indexPath = self.collectionView.indexPath(for: cell) else { return } - - let installedApp = self.dataSource.item(at: indexPath) - - let appViewController = segue.destination as! AppViewController - appViewController.app = installedApp.storeApp + switch identifier + { + case "showApp", "showUpdate": + guard let cell = sender as? UICollectionViewCell, let indexPath = self.collectionView.indexPath(for: cell) else { return } + + let installedApp = self.dataSource.item(at: indexPath) + + let appViewController = segue.destination as! AppViewController + appViewController.app = installedApp.storeApp + + default: break + } } override func shouldPerformSegue(withIdentifier identifier: String, sender: Any?) -> Bool @@ -165,7 +173,8 @@ private extension MyAppsViewController let dataSource = RSTFetchedResultsCollectionViewPrefetchingDataSource(fetchRequest: fetchRequest, managedObjectContext: DatabaseManager.shared.viewContext) dataSource.liveFetchLimit = maximumCollapsedUpdatesCount dataSource.cellIdentifierHandler = { _ in "UpdateCell" } - dataSource.cellConfigurationHandler = { (cell, installedApp, indexPath) in + dataSource.cellConfigurationHandler = { [weak self] (cell, installedApp, indexPath) in + guard let self = self else { return } guard let app = installedApp.storeApp else { return } let cell = cell as! UpdateCollectionViewCell @@ -689,6 +698,19 @@ extension MyAppsViewController return headerView } } + + override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) + { + let section = Section.allCases[indexPath.section] + switch section + { + case .updates: + guard let cell = collectionView.cellForItem(at: indexPath) else { break } + self.performSegue(withIdentifier: "showUpdate", sender: cell) + + default: break + } + } } extension MyAppsViewController: UICollectionViewDelegateFlowLayout @@ -860,3 +882,37 @@ extension MyAppsViewController: UIDocumentPickerDelegate } } } + +extension MyAppsViewController: UIViewControllerPreviewingDelegate +{ + func previewingContext(_ previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) -> UIViewController? + { + guard + let indexPath = self.collectionView.indexPathForItem(at: location), + let cell = self.collectionView.cellForItem(at: indexPath) + else { return nil } + + let section = Section.allCases[indexPath.section] + switch section + { + case .updates: + previewingContext.sourceRect = cell.frame + + let app = self.dataSource.item(at: indexPath) + guard let storeApp = app.storeApp else { return nil} + + let appViewController = AppViewController.makeAppViewController(app: storeApp) + return appViewController + + default: return nil + } + } + + func previewingContext(_ previewingContext: UIViewControllerPreviewing, commit viewControllerToCommit: UIViewController) + { + let point = CGPoint(x: previewingContext.sourceRect.midX, y: previewingContext.sourceRect.midY) + guard let indexPath = self.collectionView.indexPathForItem(at: point), let cell = self.collectionView.cellForItem(at: indexPath) else { return } + + self.performSegue(withIdentifier: "showUpdate", sender: cell) + } +} diff --git a/AltStore/My Apps/UpdateCollectionViewCell.swift b/AltStore/My Apps/UpdateCollectionViewCell.swift index 11f610ea..04cff8e0 100644 --- a/AltStore/My Apps/UpdateCollectionViewCell.swift +++ b/AltStore/My Apps/UpdateCollectionViewCell.swift @@ -58,6 +58,22 @@ extension UpdateCollectionViewCell } animator.startAnimation() } + + override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? + { + let view = super.hitTest(point, with: event) + + if view == self.versionDescriptionTextView + { + // Forward touches on the text view (but not on the nested "more" button) + // so cell selection works as expected. + return self + } + else + { + return view + } + } } private extension UpdateCollectionViewCell diff --git a/AltStore/My Apps/UpdateCollectionViewCell.xib b/AltStore/My Apps/UpdateCollectionViewCell.xib index 5fedf558..4b928242 100644 --- a/AltStore/My Apps/UpdateCollectionViewCell.xib +++ b/AltStore/My Apps/UpdateCollectionViewCell.xib @@ -84,7 +84,7 @@ - +