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

SwiftData fatal error "Never access a full future backing data"
My app started crashing a ton with Xcode 16 beta 1 / iOS 18 because of "Thread 1: Fatal error: Never access a full future backing data". I was hoping this would be resolved with beta 2, but unfortunately this is not the case. I'm having a tough time reproducing this bug in a small sample project – I'd appreciate any hints as to what might be causing this. Full error: Thread 1: Fatal error: Never access a full future backing data - PersistentIdentifier(id: SwiftData.PersistentIdentifier.ID(url: x-coredata://10A5A93C-DC7F-40F3-92DB-F4125E1C7A73/MyType/p2), implementation: SwiftData.PersistentIdentifierImplementation) with Optional(3BF44A2D-256B-4C40-AF40-9B7518FD9FE6)
0
0
15
1h
MapKit mapItemDetailAccessory Custom View
Hi all, It wasn't extensively covered in the "Unlock the power of places with MapKit" at WWDC, but is it possible to add your own views to the mapItemDetailAccessory? The default view is great, but I would like to add a button for opening a new window showing another view. The documentation is rather limited at the moment so I thought I would ask here. Thanks in advance.
0
0
19
1h
State Restoration: Deleting current state data
In the past, it seemed that if you used the app switcher and killed the app, that state restoration data would not persist, and starting the app again would not load any stored state data. But now (at lest in iOS 17) that is no longer the case. There are situations where the old state might cause issues, which we obviously need to fix, but users should be able to clear the state data. I am not using sessions and am using the older methods - application:shouldSaveApplicationState: and application:shouldRestoreApplicationState:. My question is, how can I tell my users to reset/clear state restoration data if needed?
0
0
18
2h
iOS 18 beta - Cancelling Interactive UICollectionView Layout Transition causes the collectionView to disappear
On iOS18 beta1 & beta2 builds, calling collectionView.cancelInteractiveTransition() after a call to startInteractiveTransition(to:completion:) seems to remove the intermediate transition layout object from the collection view, but doesn't reinstalls the original layout, which results in the collection view disappearing completely. This was not the case in previous iOS versions, so maybe a beta bug? Possibly related, Xcode logs the following error in the console in the exact moment when the collectionView disappears: “Requesting visual style in an implementation that has disabled it, returning nil. Behavior of caller is undefined.” I filled a bug report, together with sample project, just in case FB14057335 Thanks!
0
0
44
8h
How to embed SwiftData model container in a custom file package document type
Hi all, I have done a lot of research on this but am not able to come up with a workable solution. Background: I am trying to make an universal app on macOS/iOS that organizes media (image/video/pdf); think of its functionality like Apple's Photos app. So for my app document type, I would have my custom file package and within the package folder, there would be a SwiftData model container file and folders to hold user media. Approaches taken: DocumentGroup with SwiftData model then write directly into the file package In my App scene, I create document by having DocumentGroup(editing: .customDocument, migrationPlan: CustomMigrationPlan.self). This will create a document with a model container with my SwiftData model. And when I need to add media files into the document, I get the URL of the document, then use FileManager to write the file into the desired folder in the document. The result is that the media file is saved in the file package but then the SwiftData container is corrupted (all model data is reset to empty.) I am now trying to: 2. DocumentGroup with custom file package then try to embed SwiftData container In my current approach, I would create a document by having DocumentGroup(newDocument: CustomFileDocument()). I have custom FileDocument and FileWrapper. But the problem is I don't know how to embed a SwiftData container into my FileDocument. Is it possible to create a SwiftData model container when my FilerWrapper initialize? I can't figure out how to do this. Can anyone please advice on how I should accomplish this? Or if maybe I am looking at this problem wrongly? Do I need to use AppKit/UIKit with Core Data because it's currently not possible with SwiftUI/SwiftData? Thank you so much for reading and any input is greatly appreciated.
0
0
28
8h
SwiftUI onDrop not working with DropDelegate on iOS18
I am new to SwiftUI, and I wrote a ReorderableForEach struct with onDrag and onDrop, which is working well on iOS17. However it's not wokring on iOS18 beta1 or beta2 on my iPhone or simulator. When I long press the item, nothing happens. When I remove onDrop, I can perform a Drag animation, so I think something wrong with my onDrop code. the whole code: import UIKit import SwiftUI public typealias Reorderable = Identifiable & Equatable struct GridData: Identifiable, Equatable { let id: Int } public struct ReorderableForEach<Item: Reorderable, Content: View, Preview: View>: View { @Binding private var active: Item? @State private var hasChangedLocation = false private let items: [Item] private let content: (Item) -> Content private let preview: ((Item) -> Preview)? private let moveAction: (IndexSet, Int) -> Void private var onDropAction: ((Item) -> Void)? private var allowReorder: Bool public init( _ items: [Item], active: Binding<Item?>, allowReorder: Bool, @ViewBuilder content: @escaping (Item) -> Content, @ViewBuilder preview: @escaping (Item) -> Preview, moveAction: @escaping (IndexSet, Int) -> Void, onDropAction: ((Item) -> Void)? = nil ) { self.items = items self._active = active self.allowReorder = allowReorder self.content = content self.preview = preview self.moveAction = moveAction self.onDropAction = onDropAction } public init( _ items: [Item], active: Binding<Item?>, allowReorder: Bool, @ViewBuilder content: @escaping (Item) -> Content, moveAction: @escaping (IndexSet, Int) -> Void, onDropAction: ((Item) -> Void)? = nil ) where Preview == EmptyView { self.items = items self._active = active self.allowReorder = allowReorder self.content = content self.preview = nil self.moveAction = moveAction self.onDropAction = onDropAction } public var body: some View { ForEach(items) { item in if !allowReorder { contentView(for: item) } else if let preview { contentView(for: item) .onDrag { return dragData(for: item) } preview: { preview(item) } } else { contentView(for: item) .onDrag { return dragData(for: item) } } } } private func contentView(for item: Item) -> some View { content(item) .opacity(active == item && hasChangedLocation ? 0.5 : 1) .onDrop( of: [.text], delegate: ReorderableDragRelocateDelegate( item: item, items: items, active: $active, hasChangedLocation: $hasChangedLocation ) { from, to in withAnimation { moveAction(from, to) } } onDropAction: { item in onDropAction?(item) } ) } private func dragData(for item: Item) -> NSItemProvider { active = item return NSItemProvider(object: "\(item.id)" as NSString) } } struct ReorderableDragRelocateDelegate<Item: Reorderable>: DropDelegate { let item: Item var items: [Item] @Binding var active: Item? @Binding var hasChangedLocation: Bool var moveAction: (IndexSet, Int) -> Void var onDropAction: ((Item) -> Void)? func dropEntered(info: DropInfo) { guard item != active, let current = active else { return } guard let from = items.firstIndex(of: current) else { return } guard let to = items.firstIndex(of: item) else { return } hasChangedLocation = true if items[to] != current { moveAction(IndexSet(integer: from), to > from ? to + 1 : to) } } func dropUpdated(info: DropInfo) -> DropProposal? { DropProposal(operation: .move) } func performDrop(info: DropInfo) -> Bool { hasChangedLocation = false active = nil onDropAction?(item) return true } } struct ReorderableDropOutsideDelegate<Item: Reorderable>: DropDelegate { @Binding var active: Item? func dropUpdated(info: DropInfo) -> DropProposal? { DropProposal(operation: .move) } func performDrop(info: DropInfo) -> Bool { active = nil return true } } public extension View { func reorderableForEachContainer<Item: Reorderable>( active: Binding<Item?> ) -> some View { onDrop(of: [.text], delegate: ReorderableDropOutsideDelegate(active: active)) } } #Preview { ReorderableForEach( (1...10).map { GridData(id: $0) }, active: .constant(nil), allowReorder: true ) { item in Text("Item \(item.id)") .padding() .background(Color.blue) .cornerRadius(8) } preview: { item in Text("Preview \(item.id)") .padding() .background(Color.red) .cornerRadius(8) } moveAction: { from, to in print("Move from \(from) to \(to)") } } Am I missing something or this is a bug on iOS18? Thanks in advance.
0
0
30
9h
White text on white background
Whenever I make a new app I end up getting bug reports from people who say they can't see text, or they can just about see white text against an almost white background. It always turns out to be because their phone is in dark mode, which I don't use. Almost all of my views have the background color set to "System background color" which is the default value when you create a view. Why does dark mode change the color of the text but not the background?
1
0
36
9h
iOS18 beta2: NavigationStack, Views Being Popped Automatically
This is a report of an issue that appears to be a regression regarding NavigationStack. I have been aware of an issue where views are being automatically popped within NavigationView / NavigationStack since iOS 15, and it seems to be reoccurring in iOS 18.0 beta2. Below is the reproducible code. Additionally, in my environment, this problem does not occur iOS 18 simulator, but it does happen on an iPhone XS Max(real device) with iOS 18 beta 2. Environment: Xcode: Version 16.0 beta (16A5171c) iOS: 18.0 (22A5297f) iPhone: XS Max (real device) import SwiftUI @main struct iOS16_4NavigationSample2App: App { var body: some Scene { WindowGroup { NavigationStack { NavigationLink { ContentView() } label: { Text("Content") } } } } } enum Kind { case none, a, b, c } struct Value: Hashable, Identifiable { let id: UUID = UUID() var num: Int } @MainActor class ContentModel: ObservableObject { @Published var kind: Kind = .a @Published var vals: [Value] = { return (1...5).map { Value(num: $0) } }() init() {} } struct ContentView: View { @StateObject private var model = ContentModel() @State private var selectedData: Value? @State private var isShowingSubView = false @Environment(\.dismiss) private var dismiss init() { } var body: some View { if #available(iOS 16.0, *) { List(selection: $selectedData) { ForEach(model.vals) { val in NavigationLink(value: val) { Text("\(val.num)") } } } .navigationDestination(isPresented: .init(get: { selectedData != nil }, set: { newValue in if !newValue && selectedData != nil { selectedData = nil } }), destination: { SubView(kind: model.kind) }) } } } struct SubView: View { init(kind: Kind) { print("init(kind:)") } init() { print("init") } var body: some View { Text("Content") } } This code was shared in a different issue [iOS 16.4 NavigationStack Behavior Unstable].
2
0
45
9h
Implementing Undo/Redo Feature in UITextView with IME Support
Currently, we are implementing an undo/redo feature in UITextView. However, we cannot use the built-in UndoManager in UITextView because we have multiple UITextView instances inside a UICollectionView. Since UICollectionView recycles UITextView instances, the same UITextView might be reused in different rows, making the built-in UndoManager unreliable. The shouldChangeTextIn method in UITextViewDelegate is key to implementing undo/redo functionality properly. Here is an example of our implementation: extension ChecklistCell: UITextViewDelegate { func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool { // Get the current text let s = textView.text ?? "" // Get the starting position of the change let start = range.location // Get the number of characters that will be replaced let count = range.length // Get the number of characters that will be added let after = text.count print(">>>> The current text = \"\(s)\"") print(">>>> The starting position of the change = \(start)") print(">>>> The number of characters that will be replaced = \(count)") print(">>>> The number of characters that will be added = \(after)") print(">>>>") if let delegate = delegate, let checklistId = checklistId, let index = delegate.checklistIdToIndex(checklistId) { delegate.attachTextAction(s: s, start: start, count: count, after: after, index: index) } return true } } Working scene behind the UITextViewDelegate However, this implementation does not work well with non-English input using an IME. When using an IME, there is an intermediate input before the final input is produced. For example, typing "wo" (intermediate input) produces "我" (final input). Currently, UITextViewDelegate captures both "wo" and "我". UITextViewDelegate captures both "wo" and "我" Is there a way to ignore the intermediate input from IME and only consider the final input? In Android, we use the beforeTextChanged method in TextWatcher to seamlessly ignore the intermediate input from IME and only consider the final input. You can see this in action in this Android captures only "我" Is there an equivalent way in iOS to ignore the intermediate input from IME and only take the final input into consideration?
0
0
47
15h
Can an automaker app and a Carplay app (when automaker is not possible) live in the same App?
Hi, I'm trying to investigate if there is any way to have an app that displays an automaker app when the Carplay environment has the automaker protocol string, and displays a Carplay App (Driving Task) when there isn't the automaker protocol string. I was able to start developing an automaker app, but with an iOS16.0 deprecated method (with UIScreen Notifications), I'm not able to do it via the scene delegate... There is any kind of documentation of how to do it? I think the clue may be in the scene delegate with the property Preferred Default Scene Session Role, where I think the automaker app is a Window Application Session Role, but the scene delegate is not triggered when I open the Carplay App in the simulator. So am I missing something? Is there a way to do it or have I to publish two apps in order to use the two kind of carplay apps... ? Thank you very much.
1
0
32
16h
Is it possible to loop a ScrollView to repeat infinitely?
I have a horizontal scroll view and a fixed array. I would like to loop it such that when I scroll left and get near the end, the array will add the items in the beginning to the end so that the user can continue to scroll. I would like this to happen when scrolling both left and right and to not have the current position of the user jump around. Here is my code. What am I missing? Would appreciate any and all help. import SwiftUI import Algorithms struct ContentView: View { @State private var timePosition = ScrollPosition(idType: Int.self, edge: .leading) @State private var times: [Int] = Array(0...23) var body: some View { ScrollView(.horizontal, showsIndicators: false) { LazyHStack(spacing: 0) { ForEach(times, id:\.self) { time in Text("\(time)") .font(.system(.callout, design: .monospaced, weight: .semibold)) .padding(8) .frame(width: 180, height: 110, alignment: .topLeading) .border(width: 1, edges: [.leading, .trailing], color: .primary.opacity(0.05)) .id(time) } } .scrollTargetLayout() } .frame(height: 110) .scrollPosition($timeScrollPosition, anchor: .center) .onScrollTargetVisibilityChange(idType: Int.self) { timeIDs in if let currentViewID = model.timeScrollPosition.viewID { if timeIDs.contains(times[times.count - 2]) { times.rotate(toStartAt: times.count - 1) } if timeIDs.contains(times[1]) { times.rotate(toStartAt: times.count-1) } print("New times: \(times)") timeScrollPosition.scrollTo(id: currentViewID) } } } }
0
0
38
17h
Obscuration of Specific Content in Screenshots on visionOS
Hello, I am currently developing an app using visionOS, and I am looking for a way to obscure specific content in screenshots. My app includes certain content that is exclusive to premium users, and I need to hide these parts when screenshots are shared on social media. In iOS, I was able to achieve this by extending SecureField to hide specific Views or Images, but this method does not work in visionOS. I am seeking advice on the best approach to implement this feature in visionOS. https://github.com/yoxisem544/ScreenshotPreventing-iOS Specifically, I would appreciate guidance on the following points: The optimal method for obscuring specific Views or Images in screenshots on visionOS Any tips or tricks when using existing components similar to SecureField Techniques or approaches used by other developers to implement similar features Your assistance would be greatly appreciated. Thank you for your help.
0
0
41
20h
Pop to root view when selected tab is tapped again for WebKit
Hello everyone! I have a WKWebView in my swiftui app and would like to enable to "pop root view when selected tab is tapped again" feature, but I have been unable to figure out how to implement this. Here's the basic code: class TabIdentifierModel:ObservableObject { @Published var tabSelection:TabIdentifier { willSet { if newValue == tabSelection { NotificationCenter.default.post(name: .popRootView, object: nil, userInfo: ["tab": newValue.rawValue]) } } } init() { tabSelection = .home } } struct ContentView: View { @AppStorage(AppStorageKeys.enableShorts) var enableShorts = true @StateObject var storeVM = StoreVM() @StateObject var downloadURLManager = DownloadURLManager.shared @State var downloadViewIsOpen = false // ...... @State var tabSelection = TabIdentifierModel() var body: some View { TabView(selection: $tabSelection.tabSelection) { // ...... WebViewWrapper(url: $libraryTabURL) .tabItem { Label { Text("Library") } icon: { Image(systemName: "folder.fill") } }.tag(TabIdentifier.library) // ...... } .environmentObject(tabSelection) } } Tapping on the tab again doesn't seem to set the value again thus the NotificationCenter.default.post is not sent and the web view is not reloaded. Help would be much appreciated! Thanks in advance!
0
0
48
1d
State restoration in Document-based iOS app
Greetings - If I build an app using DocumentGroup, I get the document picker when the app launches. A good iOS app should restore the state the app was in when it was closed. It seems like with DocumentGroup, when the user leaves my app and the app is killed, the next time they launch it, they have to remember the document they were working on and reopen it. How can I have my DocumentGroup-based app restore the last open document at launch? FB13874563 Thanks - Steve
0
0
43
1d
UI Binding Issue with Consecutive Modal Prompts on Latest iOS Versions
Hi team, Currently, I am using two Modal prompts consecutively to display force update popups based on a condition. However, there's an issue where the UI thread is occasionally not binding properly after dismissing the first prompt. Please ensure that after dismissing the first prompt, the second prompt is not bound. After reviewing everything, I understand this is an iOS core library binding issue and it's occurring from the latest iOS version onwards. Could you please provide me with a solution to resolve this issue? Thank you!
0
0
58
1d
quickLookPreview keyboard issues on macOS
I'm trying to add QuickLook previews to a SwiftUI app which uses Table(). I've added the .quickLookPreview() modifier to my Table(), and added a menu command for invoking it, and if I select that menu item manually, it works fine, but I have two keyboard related issues which are making it difficult to actually ship this functionality: When using the .quickLookPreview() variant for a set of URLs, keyboard navigation between the quicklook previews only works with left/right arrows, but being invoked by a Table, it would make much more sense for up/down arrows to navigate through the previews I set a .keyboardShortcut() on the menu command to use Space, since that's the normally-expected shortcut for quicklook, and it doesn't work. If I set it to some random other key (like "a") it does work, but .space doesn't do anything.
2
0
55
1d