Post

Replies

Boosts

Views

Activity

How do you extend a modern collection view cell's default content configuration?
Apple's Displaying Cell Info tutorial shows using a default cell content configuration to set two lines of text func cellRegistrationHandler(cell: UICollectionViewListCell, indexPath: IndexPath, id: String) { let reminder = Reminder.sampleData[indexPath.item] var contentConfiguration = cell.defaultContentConfiguration() contentConfiguration.text = reminder.title contentConfiguration.secondaryText = reminder.dueDate.dayAndTimeText contentConfiguration.secondaryTextProperties.font = UIFont.preferredFont(forTextStyle: .caption1) cell.contentConfiguration = contentConfiguration } How would I get started extending this to include a third line of text? I would like to keep the built-in text, secondaryText, and accessory control (the tutorial has a done button on each cell), while also adding custom UI elements. I'm assuming this is possible since Apple uses the term "compositional collection views," but I'm not sure how to accomplish this. Is it possible, or would I instead need to register a custom UICollectionViewCell subclass?
Topic: UI Frameworks SubTopic: UIKit Tags:
0
0
733
May ’22
"Portrait-only" app presenting a landscape-only modal. What is the recommended way to do this and have a seamless modal dismissal?
override var supportedInterfaceOrientations: UIInterfaceOrientationMask { return [.landscapeRight, .landscapeLeft] } My modal view controller overrides this property, as its a complex custom video player that needs to be restricted to landscape. However, when it's dismissed, there is a jarring bug in the transition where the presenting VC is portrait in the device's landscape state for a second while half of the screen is black. It returns to normal (portrait) after a second, but I would like to avoid this transition bug. What might I be missing as to the root cause, or recommended way to have a portrait app (set in project navigator) present a landscape-only view controller?
0
0
784
Dec ’22
How do you start an `SKProductsRequest` in a watchOS app, when the existing product identifiers from the iOS app use a main bundle ID?
I have a watchOS app (not independent) that I'm trying to bring StoreKit support to purchasing subscriptions. When I make my existing StoreKit manager for iOS target watchOS, the productsRequest(_:didReceive:) delegate callback returns an empty response.products array but I don't understand why. One guess as to the cause is that when I initialize the SKProductsRequest, the products identifiers I pass ones with prepended bundle identifiers, which may different between iOS and watchOS? The existing iOS code has the format static let subscriptionKindOne = Bundle.main.bundleIdentifier!.lowercased() + ".subscriptionKindOne" static let subscriptionKindTwo = Bundle.main.bundleIdentifier!.lowercased() + ".subscriptionKindTwo" static let subscriptionKindThree = Bundle.main.bundleIdentifier!.lowercased() + ".subscriptionKindThree" Is this right? If so, what would be the correct way to start a products request on watchOS, so that the SKProductsResponse products array is populated?
0
0
640
Jul ’23
In Mac Catalyst, what would be the simplest way to hide the title bar but retain its double click functionality?
After adopting sidebar / split view controller support in Mac Catalyst, there are several UI side effects that make the default title bar stick out and look inconsistent. If I hide the title bar however, func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { guard let windowScene = (scene as? UIWindowScene) else { return } #if targetEnvironment(macCatalyst) if let titlebar = windowScene.titlebar { titlebar.titleVisibility = .hidden titlebar.toolbar = nil } #endif } the ability to double click the top of the window to maximize it is lost. What would be the simplest approach to have both the hidden appearance, but keep the double click behavior?
0
0
668
May ’24
With the Vision framework, is it possible to get the time ranges or frames for which the video contains trajectories?
As far as I can tell - https://developer.apple.com/documentation/vision/identifying_trajectories_in_video trajectory detection lets you use characteristics of the trajectories detected for, say, drawing over the video as it plays. However, is it possible to mark which time ranges the video has detected trajectories, or perhaps access the frames for which there are trajectories?
1
0
759
Feb ’21
With user imported video, how do you filter for frames based on Vision analysis?
I'd like to perform VNDetectHumanBodyPoseRequests on a video that the user imports through the system photo picker or document view controller. I started looking at the Building a Feature-Rich App for Sports Analysis - https://developer.apple.com/documentation/vision/building_a_feature-rich_app_for_sports_analysis sample code since it has an example where video is imported from disk and then analyzed. However, my end goal is to filter for frames that contain certain poses, so that all frames without them are edited out / deleted (instead of in the sample code drawing on frames with detected trajectories). For pose detection I'm looking at the Detecting Human Actions in a Live Video Feed - https://developer.apple.com/documentation/createml/detecting_human_actions_in_a_live_video_feed, but the live video capture isn't quite relevant. I'm trying to break this down into smaller problems and have a few questions: Should a full video file copy be made before analysis? The Detecting Human Actions in a Live Video Feed - https://developer.apple.com/documentation/createml/detecting_human_actions_in_a_live_video_feed sample code uses a Combine pipeline for analyzing live video frames. Since I'm analyzing imported video, would Combine be overkill or a good fit here? After I've detected which frames have a particular pose, how (in AVFoundation terms) do I filter for those frames or edit out / delete the frames without that pose?
1
0
856
Mar ’21
What is a robust approach to deleting a CKRecord associated with an IndexPath in a table view or collection view?
When synchronizing model objects, local CKRecords, and CKRecords in CloudKit during swipe-to-delete, how can I make this as robust as possible? Error handling omitted for the sake of the example. override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {         if editingStyle == .delete {             let record = self.records[indexPath.row]             privateDatabase.delete(withRecordID: record.recordID) { recordID, error in                 self.records.remove(at: indexPath.row)             }         }     } Since indexPath could change due to other changes in the table view / collection view during the time it takes to delete the record from CloudKit, how could this be improved upon?
1
0
649
Jul ’21
How do you apply a diffable data source UI snapshot only after awaiting (with async/await) data fetched from the network?
I'm new to async/await, and am currently migrating my completion handler code to Swift 5.5's concurrency features. After generating an sync alternative in Xcode to my function func fetchMatchRecords(completion: @escaping ([Match]) -> Void), it becomes func fetchMatchRecords() async -> [Match]. I'm not sure how it would be used in the context of UIKit and diffable data sources. In a viewDidLoad, previously it would be MatchHistoryController.shared.fetchMatchRecords() { matches in DispatchQueue.main.async { self.dataSource.apply(self.initialSnapshot(), animatingDifferences: false) } } But I'm not sure how it would be used now Task { await MatchHistoryController.shared.fetchMatchRecords() } self.dataSource.apply(self.initialSnapshot(), animatingDifferences: false) How would I make sure that the snapshot is applied only after awaiting a successful fetch result? Here's the definition of initialSnapshot() that I used: func initialSnapshot() -> NSDiffableDataSourceSnapshot<Section, Match> { var snapshot = NSDiffableDataSourceSnapshot<Section, Match>() snapshot.appendSections([.main]) snapshot.appendItems(MatchHistoryController.shared.matches) return snapshot }
1
0
2.1k
Sep ’23