Explore the various UI frameworks available for building app interfaces. Discuss the use cases for different frameworks, share best practices, and get help with specific framework-related questions.

All subtopics

Post

Replies

Boosts

Views

Activity

SwiftUI dropping state changes silently?
Hello all, I have an app that demonstrates how sorting algorithms work. It's written in SwiftUI and uses native geometry objects (Rectangle, etc.) to draw the bars that are demonstrating the sorting algorithm. The application runs just fine on macOS Sonoma and iPadOS 17, if not a little bit slowly because the algorithm and drawing are interlocked to stay in time. When I started working on the app in Xcode 16 and running it on macOS Sequoia, I notice a very unusual change: the algorithm is running significantly faster (104.5 "operations" per second in Sequoia vs. 78.5 in Sonoma), with the nebulous side effect of the visualization noticeably stuttering. The application sometimes looks like it's frozen because several underlying state changes are being reflected in the UI, and when the sorting process is completed, it's supposed to turn all of the rectangles green, but this doesn't happen on the Sequoia/Xcode 16 build unless I open the navigation pane after sorting is completed. I can't find any reference to behavior changes in SwiftUI like this. Is this expected behavior? I thought that if such a significant change was made to SwiftUI's behavior, then Apple would at least inform their developers that they need to adapt their code in an article or a WWDC video. I did file a bug, it's 14025421 in Radar (don't know the correct format for Radar links). I included examples of how the app is supposed to look, along with some source code, and a large number of Instruments traces. I attempted to debug from there, but nothing was out of the ordinary; the traces were almost identical between the release version that runs on Sonoma and the debug build version that runs on Sequoia. Here's the behavior between the two versions on display, for reference. You might have to copy and paste the links, because the editor told me I wasn't allowed to have links to YouTube for whatever reason. Expected behavior, where animations are smooth, but algorithm runs more slowly: https://www.youtube.com/watch?v=UWMXiju8EMg Unexpected behavior, where sort algorithm performance is higher, but animations are choppy, and state changes are skipped: https://www.youtube.com/watch?v=GB0VJo8W7_0
0
0
110
1w
Programatic Haptics
I'm developing an iPhone App that is using on-device speech recognition. I'd like to create a 'buzz' to confirm the word was recognised without having to look at the screen. I can get haptics working from a button; but when I try to attach sensoryfeedback to any view element, it does not fire despite my toggle from successful voice commands variable correctly flipping. Has anyone tried a similar thing with success, or have any ideas? Thanks very much.
0
0
113
1w
Non-tinted image in complications using WidgetKit
I have a watchOS app where a user can select a picture. I’d like the picture to be displayed in a complication. I’m using WidgetKit, and I found out that for some watch faces (rendering mode = accented), the image gets tinted. Instead of the picture, the user sees only a colored box. It appears that using the old framework, ClockKit, it was possible to display an image that gets slightly colored with the tint color on tinted watch faces. I believe this is to ensure backward compatibility of old complications. My question is: can I do the same using WidgetKit? I tried using the widgetAccentable() modifier, but it doesn’t work. Here's an example of what I mean. In the middle complication, instead of the pink square, I'd like to display the user picture.
5
1
210
1w
Confusing SwiftUI error log: "Mutating observable property after view is torn down has no effect"
Hey, I have a setup in my app that I am currently building, that uses @Observable router objects that hold the app's entire navigation state, so that I can easily set it globally and let SwiftUI show the appropriate views accordingly. Each view gets passed in such a router object and there is a global "app" router that the app's root view can access as an entry point: @Observable @MainActor final class AppRouter { static let shared = AppRouter() // Entry point used by the app's root view var isShowingSheet = false // Navigation state let sheetRouter = SheetRouter() // Router that's passed to the sheet view. This router could contain other routers for sheets it will show, and so on } @Observable @MainActor final class SheetRouter { // Example of a "nested" router for a sheet view var path = NavigationPath() var isShowingOtherSheet = false func reset() { path = .init() isShowingOtherSheet = false } } To open a sheet, I have a button like this: @Bindable var appRouter = AppRouter.shared // ... Button("Present") { appRouter.sheetRouter.reset() // Reset sheet router appRouter.isShowingSheet = true // show sheet } This seems to work perfectly fine. However, this produces tons of "error" logs in the console, whenever I open the sheet for a second time: Mutating observable property \SheetRouter.path after view is torn down has no effect. Mutating observable property \SheetRouter.path after view is torn down has no effect. Mutating observable property \SheetRouter.path after view is torn down has no effect. Mutating observable property \SheetRouter.path after view is torn down has no effect. Mutating observable property \SheetRouter.isShowingOtherSheet after view is torn down has no effect. These errors appear when calling the reset() of the sheet view's router before opening the sheet. That method simply resets all navigation states in a router back to their defaults. It's as if the sheetRouter is still connected to the dismissed view from the previous sheet, causing a mutation to trigger these error logs. Am I misusing SwiftUI here or is that a bug? It's also worth mentioning that these error logs do not appear on iOS 17. Only on iOS 18. So it might be a bug but I just want to make sure my usage of these router objects is okay and not a misuse of the SwiftUI API that the runtime previously simply did not catch/notice. Then I'd have to rewrite my entire navigation logic. I do have an example project to demonstrate the issue. You can find it here: https://github.com/SwiftedMind/PresentationBugDemo. I have also filed a feedback for this: FB14162780 STEPS TO REPRODUCE Open the example project. Open the sheet in the ContentView twice by tapping "Present" Close that sheet Open it again. Then the console will show these error logs from above. I'd appreciate any help with this. Cheers
2
2
256
1w
swiftui. need .isVisible() {}. or similar
Im using a lazyvgrid with a customImage View that supports lazy loading of a high res image (otherwise thumb is used) What I'm looking for is some way to initiate my loadFullImage() functionality when the CustomImage view is visible ( onAppear() is not what I need. its called when view is loaded in grid, not when visible ) I've tried variation of this, but they do not work reliably CustomImage(key: key) .background( GeometryReader { proxy in Color.clear .preference(key: ViewVisibleKey.self, value: true) } ) .onPreferenceChange(ViewVisibleKey.self) { isVisible in DispatchQueue.main.async { loadImage(key) } } } Anyone have any suggestions ? either why the code above doesn't work reliably (its like 10%) , or some other way to accomplish this. Thanks
0
0
93
1w
Map behaves differently compared to MKMapView
Hey, I have a problem. I was using MKMapView in my app, and in the view where I had a background at the top of the screen, in the example it was Color.red, it extended all the way to the top of the screen. Now, I wanted to switch to the newer Map and I'm seeing an issue because I'm getting a navigation bar that cuts off my color as I indicated in the picture. Does anyone know why this is happening and if there's another way to achieve this? Steps to reproduce: Change MapView() to Map() to see difference import SwiftUI import MapKit @main struct TestAppApp: App { var body: some Scene { WindowGroup { ContentView() } } } struct ContentView: View { var body: some View { NavigationStack { ScrollView(.vertical) { Color.red .padding(.top, -200) .frame(height: 200) MapView().frame(minHeight: 300) // change this line to Map } .navigationTitle("Title") .navigationBarTitleDisplayMode(.large) } } } private typealias ViewControllerRepresentable = UIViewControllerRepresentable struct MapView: ViewControllerRepresentable { typealias ViewController = UIViewController class Controller: ViewController { var mapView: MKMapView { guard let tempView = view as? MKMapView else { fatalError("View could not be cast as MapView.") } return tempView } override func loadView() { let mapView = MKMapView() view = mapView } } func makeUIViewController(context: Context) -> Controller { Controller() } func updateUIViewController(_ controller: Controller, context: Context) { update(controller: controller) } func update(controller: Controller) { } } #Preview { ContentView() } I got: I want:
0
0
132
1w
Cannot Get ScrollViewReader to scroll reliably across platforms.
I've searched this this all over this forum and the web, and I keep seeing "solutions" that don't actually seem to solve my (simple, I think) case. I'm trying to build a scrolling "conversation" view (think iMessage) where as each new line is added at the bottom, the view scrolls to completely display it. Here's what I've got: struct ConversationView: View { @Environment(GameModel.self) private var gameModel @State var shownSteps: Int = 0 var body: some View { VStack { HStack { Spacer() Button { //...random button actions... } label: { Text("Skip Conversation") } }.padding(5) ScrollViewReader { proxy in List { ForEach (gameModel.conversationPoints) {cp in let ind = gameModel.conversationPoints.firstIndex(of: cp)! if (ind <= shownSteps) { ConversationLineView(step: ind, shownSteps: $shownSteps).border(Color.blue) .id(cp.id) } } }.onChange(of: shownSteps) { a, b in proxy.scrollTo(gameModel.conversationPoints[shownSteps].id, anchor: .bottom)} } } } } Basically "shownSteps" is how many entries there are visible at the moment (out of a pre-populated list of "conversation points"), and every time it changes, I want to scroll to that entry. This looks to me identical to several "working" examples I've found online, and it's obviously close, because it works in some places, but not others: macOS: Code works fine in Sequioa betas, but doesn't scroll (new messages just show up below the bottom of the scroll region) at all in Sonoma. iPadOS: The opposite: Works in 17, doesn't work in 18. (My app doesn't run on phone, but I assume the same for iOS) visionOS: Works in 2.0 betas, haven't checked 1.2. Any ideas?
4
0
141
1w
UIDocumentViewController and multiple windows
I'm trying to migrate my document-based app to UIDocumentViewController so that it can take advantage of the new launch experience in iOS 18. Unfortunately, UIDocumentViewController closes the UIDocument when the document is set to nil or the controller is deallocated. This means you can't have the same document in more than one scene. Is there any way to prevent UIDocumentViewController from closing the document? -Steve
1
0
154
1w
scene(_:continue:) not invoked
Hi all, I recently migrated our app from AppDelegate to SceneDelegate in order to make it available on visionOS. So far it is working, but I have a problem with Universal links not being invoked. I implemented: func scene(_ scene: UIScene, continue userActivity: NSUserActivity) in my Scene Delegate, but it doesn't get invoked after the system opens the app. This only happens, if the app is running in the background. If the app is not running and is launched by the OS, I receive the URL as expected in: func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) If I also implement: func scene(_ scene: UIScene, willContinueUserActivityWithType userActivityType: String) it will be invoked by the OS, but after willContinueUserActivityWithType was called, neither: func scene(_ scene: UIScene, didFailToContinueUserActivityWithType userActivityType: String, error: any Error) nor: func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) are being invoked by the OS. I made a simple Barebones project with the same Bundle ID and the same Entitlements and there: func scene(_ scene: UIScene, continue userActivity: NSUserActivity) is being invoked as expected, upon tapping on the Universal Link in another app. What might be the difference between the two projects causing this behaviour? It is a rather big and old app, so it is difficult for me to compare the simple example project to the real project. Does anybody know, where I could start to debug? Many thanks in advance!
1
0
136
1w
Show animation images using UIImageView
We want to animate the images using animationImages propery of UIImageView in our app. There are 45 heif images with dimensions of 1668x2388. Below is the code i am using to animate images. let imageViewAnimation = UIImageView() imgViewAnimation.animationImages = images imgViewAnimation.animationDuration = 5.0 imgViewAnimation.animationRepeatCount = 1 imgViewAnimation.startAnimating() Timer.scheduledTimer(withTimeInterval: 5.0 + 0.5, repeats: false) { _ in DispatchQueue.main.async { self.showAlert() } } The issue i am facing is, it takes more than 5.0 seconds (animationDuration) to display all the images. Alert is shown before all the images are shown. We face this issue only for few sets of images. For some other sets, it is working fine. Is this issue due to heif images used, or due to memory and CPU load of using large number of images.
2
0
182
1w
SwiftUI and SwiftData projects, textField gets focus, freezes, and takes 7000 milliseconds to focus
macOS 14.5、Xcode 15.4、iPhone OS 18.0 beta Open Xcode and create a new project. Select swiftUI for Interface, Swift for Language, and Swiftdata for Storage. After creating the project, open the ContentView.swift file,write the code @State var username: String = "" TextField("info", text: $username) .textFieldStyle(.roundedBorder) .disableAutocorrection(true) .textInputAutocapitalization(.never) Run the project on iPhone. textField gets focus, freezes, and takes 7000 milliseconds to focus
0
0
114
1w
How to integrate Pencil into my application? I have encountered a problem.
我是个新手。我是UIKit的新手。我真的不知道该怎么办。我的问题是,我希望用铅笔绘制的图纸在PencilCreate中显示,但我不知道如何控制它们的交付。我需要单击HB才能跳转到铅笔视图界面。然后,铅笔视图界面中绘制的内容可以显示在PencilCreate的.border中。 导入SwiftUI 导入 PencilKit struct GrPencil:查看{ var body:一些视图{ 导航堆栈{ 画布视图() } } } struct CanvasView:UIViewRepresentable { @State var canvasView:PKCanvasView = PKCanvasView() @State var toolPicker = PKToolPicker() func makeUIView(上下文:上下文)-> PKCanvasView { canvasView.drawingPolicy = .anyInput canvasView.becomeFirstResponder() toolPicker.setVisible(true,forFirstResponder:canvasView) toolPicker.addObserver(canvasView) 返回canvasView } func updateUIView(_ uiView: PKCanvasView, context: Context) { } } #预览 { GrPencil() } 导入SwiftUI 导入 PencilKit struct PencilCreate:查看{ @State var drawing = PKDrawing() var body:一些视图{ VStack { VStack { 图像(uiImage:drawing.image(来自:drawing.bounds,比例:1)) .resizable() .框架(宽度:200,高度:120) .border(颜色.黑色) 按钮{ }标签:{ 文本(“HB”) } } } } } #预览 { PencilCreate() }
0
0
89
1w
Is it Possible to save AttributedString with image to RTF doc?
Hello, I am trying to implement an RTF document export feature on a small app. But after days of trying and failing with dozens of approaches I’m beginning to wonder if it is even possible to create an .rtf file with embedded text and images in Swift/SwiftUI. I’ve tried many variations of (A) building the text and image content with HTML, converting it to AttributedString, then exporting to RTF, and (B) building the text and image content directly with AttributedString attributes and attachments for the image — and in both cases, the images are not saved in the RTF file. I am able to create a preview of the AttributedString with formatted text and image, and able to create an RTF file with formatted text that opens with TextEdit, Pages and Word without issue; but cannot get the image to appear in the saved RTF file. I’m hoping someone here can shed some light on if this is possible and if yes, how to save the combined text and image data to an RTF file. Here is the latest variation of the code I’m using — any ideas/suggestions are appreciated 🙏🏽: import SwiftUI struct ContentView: View { @State private var showExportSheet = false @State private var rtfData: Data? @State private var isLoading = false @State private var previewAttributedString: NSAttributedString? var body: some View { VStack { Button("Export RTF with Image") { isLoading = true createRTFWithEmbeddedImage() } .disabled(isLoading) if isLoading { ProgressView() } if let previewAttributedString = previewAttributedString { VStack { Text("Preview:") .font(.headline) TextView(attributedString: previewAttributedString) .frame(minWidth: 0, maxWidth: .infinity, minHeight: 200, maxHeight: .infinity) .background(Color.gray.opacity(0.1)) } .padding() } } .sheet(isPresented: $showExportSheet) { DocumentPicker(rtfData: $rtfData) } } func createRTFWithEmbeddedImage() { let text = "This is a sample RTF document with an embedded image:" // Load the image (star.fill as a fallback) guard let image = UIImage(systemName: "star.fill") else { print("Failed to load image") isLoading = false return } // Resize the image to 100x100 pixels let resizedImage = resizeImage(image: image, targetSize: CGSize(width: 100, height: 100)) // Convert image to NSTextAttachment let attachment = NSTextAttachment() attachment.image = resizedImage // Set bounds for the image attachment.bounds = CGRect(x: 0, y: 0, width: 100, height: 100) // Create attributed string with the attachment let attributedString = NSMutableAttributedString(string: text) let attachmentString = NSAttributedString(attachment: attachment) attributedString.append(attachmentString) // Add red border around the image attributedString.addAttribute(.strokeColor, value: UIColor.red, range: NSRange(location: attributedString.length - attachmentString.length, length: attachmentString.length)) attributedString.addAttribute(.strokeWidth, value: -2.0, range: NSRange(location: attributedString.length - attachmentString.length, length: attachmentString.length)) // Set previewAttributedString for preview self.previewAttributedString = attributedString // Convert attributed string to RTF data guard let rtfData = try? attributedString.data(from: NSRange(location: 0, length: attributedString.length), documentAttributes: [.documentType: NSAttributedString.DocumentType.rtf]) else { print("Failed to create RTF data") isLoading = false return } self.rtfData = rtfData isLoading = false showExportSheet = true // Debug: Save RTF to a file in the Documents directory saveRTFToDocuments(rtfData) } func resizeImage(image: UIImage, targetSize: CGSize) -> UIImage { let size = image.size let widthRatio = targetSize.width / size.width let heightRatio = targetSize.height / size.height let newSize: CGSize if widthRatio > heightRatio { newSize = CGSize(width: size.width * heightRatio, height: size.height * heightRatio) } else { newSize = CGSize(width: size.width * widthRatio, height: size.height * widthRatio) } let rect = CGRect(origin: .zero, size: newSize) UIGraphicsBeginImageContextWithOptions(newSize, false, 1.0) image.draw(in: rect) let newImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return newImage ?? UIImage() } func saveRTFToDocuments(_ data: Data) { let fileManager = FileManager.default guard let documentsDirectory = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first else { print("Unable to access Documents directory") return } let fileURL = documentsDirectory.appendingPathComponent("debug_output.rtf") do { try data.write(to: fileURL) print("Debug RTF file saved to: \(fileURL.path)") } catch { print("Error saving debug RTF file: \(error)") } } } struct DocumentPicker: UIViewControllerRepresentable { @Binding var rtfData: Data? func makeUIViewController(context: Context) -> UIDocumentPickerViewController { let tempURL = FileManager.default.temporaryDirectory.appendingPathComponent("document_with_image.rtf") do { try rtfData?.write(to: tempURL) } catch { print("Error writing RTF file: \(error)") } let picker = UIDocumentPickerViewController(forExporting: [tempURL], asCopy: true) return picker } func updateUIViewController(_ uiViewController: UIDocumentPickerViewController, context: Context) {} } struct TextView: UIViewRepresentable { let attributedString: NSAttributedString func makeUIView(context: Context) -> UITextView { let textView = UITextView() textView.isEditable = false textView.attributedText = attributedString return textView } func updateUIView(_ uiView: UITextView, context: Context) { uiView.attributedText = attributedString } } Thank in advance!
2
0
157
1w
Question about preview using code in SwiftUI
Hello, I have a view which have a few controls and preview macro. I replaced preview macro with following code: struct ContentView_Preview:PreviewProvider{ static var previews: some View{ ContentView() } } after replacement, preview doesn't work properly. plz tell me how can i fix it. thanks, c00012
2
0
133
1w
Large Title Navigation Bar Problems with Two Views
As has been posted a number of times, the large title navigation bar only collapses on scrolling for the UIView listed first in an .xib or storyboard file. In my case, I have an enclosing view containing 2 Views, a TableView and a CollectionView in an .XIB file. This is connected to a UIKit class. Tapping a button switches between the two views. If the TableView is the first view listed, the navigationbar collapses with scrolling but with the CollectionView listed second, the large title navigation bar doesn't collapse with scrolling. Alternatively, if the CollectionView is the first view listed, the navigation bar collapses with scrolling but with the TableView listed second, the large title navigation bar doesn't collapse with scrolling. I have not been able to figure out a way to enable the collapsable large title navigation bar to work in such a scenario as mine for both views within a container view. Is there a way to do this? I have tested this capability through iOS 17.
2
0
207
1w
SwiftUI Previews not working with Firebase in Xcode 16.0 beta
The SwiftUI previews have been working fine in Xcode 16.0 beta, but ever since I added Firebase into my app, I've been getting error with previews. CrashReportError: IshaanCord crashed IshaanCord crashed. Check ~/Library/Logs/DiagnosticReports for crash logs from your application. Process: IshaanCord[5651] Date/Time: 2024-07-04 19:29:51 +0000 Log File: <none> "Cannot preview in this file" Does anyone know how to fix this? Thank you.
2
0
231
1w
Is it possible to use a list-style UICollectionView but have multiple columns?
I'm working on a UICollectionView that has a custom compositional layout with multiple columns. I wanted to add swipe actions to the cells (specifically, a delete action). I knew this was possible because of the existence of trailingSwipeActionsConfigurationProvider but I didn't realize that this is only for list layouts, created with UICollectionViewCompositionalLayout.list. But if I use a list layout, I don't think I have any opportunity to add multiple columns. Do I really have to choose between multiple columns and trailing swipe actions? Or is there some way to get both?
0
0
132
1w