Construct and manage graphical, event-driven user interfaces for iOS or tvOS apps using UIKit.

UIKit Documentation

Post

Replies

Boosts

Views

Activity

Error When Saving Video To Camera Roll
I am working on enabling the option for users to save a video from a post in a social media app to their cameral roll. I am trying to use PHPhotoLibrary to perform the task similarly to how I did the functionality for saving images and gifs. However, when I try to perform the task with the code as is, I get the following errors: Error Domain=PHPhotosErrorDomain Code=-1 "(null)" The operation couldn’t be completed. (PHPhotosErrorDomain error -1.) The implementation is as follows: Button(action: { guard let videoURL = URL(string: media.link.absoluteString) else { print("Invalid video url.") return } PHPhotoLibrary.shared().performChanges({ PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: videoURL) print("Video URL: \(videoURL)") }) { (success, error) in if let error = error { debugPrint(error) print(error.localizedDescription) } else { print("Video saved to camera roll!") } } }) { Text("Save Video") Image(systemName: "square.and.arrow.down") } The video URL is successfully fetched dynamically from the post, but there's an issue with storing it locally in the library. What am I missing?
1
0
721
Feb ’24
why is my initial view controller showing a black screen with the following errors
hi everyone. im new to xcode and wondering if anyone has any idea for what to do when your initial view controller keeps showing a black screen. ive done the following ensured Main storyboard file base name in info.pl is set to my storyboard. also under application scene manifest --> scene configurations --> application session role --> item 0 i have storyboard name as my storyboard and delegate class name as my SceneDelegate but I keep receiving this error 2024-02-13 22:42:47.452242-0500 PROJECT-NAME[11302:838011] [SceneConfiguration] Info.plist configuration "(no name)" for UIWindowSceneSessionRoleApplication contained UISceneDelegateClassName key, but could not load class with name "SceneDelegate". 2024-02-13 22:42:47.452641-0500 PROJECT-NAME[11302:838011] [SceneConfiguration] Info.plist configuration "(no name)" for UIWindowSceneSessionRoleApplication contained UISceneDelegateClassName key, but could not load class with name "SceneDelegate". 2024-02-13 22:42:47.456532-0500 PROJECT-NAME[11302:838011] [WindowScene] There is no scene delegate set. A scene delegate class must be specified to use a main storyboard file. the initial view controller box is checked for the correct controller (HomePageController) ive added print statements to my viewDidLoad() in my HomePageController (i guess one weird thing is that i cant set 'main interface' to my main storyboard in the deployment info section) im really not sure what else to do, and any help would be really appreciated. im a beginner so all of this is a bit difficult. this is my info.pl file: https://drive.google.com/file/d/1W-KOH3BjqgfJf10n9LM5bRTYHXQYM9ER/view?usp=sharing
0
0
590
Feb ’24
CoreData with cloudkit sync - partially broken.
When I add or delete data of my entity type I can see the updates (between the simulator and the phone) but when i edit I dont see the updates although table view is reloaded. The console says Ignoring remote change notification because it didn't change any entities tracked by persistent history When I rebuild the app for both device and simulator I see it reflecting the most current changes. Any help? Neerav
0
0
379
Feb ’24
UIColorPickerController extension doesn't seem to work to set VC as delegate.
I am taking a reference to a VC in app delegate and using a UIColorPickerController extension with the following code, I'm setting this VC as a delegate to the picker. I need to take these lengthy steps because there is no reference to the picker that a UIColorWell displays! This way, I can set the background color of the VC while the user selects different colors from picker, one after another. This is the give a live effect or color change. However, I dont see this happening. The delegate is not being called. Any help? import Foundation import UIKit extension UIColorPickerViewController{ open override func viewDidLoad() { super.viewDidLoad() let appDelegate = UIApplication.shared.delegate as! AppDelegate delegate = appDelegate.addOrEditVC } }```
1
0
419
Feb ’24
Making ScrollView based discrete scrubber in SwiftUI
I am trying to recreate Discrete scrubber in SwiftUI with haptic feedback and snap to nearest integer step. I use ScrollView and LazyHStack as follows: struct DiscreteScrubber: View { @State var numLines:Int = 100 var body: some View { ScrollView(.horizontal, showsIndicators: false) { LazyHStack { ForEach(0..<numLines, id: \.self) { _ in Rectangle().frame(width: 2, height: 10, alignment: .center) .foregroundStyle(Color.red) Spacer().frame(width: 10) } } } } } Problem: I need to add content inset of half the frame width of ScrollView so that the first line in the scrubber starts at the center of the view and so does the last line, and also generate haptic feedback as it scrolls. This was easy in UIKit but not obvious in SwiftUI.
0
0
474
Feb ’24
Checking if Classic Invert is enabled in iOS
Hello, I am currently developing an iOS app and need to check if the Classic Invert accessibility setting is enabled. According to the Apple documentation, the isInvertColorsEnabled property should indicate whether the Classic Invert setting is enabled: "A Boolean value that indicates whether the Classic Invert setting is in an enabled state." https://developer.apple.com/documentation/uikit/uiaccessibility/1615167-isinvertcolorsenabled However, in my app, isInvertColorsEnabled only returns true when the Smart Invert setting is enabled. It always returns false when Classic Invert is enabled. Is this a bug in the documentation? If so, is there another way to check if Classic Invert is enabled? Thank you for your time. Additional information: Xcode 15, iOS 17.0
0
0
293
Feb ’24
UIKit drawing and animation differences in ShareExtensions
I noticed two differences in my share extension's behaviour compared to my main app: The layer.presentation() values can be massively out of date, which means that continuing animations from their current position is not possible. This is both true for manually checking the layer.presentation() values, as well as for letting UIKit doing the replacement-continuation via UIView.animate(..., options: [.beginFromCurrentState], ...). UI updates seem to be ignored if the share extension performs heavy calculation. Interestingly, it doesn't seem to matter whether I do this calculation in the main thread or in a background thread, and call the main thread for UI updates via DispatchQueue.main.sync { ... }. I see my console in Xcode filling with progress updates from print(progress) statements, but the UI just doesn't move. Once the heavy processing is done, it instantly updates again. I assume that 1 and 2 are related. If I cannot get the UI to draw while the computation is done, I probably also can't get up-to-date presentation layer values. Are there any explanations for this behaviour, and any advice on how I could circumvent the problem? Again, this is specific to my share extension and doesn't happen in my main app.
0
0
461
Feb ’24
Behavior Change in Dismissing View Controllers in Catalyst Apps on macOS 14.4 Betas
I wanted to post this here in the hope that this will draw attention to what I think is a serious change in behavior that could negatively affect Catalyst apps in macOS 14.4. Prior to macOS 14.4, when the completion handler was invoked from calling dismiss() to dismiss a presented view controller in a Catalyst app, the dismissed controller no longer appeared in the chain. That is to say that if the root view controller presents View Controller A, when View Controller A is dismissed, the root view controller's presentedViewController property is nil when the completion handler for dismiss() is called. With macOS 14.4, this is no longer the case. If the root view controller presents View Controller A and then View Controller A is dismissed, the presentedViewController property of the root view controller still refers to Controller A when dismiss()'s completion handler is called. The side effect of this change in behavior means that if you try to present another view controller from the completion handler of the one being dismissed, it will fail to show because the top most view controller in the chain is the controller being dismissed and presenting from it will result in nothing showing up because it is removed from the chain immediately after the completion handler is invoked. Before macOS 14.4, it the top of the chain would have been the controller that presented the controller that was dismissed, which is what you actually want. This problem does not exist in the betas for iOS 17.4 or iPadOS 17.4. It appears to affect only Catalyst apps running under macOS 1.4.4. I think this change in behavior has the potential to affect a number existing Catalyst apps and it may not be obvious to the user something is going wrong. It really should be fixed before macOS 14.4 is released to the public. I've created a feedback with a sample Xcode project that demonstrates the problem (feedback number FB13622757).
3
0
791
Feb ’24
UIDocumentInteractionController keyboard trap
We are using UIDocumentInteractionController to preview a pdf. When you navigate on your phone with the hardware keyboard and it focuses on the pfd preview, there is no way we can reach the buttons in the toolbar anymore like the share and done button. Is this a bug or is there a way to get to the navigation/toolbars? iOS17.0 iPhone14 sim and real device.
2
0
485
Feb ’24
Xcode 13.2.1 : alert mishandling on Iphone but working on simulator ???
Hello everyone! I'm just working on my first app in swift, and am out of knowledge about this case. First, the related code : `@IBAction func ajouterNouvelleValeur(_ sender: Any) { // Créer une alerte pour saisir la nouvelle valeur let alert = UIAlertController(title: "Ajouter une nouvelle valeur", message: nil, preferredStyle: .alert) alert.addTextField { (textField) in textField.placeholder = "Entrez la nouvelle valeur" } // Ajouter un bouton "Ajouter" pour ajouter la nouvelle valeur alert.addAction(UIAlertAction(title: "Ajouter", style: .default, handler: { [weak self] action in guard let textField = alert.textFields?.first, let newValue = textField.text else { return } self?.ajouterNouvelleValeur(newValue) })) // Ajouter un bouton "Annuler" alert.addAction(UIAlertAction(title: "Annuler", style: .cancel, handler: nil)) // Afficher l'alerte present(alert, animated: true, completion: nil) } this to present an alert with textField to enter a new value to an array. Works properly on simulator, but when testing on my iPhone12 SE, it appears not to catch any value for the textField. Has anyone encountered the same issue, and knows the solution? Hope my english is not too bad (as a French member, I appologize if not!) Best regards Sébastien
1
0
531
Feb ’24
CollectionView not calling didSelectItemAt correctly
I have a CollectionView in my SwiftUI App. The collectionView is wrapped in a UIViewRepresentable. If I tap on a collectionView cell normally the function isn't called but if I hold the cell down the console prints <0x107507790> Gesture: System gesture gate timed out. and when I let go of the cell after that's printed then didSelectItem is called. Here is my CollectionView Class: class SessionsCollectionView: UIView, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout { lazy var collectionView: UICollectionView = { let layout = UICollectionViewFlowLayout() layout.minimumInteritemSpacing = 0 layout.minimumLineSpacing = 30 let collectionView = UICollectionView(frame: CGRect.zero, collectionViewLayout: layout) collectionView.translatesAutoresizingMaskIntoConstraints = false collectionView.dataSource = self collectionView.delegate = self collectionView.clipsToBounds = false collectionView.delaysContentTouches = false collectionView.register(SessionCell.self, forCellWithReuseIdentifier: "cell") collectionView.register(SessionsHeader.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: "header") return collectionView }() override init(frame: CGRect) { super.init(frame: frame) self.backgroundColor = .clear setupCollectionView() } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } private func setupCollectionView() { addSubview(collectionView) collectionView.backgroundColor = .clear collectionView.alwaysBounceVertical = true collectionView.alwaysBounceHorizontal = false collectionView.delaysContentTouches = false collectionView.contentInset = .init(top: 20, left: 0, bottom: 20, right: 0) collectionView.showsVerticalScrollIndicator = false NSLayoutConstraint.activate([ collectionView.topAnchor.constraint(equalTo: topAnchor), collectionView.leadingAnchor.constraint(equalTo: leadingAnchor), collectionView.trailingAnchor.constraint(equalTo: trailingAnchor), collectionView.bottomAnchor.constraint(equalTo: bottomAnchor) ]) } // MARK: Header func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView { if kind == UICollectionView.elementKindSectionHeader { let sectionHeader = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "header", for: indexPath) as! Header return sectionHeader } } func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize { let width: CGFloat = collectionView.frame.width let height: CGFloat = 33 + 20 return CGSize(width: width, height: height) } // MARK: - UICollectionViewDataSource func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return 10 } func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! SessionCell return cell } // MARK: - UICollectionViewDelegateFlowLayout func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { let width = collectionView.bounds.width let height = 150 return CGSize(width: collectionView.bounds.width, height: height) } func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { print(indexPath.row) } } struct SessionsCollectionViewWrapper: UIViewRepresentable { var sessionViewNavigation: SessionViewNavigation func makeUIView(context: Context) -> SessionsCollectionView { let sessionsCollectionView = SessionsCollectionView() return sessionsCollectionView } func updateUIView(_ uiView: SessionsCollectionView, context: Context) { // Update any properties or handle updates if needed } }
2
0
1.2k
Feb ’24
How to cancel a Drag/Drop item loading in UIKit
After a drag/drop of an item into my app's collectionView, UIKit shows this progress UI while the data loads: How do I cancel the loading of the dropped items when the user cancels? The itemProvider.loadFileRepresentation completion block is always called without error. What am I missing? coordinator.session.progress.cancellationHandler = { Task { @MainActor in // User canceled the dropped items loading } } for item in coordinator.items { item.dragItem.itemProvider.loadFileRepresentation(forTypeIdentifier: AVFileType.mov.rawValue) { [ weak self] (videoURL, error) in // This completion block will get called even after operation was canceled. } }
0
0
414
Feb ’24
Convert from SQLite database in UIKit to storage on iCloud
My apps are set up to store data in a SQLite database on the device. The user is also able to add images and those are also stored on the device. The database and images are stored in the apps documents folder. The database is set up with four tables, one of them containing a list of selectable items so the information in that table is constant. The other three are read/write to the user. The database also contains a field, which contains true/false as to whether the app has been purchased or not. My thought behind was that this would make the users data private and secure. My apps are set up using UIKit so SwiftData is not an option unless I rewrite the entire app in SwiftUI. Or is there a good way to use SwiftData in UIKit? Is there a way to store/move this information into the cloud so that the data can be synced across multiple devices? Or maybe set up an import/export scenario using a CSV file for the database using Dropbox? Any help or advice would be appreciated. Thanks in advance.
0
0
471
Feb ’24
App running on iOS 17 creates different PDF data from on iOS 16 and earlier
Hello, I have a question about PDF data creation on iOS 17. My app creates PDF data from HTML for printing, and it is not possible to print out the PDF data to a particular printer when the app runs on iOS 17, despite that it works fine on iOS 16 and earlier. The cause of the printing problem is unclear, however, I found that the contents of PDF data are different between iOS 17 and iOS 16 in the following 4 points: PDF version iOS 17: Ver. 1.4 iOS 16: Ver. 1.3 Size of PDF data iOS 17: 100KB iOS 16: 505KB Embedded font iOS 17: HiraginoSans-W5 iOS 16: HiraginoSans-W3 Displayed text size iOS 17: just a little bigger than 14pt iOS 16: 14pt I am hoping that the printing problem can be resolved if my app running on iOS 17 creates the same PDF data as on iOS 16, so my question is: Is there any way to create the same format of PDF data as iOS 16 or earlier when an app is running on iOS 17, especially to create data in version 1.3 of PDF? In my app, I use almost the same as the following code to create PDF data from HTML, and I couldn't find any option to specify a version of PDF for UIPrintPageRenderer, UIMarkupTextPrintFormatter and UIGraphicsPDFContext classes... Any info would be appreciated. Thanks, let htmlString = """ <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=420,height=595, shrink-to-fit=yes" /> <style type="text/css"> * { box-sizing: border-box; font-family: 'Hiragino Mincho ProN', serif; font-size: 1em; line-height: 1; } body { margin: 0; padding: 0; font-size: 14pt; } span.gothic { font-size: 3.5em; font-family: "Helvetica Neue", Helvetica, "Hiragino Sans", sans-serif; } </style> </head> <body> 明朝体のテキスト <span class="gothic">ゴシック体のテキスト</span> </body> </html> """ let render = UIPrintPageRenderer() let paperRect = CGRect(x: 0, y: 0, width: 420.0, height: 595) // A5, 72 dpi render.setValue(paperRect, forKey: "paperRect") let contentsRect = CGRect(x: 0, y: 0, width: 420.0, height: 595) // A5, 72 dpi render.setValue(contentsRect, forKey: "printableRect") let fmt = UIMarkupTextPrintFormatter(markupText: htmlString) render.addPrintFormatter(fmt, startingAtPageAt: 0) let pdfData = NSMutableData() UIGraphicsBeginPDFContextToData(pdfData, paperRect, nil) render.prepare(forDrawingPages: NSMakeRange(0, render.numberOfPages)) let bound = UIGraphicsGetPDFContextBounds() for i in 0..<render.numberOfPages { UIGraphicsBeginPDFPage() render.drawPage(at: i, in: bound) } UIGraphicsEndPDFContext() do { let url = URL(fileURLWithPath:"test.pdf") try pdfData.write(to: url) print("Done") } catch { print("Failed to save", error) }
0
0
532
Feb ’24