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
Posts under UI Frameworks topic

Post

Replies

Boosts

Views

Activity

Does adding a bar button item to the navigation bar programmatically when offering scene support differ from the old app delegate approach
I have used the following code for years to add a right bar button item to the navigation bar, but for some unknown reason, this no longer works. It stopped working when I updated my app to have Scene support. I don't understand what is preventing this code from working. @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. NSLog(@"viewDidLoad"); // Add a Share Button UIBarButtonItem *shareButton; shareButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAction target:self action:@selector(editProject:)]; self.navigationItem.rightBarButtonItem = shareButton; self.navigationItem.rightBarButtonItem.tintColor = [UIColor blueColor]; } -(void) editProject:(id)sender { } @end To test this, I created a brand new test app that does nothing except for attempting to add this button. The autogenerated code gives you the following project and I simply modified the ViewController class as shown above: What do I need to do differently to make the right bar button item to display? I know that I can add buttons using the storyboard that can be controlled via IBOutlets, but just want to know if its still possible to do this programmatically.
3
0
170
May ’25
Some sharing extensions disabled when running iOS app with Mac Catalyst
When I run my iOS app on a Mac using Mac Catalyst, several sharing options that show up on an iOS device in a share sheet are absent on the Mac. Clicking on Edit Extensions, I see Mail, Message and AirDrop, their switches are on and disabled. All three items show up when I share from Safari or Notes. How can I make Mail, Message and AirDrop available? For example, when sharing data, no share extensions are shown. For text, only Simulator, Shortcuts and Copy are shown.
0
0
115
Jun ’25
Display a broader track of a user on ios app with Mapkit.
Hello I'm currently building a feature within an ios app using SwiftUI and Mapkit to record the gps cordinates of a user as they move and render the track on the map. the idea is not really to have a "track" but to have a visual representation of the area the user sees while they are moving around. I need this width/breadth to be relative to the map and not the screen, such that when I zoom in and out of the map, the size will adjust automatically.
0
0
85
May ’25
Mixing ReferenceFileDocument and @Observable
I have an app in which the data model is @Observable, and views see it through @Environment(dataModel.self) private var dataModel. Since there are a large number of views, only some of which may need to be redrawn at a given time, I believe that @Observable is more efficient at run time than @Published and @ObservedObject I’ve been trying to make the app document based. Although I started using SwiftData, it has trouble with Codable, and a long thread in the Developer forum suggests that SwiftData does not support the Undo manager - and in any event, simple JSON serialization is all that this app requires. Unfortunately, ReferenceFileDocument inherits from ObservableObject, which seems to not play nice with @Observable. I’d like to keep using @Observable, but haven’t been able to figure out how. When I deserialize a JSON ReferenceFileDocument, I can’t seem to connect it to an @Observable class instance and to let the various views and view models know where to find and update it. I’d appreciate advice on how to implement document persistence in this app. Also, the default behaviour of DoumentGroup provides a nice menu to, another things, rename a new file to something other than Untitled xx, but it doesn’t appear to work (there is an extensive thread on the Developer website discussing this issue). Is there a solution to this problem? Thanks for any help you can offer.
3
0
176
May ’25
How to replace layoutManager with textLayoutManager for a flexible dynamic height UITextView
In order to create a UITextView like that of the Messages app whose height grows to fits its contents (number of lines), I subclassed UITextView and customized the intrinsicContentSize like so: override var intrinsicContentSize: CGSize { var size = super.intrinsicContentSize if size.height == UIView.noIntrinsicMetric { layoutManager.glyphRange(for: textContainer) size.height = layoutManager.usedRect(for: textContainer).height + textContainerInset.top + textContainerInset.bottom } return size } As noted at WWDC, accessing layoutManager will force TextKit 1, we should instead use textLayoutManager. How can this code be migrated to support TextKit 2?
3
0
226
Jun ’25
Application crashes when using TextEditor(text, selection)
I have a TextEditor, to the constructor of which in addition to the text I pass an object of the TextSelection? type. I check on the Simulator with iOS 18.2. An attempt to clear the text leads to a crash with the message "Thread 1: Fatal error: String index is out of bounds" in Xcode. More about the error: libswiftCore.dylib`_swift_runtime_on_report: -> 0x194f32024 <+0>: ret More about the reproduction conditions: struct MyView: View { @Bindable private var viewModel = MyViewModel() @State var myTextSelection: TextSelection? = nil var body: some View { ZStack { // Some other code myEditor // Some other code } .toolbar { ToolbarItem(placement: .primaryAction) { Button { viewModel.clear() } label: { Label("Clear", systemImage: "eraser") } } } } var myEditor: some View { ZStack(alignment: .topLeading) { TextEditor(text: $viewModel.text, selection: $myTextSelection) .disableAutocorrection(true) .autocapitalization(.sentences) } // Some other code } } MyViewModel: @Observable final class MyViewModel: ObservableObject { var text: String = "" func clear() { text = "" } }
1
0
141
May ’25
Core Transferable Error
I'm developing an app that uses the SwiftUI .photosPicker modifier to allow the user to open videos from their photos. While many videos successfully load, one video results in the following errors occurring: Error loading com.apple.quicktime-movie: <decode: bad range for [%@] got [offs:100 len:1229 within:0]> Error loading public.movie: <decode: bad range for [%@] got [offs:87 len:1229 within:0]> "The operation couldn’t be completed. (CoreTransferable.TransferableSupportError error 0.)" I was able to isolate the line of code within the Transferable where this occurs to be the following: try FileManager.default.copyItem(at: received.file, to: destination) Is there something that I can do to ensure the app can reliably open any video? The entire transferable struct is as follows: import Foundation import CoreTransferable import UniformTypeIdentifiers struct Video: Transferable { let url: URL let filename: String static var transferRepresentation: some TransferRepresentation { FileRepresentation(contentType: .mpeg4Movie) { video in SentTransferredFile(video.url) } importing: { received in try Video.transfer(from: received) } FileRepresentation(contentType: .quickTimeMovie) { video in SentTransferredFile(video.url) } importing: { received in try Video.transfer(from: received) } FileRepresentation(contentType: .avi) { video in SentTransferredFile(video.url) } importing: { received in try Video.transfer(from: received) } FileRepresentation(contentType: .mpeg) { video in SentTransferredFile(video.url) } importing: { received in try Video.transfer(from: received) } FileRepresentation(contentType: .mpeg2Video) { video in SentTransferredFile(video.url) } importing: { received in try Video.transfer(from: received) } FileRepresentation(contentType: .video) { video in SentTransferredFile(video.url) } importing: { received in try Video.transfer(from: received) } FileRepresentation(contentType: .movie) { video in SentTransferredFile(video.url) } importing: { received in try Video.transfer(from: received) } } static func transfer(from received: ReceivedTransferredFile) throws -> Video { let destination = FileManager.default.temporaryDirectory.appendingPathComponent(received.file.lastPathComponent) if FileManager.default.fileExists(atPath: destination.path) { try FileManager.default.removeItem(at: destination) } try FileManager.default.copyItem(at: received.file, to: destination) return Video(url: destination, filename: received.file.lastPathComponent) } }
1
0
359
Jun ’25
UIPageViewController embedded in UIScrollView ignores the first pan gesture on its pages
I have a UIPageViewController embedded in a UIScrollView and each page has a drawing view with a UIPanGestureRecognizer to free-draw. With this setup, the 1st time I attempt to draw, the pan gesture is ignored. It works the 2nd time I perform the gesture. In my case I need to wrap the UIPageViewController in a UIScrollView to have a pull to refresh mechanism (set thescrollView.refreshControl). I’ve tried every combination of UIGestureRecognizerDelegate methods (shouldRecognizeSimultaneously…, require(toFail:), etc.) with no luck. This is my view hierarchy: ScrollView |- UIPageViewController |- Page 1 | |- DrawingView with UIPanGestureRecognizer |- Page 2 |- DrawingView with UIPanGestureRecognizer Is this a known limitation when a UIPageViewController is nested inside another scroll view? Reproduction steps (tested on iOS 18.4 / Xcode 16.3, iPhone 16 Pro) Launch the app; the first page shows a white canvas in the bottom part. Try to draw immediately → nothing happens. Lift your finger and draw again → works. Here is a link for the sample project with the reproducible code: https://github.com/marcod-storyteller/page-controller-sample P.S: If the UIPageViewController has a .pageCurl transition style instead, the problem disappears.
Topic: UI Frameworks SubTopic: UIKit Tags:
2
1
124
May ’25
SwiftUI TextEditor undo button
I'm using SwiftUI's TextEditor. I'd like to include an undo button in my UI that operates on the TextEditor. I don't see a way to hook this up. You can get the UndoManager from the environment, but this is not the undo manager the TextEditor is using. I know that UITextView uses an undocumented UndoManager (_UITextUndoManager) and I've accessed that before when using a UIViewRepresentable wrapper around UITextView. I'd like to achieve the same with TextEditor.
Topic: UI Frameworks SubTopic: SwiftUI
0
0
104
Jun ’25
How to hide the tab bar in SwiftUI's TabView for macOS?
In SwiftUI for macOS, how can I hide the tab bar when using TabView? I would like to provide my own tab bar implementation. In AppKit's NSTabViewController, we can do the following: let tabViewController = NSTabViewController() tabViewController.tabStyle = .unspecified I've come across various posts that suggest using the .toolbar modifier, but none appear to work on macOS (or at least I haven't found the right implementation). struct ContentView: View { var body: some View { TabView { // ... content } <- which view modifier hides the tab bar? } } Latest macOS, Latest Xcode
3
0
262
May ’25
Issues with .zoom NavigationTransition to a sheet with a .medium detent
When using a .zoom navigation transition, where .matchedTransitionSource is applied to a button in a toolbar and the destination view is a sheet which is presented with PresentationDetent.medium, the transition works initially, but shortly after it completes, the sheet's background is dimmed and the text of the source button reappears abruptly. Code and a screenshot are below, though the effect is best observed when interacting with the view. // // ContentView.swift // ZoomNavigationTransitionSample // // Created by Matthew DuBois on 6/15/25. // import SwiftUI struct ContentView: View { @State private var isPresentingSheet = false @Namespace private var namespace var body: some View { NavigationStack { List { Text("Some content") } .navigationTitle("Sample") .toolbar { ToolbarItem(placement: .topBarTrailing) { Button("Button") { isPresentingSheet = true } .matchedTransitionSource(id: "button", in: namespace) } } .sheet(isPresented: $isPresentingSheet) { Text("Some sheet content") .navigationTransition(.zoom(sourceID: "button", in: namespace)) .presentationDetents([.medium]) } } } } #Preview { ContentView() }
1
1
159
Jun ’25
AVAudioSession dropping wired USBAudio source
My app inputs electrical waveforms from an IV485B39 2 channel USB device using an AVAudioSession. Before attempting to acquire data I make sure the input device is available as follows: AVAudiosSession *audioSession = [AVAudioSession sharedInstance]; [audioSession setCategory :AVAudioSessionCategoryRecord error:&err]; NSArray *inputs = [audioSession availableInputs]; I have been using this code for about 10 years. My app is scriptable so a user can acquire data from the IV485B29 multiple times with various parameter settings (sampling rates and sample duration). Recently the scripts have been failing to complete and what I have notice that when it fails the list of available inputs is missing the USBAudio input. While debugging I have noticed that when working properly the list of inputs includes both the internal microphone as well as the USBAudio device as shown below. VIB_TimeSeriesViewController:***Available inputs = ( "<AVAudioSessionPortDescription: 0x11584c7d0, type = MicrophoneBuiltIn; name = iPad Microphone; UID = Built-In Microphone; selectedDataSource = Front>", "<AVAudioSessionPortDescription: 0x11584cae0, type = USBAudio; name = 485B39 200095708064650803073200616; UID = AppleUSBAudioEngine:Digiducer.com :485B39 200095708064650803073200616:000957 200095708064650803073200616:1; selectedDataSource = (null)>" ) But when it fails I only see the built in microphone. VIB_TimeSeriesViewController:***Available inputs = ( "<AVAudioSessionPortDescription: 0x11584cef0, type = MicrophoneBuiltIn; name = iPad Microphone; UID = Built-In Microphone; selectedDataSource = Front>" ) If I only see the built in microphone I immediately repeat the three lines of code and most of the "inputs" contains both the internal microphone and the USBAudioDevice AVAudiosSession *audioSession = [AVAudioSession sharedInstance]; [audioSession setCategory :AVAudioSessionCategoryRecord error:&err]; NSArray *inputs = [audioSession availableInputs]; This fix always works on my M2 iPadPro and my iPhone 14 but some of my customers have older devices and even with 3 tries they still get faults about 1 in 10 tries. I rolled back my code to a released version from about 12 months ago where I know we never had this problem and compiled it against the current libraries and the problem still exists. I assume this is a problem caused by a change in the AVAudioSession framework libraries. I need to find a way to work around the issue or get the library fixed.
0
0
153
May ’25
How to show lanes in carplay programatically
Hello all, I'm confused about how to show lanes in CarPlay. I understand CPLaneGuidance and CPLane I don't find anywhere where to tell Carplay which icon to show for each lane. I've found some information saying we put the icon in CPManeuver, but then CPManeuver is linked to only one CPLaneGuidance, and we can put only one icon in CPManeuver. At the same time, we might have multiple lanes. Any help, tips, or examples would be highly helpful.
0
0
73
Jun ’25
`SwiftUI.Table` Select and Done buttons breaking navigation on iPadOS?
https://github.com/apple/sample-food-truck Hi! I'm following along with the sample-food-truck application from WWDC 2022. I'm seeing some weird navigation issues when building the app for iPadOS. The Table component displays a Select Button for selecting elements and a Done Button disabling that state. These buttons seem to be breaking something about navigation on iOS 18.4.1. It's a nondeterministic issue… but tapping the buttons seems to lead to some corrupt state where the app transitions out of OrdersView and back to TruckView. This code from FoodTruckModel seems to be making a difference: Task(priority: .background) { var generator = OrderGenerator.SeededRandomGenerator(seed: 5) for _ in 0..<20 { try? await Task.sleep(nanoseconds: .secondsToNanoseconds(.random(in: 3 ... 8, using: &generator))) Task { @MainActor in withAnimation(.spring(response: 0.4, dampingFraction: 1)) { self.orders.append(orderGenerator.generateOrder(number: orders.count + 1, date: .now, generator: &generator)) } } } } Commenting out that code and disabling the new Order values coming in seems to fix the issue. Is there any public documentation for me to learn about the Select and Done buttons? I don't see anywhere for me to learn about how these work and what my ability is to customize their behavior. Any ideas? I can repro from device and simulator.
2
0
125
May ’25
Clustering on MapKit for SwiftUI iOS17+
Hi What would be the best way to achieve clustering on MapKit within SwiftUI? We're building a decentralized commerce auction platform that is currently live in Switzerland with 3'500 live auctions that can be discovered on a map. We're now running into the issue that the map gets cluttered, when zooming out and haven't been able to find a way to cluster We moved back to UIKit, where clustering works, but UIKit has other drawdowns. So ideally there is a way to handle it within SwiftUI without having to wrap UIKit or move back entirely to UIKit. Thanks for any help or suggestions! Developer Documentation https://developer.apple.com/documentation/mapkit/mapkit-for-swiftui Julius Ilg AuctionShack
2
1
265
Jun ’25
The NSTextViewDelegate method textViewDidChangeSelection(:) will not fire, while all other text view delegate methods do.
I am trying to implement the NSTextViewDelegate function textViewDidChangeSelection(_ notification: Notification). My text view's delegate is the Coordinator of my NSViewRepresentable. I've found that this delegate function never fires, but any other delegate function that I implement, as long as it doesn't take a Notification as an argument, does fire (e.g., textView(:willChangeSelectionFromCharacterRange:toCharacterRange:), fires and is called on the delegate exactly when it should be). For context, I've verified all of the below: textView.isSelectable = true textView.isEditable = true textView.delegate === my coordinator I can call textViewDidChangeSelection(:) directly on the delegate without issue. I can select and edit text without issues. I.e., the selections are being set correctly. But the delegate method is never called when they are. I am able to add the intended delegate as an observer for the selector textViewDidChangeSelection via NotificationCenter. If I do this, the function executes when it should, but fires for every text view in my view hierarchy, which can number in the hundreds. I'm using an NSLayoutManager, so I figure this should only fire once. I've added a check within my code: func textViewDidChangeSelection(_ notification: Notification) { guard let textView = notification.object as? NSTextView, textView === layoutManager.firstTextView else { return } // Any code I want to execute... } But the above guard check lets through every notification, so, no matter what, my closure executes hundreds of times if I have hundreds of text views, all of them being sent by textView === layoutManager.firstTextView, but once for each and every text view managed by that layoutManager. Does anyone know why this method isn't ever called on the delegate, while seemingly all other delegate methods are? I could go the NotificationCenter route, but I'd love to know why this won't execute as a delegate method when documentation says that it should, and I don't want to have to implement a counter to make sure my code only executes once per selection update. And for more reasons than that, implementing via delegate method is preferable to using notifications for my use case. Thanks for any help!
3
0
267
May ’25
Search in a bottom toolbar
Dear all, The Search fields documentation appears to make a distinction between putting a search in a tab bar and in a bottom toolbar in an iOS device. Putting a search in a tab bar in iOS26 appears to be quick and easy: Tab(role: .search) { // Search } I cannot find, however, a way on how to put a search bar in a bottom toolbar (as illustrated here). The following code puts it in the top toolbar: .searchable(text: $searchQuery, placement: .toolbar) Same as this one: .searchable(text: $searchQuery, placement: .toolbarPrincipal) Do I miss something in this regard? Thanks!
1
0
292
Jun ’25
NSLayoutManager Bug -- layout manager re-laying out overlapping text into the same container.
I've posted a couple times now about major issues I'm having with NSLayoutManager and have written to Apple for code-level support, but no one at Apple has responded to me in more than two weeks. So I'm turning to the community again for any help whatsoever. I'm fairly certain it's a real bug in TextKit. If I'm right about that, I'd love for anyone at Apple to take an interest. And better yet, if I'm wrong (and I hope I am), I'd be incredibly grateful to anyone who can point out where my mistake lies! I've been stuck with this bug for weeks on end. The crux of the issue is that I'm getting what seemed to be totally incompatible results from back to back calls to textContainer(forGlyphAt:effectiveRange:) and lineFragmentRect(forGlyphAt:effectiveRange:withoutAdditionalLayout:)... I'd lay out my text into a fairly tall container of standard page width and then query the layout manager for the text container and line fragment rect for a particular glyph (a glyph that happens to fall after many newlines). Impossibly, the layout manager would report that that glyph was in said very tall container, but that the maxY of its lineFragmentRect was only at 14 points (my NSTextView's isFlipped is true, so that's 14 points measuring from the top down). After investigating, it appears that what is happening under the hood is NSLayoutManager is for some reason laying out text back into the first container in my series of containers, rather than overflowing it into the next container(s) and/or giving me a nil result for textContainer(forGlyphAt:...) I've created a totally stripped down version of my project that recreates this issue reliably and I'm hoping literally anyone at Apple will respond to me. In order to recreate the bug, I've had to build a very specific set of preview data - namely some NSTextStorage content and a unique set of NSTextViews / NSTextContainers. Because of the unique and particular setup required to recreate this bug, the code is too much to paste here (my preview data definition is a little unwieldy but the code that actually processes/parses it is not). I can share the project if anyone is able and willing to look into this with me. It seems I'm not able to share a .zip of the project folder here but am happy to email or share a dropbox link.
7
0
343
May ’25
iOS 26: TextEditor and Text Attachments
Does the new TextEditor in iOS 26, which supports rich text / AttributedString, also support the ability to add text attachments or tokens? For example, in Xcode, we can type <#foo#> to create an inline text placeholder/token which can be interacted with in a different way than standard text.
Replies
1
Boosts
0
Views
175
Activity
Jun ’25
Does adding a bar button item to the navigation bar programmatically when offering scene support differ from the old app delegate approach
I have used the following code for years to add a right bar button item to the navigation bar, but for some unknown reason, this no longer works. It stopped working when I updated my app to have Scene support. I don't understand what is preventing this code from working. @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. NSLog(@"viewDidLoad"); // Add a Share Button UIBarButtonItem *shareButton; shareButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAction target:self action:@selector(editProject:)]; self.navigationItem.rightBarButtonItem = shareButton; self.navigationItem.rightBarButtonItem.tintColor = [UIColor blueColor]; } -(void) editProject:(id)sender { } @end To test this, I created a brand new test app that does nothing except for attempting to add this button. The autogenerated code gives you the following project and I simply modified the ViewController class as shown above: What do I need to do differently to make the right bar button item to display? I know that I can add buttons using the storyboard that can be controlled via IBOutlets, but just want to know if its still possible to do this programmatically.
Replies
3
Boosts
0
Views
170
Activity
May ’25
Some sharing extensions disabled when running iOS app with Mac Catalyst
When I run my iOS app on a Mac using Mac Catalyst, several sharing options that show up on an iOS device in a share sheet are absent on the Mac. Clicking on Edit Extensions, I see Mail, Message and AirDrop, their switches are on and disabled. All three items show up when I share from Safari or Notes. How can I make Mail, Message and AirDrop available? For example, when sharing data, no share extensions are shown. For text, only Simulator, Shortcuts and Copy are shown.
Replies
0
Boosts
0
Views
115
Activity
Jun ’25
Display a broader track of a user on ios app with Mapkit.
Hello I'm currently building a feature within an ios app using SwiftUI and Mapkit to record the gps cordinates of a user as they move and render the track on the map. the idea is not really to have a "track" but to have a visual representation of the area the user sees while they are moving around. I need this width/breadth to be relative to the map and not the screen, such that when I zoom in and out of the map, the size will adjust automatically.
Replies
0
Boosts
0
Views
85
Activity
May ’25
Generic parameter 'V' could not be inferred Xcode error Please help
Generic parameter 'V' could not be inferred ERROR
Replies
7
Boosts
0
Views
7.8k
Activity
Jun ’25
Mixing ReferenceFileDocument and @Observable
I have an app in which the data model is @Observable, and views see it through @Environment(dataModel.self) private var dataModel. Since there are a large number of views, only some of which may need to be redrawn at a given time, I believe that @Observable is more efficient at run time than @Published and @ObservedObject I’ve been trying to make the app document based. Although I started using SwiftData, it has trouble with Codable, and a long thread in the Developer forum suggests that SwiftData does not support the Undo manager - and in any event, simple JSON serialization is all that this app requires. Unfortunately, ReferenceFileDocument inherits from ObservableObject, which seems to not play nice with @Observable. I’d like to keep using @Observable, but haven’t been able to figure out how. When I deserialize a JSON ReferenceFileDocument, I can’t seem to connect it to an @Observable class instance and to let the various views and view models know where to find and update it. I’d appreciate advice on how to implement document persistence in this app. Also, the default behaviour of DoumentGroup provides a nice menu to, another things, rename a new file to something other than Untitled xx, but it doesn’t appear to work (there is an extensive thread on the Developer website discussing this issue). Is there a solution to this problem? Thanks for any help you can offer.
Replies
3
Boosts
0
Views
176
Activity
May ’25
How to replace layoutManager with textLayoutManager for a flexible dynamic height UITextView
In order to create a UITextView like that of the Messages app whose height grows to fits its contents (number of lines), I subclassed UITextView and customized the intrinsicContentSize like so: override var intrinsicContentSize: CGSize { var size = super.intrinsicContentSize if size.height == UIView.noIntrinsicMetric { layoutManager.glyphRange(for: textContainer) size.height = layoutManager.usedRect(for: textContainer).height + textContainerInset.top + textContainerInset.bottom } return size } As noted at WWDC, accessing layoutManager will force TextKit 1, we should instead use textLayoutManager. How can this code be migrated to support TextKit 2?
Replies
3
Boosts
0
Views
226
Activity
Jun ’25
Application crashes when using TextEditor(text, selection)
I have a TextEditor, to the constructor of which in addition to the text I pass an object of the TextSelection? type. I check on the Simulator with iOS 18.2. An attempt to clear the text leads to a crash with the message "Thread 1: Fatal error: String index is out of bounds" in Xcode. More about the error: libswiftCore.dylib`_swift_runtime_on_report: -> 0x194f32024 <+0>: ret More about the reproduction conditions: struct MyView: View { @Bindable private var viewModel = MyViewModel() @State var myTextSelection: TextSelection? = nil var body: some View { ZStack { // Some other code myEditor // Some other code } .toolbar { ToolbarItem(placement: .primaryAction) { Button { viewModel.clear() } label: { Label("Clear", systemImage: "eraser") } } } } var myEditor: some View { ZStack(alignment: .topLeading) { TextEditor(text: $viewModel.text, selection: $myTextSelection) .disableAutocorrection(true) .autocapitalization(.sentences) } // Some other code } } MyViewModel: @Observable final class MyViewModel: ObservableObject { var text: String = "" func clear() { text = "" } }
Replies
1
Boosts
0
Views
141
Activity
May ’25
Core Transferable Error
I'm developing an app that uses the SwiftUI .photosPicker modifier to allow the user to open videos from their photos. While many videos successfully load, one video results in the following errors occurring: Error loading com.apple.quicktime-movie: <decode: bad range for [%@] got [offs:100 len:1229 within:0]> Error loading public.movie: <decode: bad range for [%@] got [offs:87 len:1229 within:0]> "The operation couldn’t be completed. (CoreTransferable.TransferableSupportError error 0.)" I was able to isolate the line of code within the Transferable where this occurs to be the following: try FileManager.default.copyItem(at: received.file, to: destination) Is there something that I can do to ensure the app can reliably open any video? The entire transferable struct is as follows: import Foundation import CoreTransferable import UniformTypeIdentifiers struct Video: Transferable { let url: URL let filename: String static var transferRepresentation: some TransferRepresentation { FileRepresentation(contentType: .mpeg4Movie) { video in SentTransferredFile(video.url) } importing: { received in try Video.transfer(from: received) } FileRepresentation(contentType: .quickTimeMovie) { video in SentTransferredFile(video.url) } importing: { received in try Video.transfer(from: received) } FileRepresentation(contentType: .avi) { video in SentTransferredFile(video.url) } importing: { received in try Video.transfer(from: received) } FileRepresentation(contentType: .mpeg) { video in SentTransferredFile(video.url) } importing: { received in try Video.transfer(from: received) } FileRepresentation(contentType: .mpeg2Video) { video in SentTransferredFile(video.url) } importing: { received in try Video.transfer(from: received) } FileRepresentation(contentType: .video) { video in SentTransferredFile(video.url) } importing: { received in try Video.transfer(from: received) } FileRepresentation(contentType: .movie) { video in SentTransferredFile(video.url) } importing: { received in try Video.transfer(from: received) } } static func transfer(from received: ReceivedTransferredFile) throws -> Video { let destination = FileManager.default.temporaryDirectory.appendingPathComponent(received.file.lastPathComponent) if FileManager.default.fileExists(atPath: destination.path) { try FileManager.default.removeItem(at: destination) } try FileManager.default.copyItem(at: received.file, to: destination) return Video(url: destination, filename: received.file.lastPathComponent) } }
Replies
1
Boosts
0
Views
359
Activity
Jun ’25
UIPageViewController embedded in UIScrollView ignores the first pan gesture on its pages
I have a UIPageViewController embedded in a UIScrollView and each page has a drawing view with a UIPanGestureRecognizer to free-draw. With this setup, the 1st time I attempt to draw, the pan gesture is ignored. It works the 2nd time I perform the gesture. In my case I need to wrap the UIPageViewController in a UIScrollView to have a pull to refresh mechanism (set thescrollView.refreshControl). I’ve tried every combination of UIGestureRecognizerDelegate methods (shouldRecognizeSimultaneously…, require(toFail:), etc.) with no luck. This is my view hierarchy: ScrollView |- UIPageViewController |- Page 1 | |- DrawingView with UIPanGestureRecognizer |- Page 2 |- DrawingView with UIPanGestureRecognizer Is this a known limitation when a UIPageViewController is nested inside another scroll view? Reproduction steps (tested on iOS 18.4 / Xcode 16.3, iPhone 16 Pro) Launch the app; the first page shows a white canvas in the bottom part. Try to draw immediately → nothing happens. Lift your finger and draw again → works. Here is a link for the sample project with the reproducible code: https://github.com/marcod-storyteller/page-controller-sample P.S: If the UIPageViewController has a .pageCurl transition style instead, the problem disappears.
Topic: UI Frameworks SubTopic: UIKit Tags:
Replies
2
Boosts
1
Views
124
Activity
May ’25
SwiftUI TextEditor undo button
I'm using SwiftUI's TextEditor. I'd like to include an undo button in my UI that operates on the TextEditor. I don't see a way to hook this up. You can get the UndoManager from the environment, but this is not the undo manager the TextEditor is using. I know that UITextView uses an undocumented UndoManager (_UITextUndoManager) and I've accessed that before when using a UIViewRepresentable wrapper around UITextView. I'd like to achieve the same with TextEditor.
Topic: UI Frameworks SubTopic: SwiftUI
Replies
0
Boosts
0
Views
104
Activity
Jun ’25
How to hide the tab bar in SwiftUI's TabView for macOS?
In SwiftUI for macOS, how can I hide the tab bar when using TabView? I would like to provide my own tab bar implementation. In AppKit's NSTabViewController, we can do the following: let tabViewController = NSTabViewController() tabViewController.tabStyle = .unspecified I've come across various posts that suggest using the .toolbar modifier, but none appear to work on macOS (or at least I haven't found the right implementation). struct ContentView: View { var body: some View { TabView { // ... content } <- which view modifier hides the tab bar? } } Latest macOS, Latest Xcode
Replies
3
Boosts
0
Views
262
Activity
May ’25
Issues with .zoom NavigationTransition to a sheet with a .medium detent
When using a .zoom navigation transition, where .matchedTransitionSource is applied to a button in a toolbar and the destination view is a sheet which is presented with PresentationDetent.medium, the transition works initially, but shortly after it completes, the sheet's background is dimmed and the text of the source button reappears abruptly. Code and a screenshot are below, though the effect is best observed when interacting with the view. // // ContentView.swift // ZoomNavigationTransitionSample // // Created by Matthew DuBois on 6/15/25. // import SwiftUI struct ContentView: View { @State private var isPresentingSheet = false @Namespace private var namespace var body: some View { NavigationStack { List { Text("Some content") } .navigationTitle("Sample") .toolbar { ToolbarItem(placement: .topBarTrailing) { Button("Button") { isPresentingSheet = true } .matchedTransitionSource(id: "button", in: namespace) } } .sheet(isPresented: $isPresentingSheet) { Text("Some sheet content") .navigationTransition(.zoom(sourceID: "button", in: namespace)) .presentationDetents([.medium]) } } } } #Preview { ContentView() }
Replies
1
Boosts
1
Views
159
Activity
Jun ’25
AVAudioSession dropping wired USBAudio source
My app inputs electrical waveforms from an IV485B39 2 channel USB device using an AVAudioSession. Before attempting to acquire data I make sure the input device is available as follows: AVAudiosSession *audioSession = [AVAudioSession sharedInstance]; [audioSession setCategory :AVAudioSessionCategoryRecord error:&err]; NSArray *inputs = [audioSession availableInputs]; I have been using this code for about 10 years. My app is scriptable so a user can acquire data from the IV485B29 multiple times with various parameter settings (sampling rates and sample duration). Recently the scripts have been failing to complete and what I have notice that when it fails the list of available inputs is missing the USBAudio input. While debugging I have noticed that when working properly the list of inputs includes both the internal microphone as well as the USBAudio device as shown below. VIB_TimeSeriesViewController:***Available inputs = ( "<AVAudioSessionPortDescription: 0x11584c7d0, type = MicrophoneBuiltIn; name = iPad Microphone; UID = Built-In Microphone; selectedDataSource = Front>", "<AVAudioSessionPortDescription: 0x11584cae0, type = USBAudio; name = 485B39 200095708064650803073200616; UID = AppleUSBAudioEngine:Digiducer.com :485B39 200095708064650803073200616:000957 200095708064650803073200616:1; selectedDataSource = (null)>" ) But when it fails I only see the built in microphone. VIB_TimeSeriesViewController:***Available inputs = ( "<AVAudioSessionPortDescription: 0x11584cef0, type = MicrophoneBuiltIn; name = iPad Microphone; UID = Built-In Microphone; selectedDataSource = Front>" ) If I only see the built in microphone I immediately repeat the three lines of code and most of the "inputs" contains both the internal microphone and the USBAudioDevice AVAudiosSession *audioSession = [AVAudioSession sharedInstance]; [audioSession setCategory :AVAudioSessionCategoryRecord error:&err]; NSArray *inputs = [audioSession availableInputs]; This fix always works on my M2 iPadPro and my iPhone 14 but some of my customers have older devices and even with 3 tries they still get faults about 1 in 10 tries. I rolled back my code to a released version from about 12 months ago where I know we never had this problem and compiled it against the current libraries and the problem still exists. I assume this is a problem caused by a change in the AVAudioSession framework libraries. I need to find a way to work around the issue or get the library fixed.
Replies
0
Boosts
0
Views
153
Activity
May ’25
How to show lanes in carplay programatically
Hello all, I'm confused about how to show lanes in CarPlay. I understand CPLaneGuidance and CPLane I don't find anywhere where to tell Carplay which icon to show for each lane. I've found some information saying we put the icon in CPManeuver, but then CPManeuver is linked to only one CPLaneGuidance, and we can put only one icon in CPManeuver. At the same time, we might have multiple lanes. Any help, tips, or examples would be highly helpful.
Replies
0
Boosts
0
Views
73
Activity
Jun ’25
`SwiftUI.Table` Select and Done buttons breaking navigation on iPadOS?
https://github.com/apple/sample-food-truck Hi! I'm following along with the sample-food-truck application from WWDC 2022. I'm seeing some weird navigation issues when building the app for iPadOS. The Table component displays a Select Button for selecting elements and a Done Button disabling that state. These buttons seem to be breaking something about navigation on iOS 18.4.1. It's a nondeterministic issue… but tapping the buttons seems to lead to some corrupt state where the app transitions out of OrdersView and back to TruckView. This code from FoodTruckModel seems to be making a difference: Task(priority: .background) { var generator = OrderGenerator.SeededRandomGenerator(seed: 5) for _ in 0..<20 { try? await Task.sleep(nanoseconds: .secondsToNanoseconds(.random(in: 3 ... 8, using: &generator))) Task { @MainActor in withAnimation(.spring(response: 0.4, dampingFraction: 1)) { self.orders.append(orderGenerator.generateOrder(number: orders.count + 1, date: .now, generator: &generator)) } } } } Commenting out that code and disabling the new Order values coming in seems to fix the issue. Is there any public documentation for me to learn about the Select and Done buttons? I don't see anywhere for me to learn about how these work and what my ability is to customize their behavior. Any ideas? I can repro from device and simulator.
Replies
2
Boosts
0
Views
125
Activity
May ’25
Clustering on MapKit for SwiftUI iOS17+
Hi What would be the best way to achieve clustering on MapKit within SwiftUI? We're building a decentralized commerce auction platform that is currently live in Switzerland with 3'500 live auctions that can be discovered on a map. We're now running into the issue that the map gets cluttered, when zooming out and haven't been able to find a way to cluster We moved back to UIKit, where clustering works, but UIKit has other drawdowns. So ideally there is a way to handle it within SwiftUI without having to wrap UIKit or move back entirely to UIKit. Thanks for any help or suggestions! Developer Documentation https://developer.apple.com/documentation/mapkit/mapkit-for-swiftui Julius Ilg AuctionShack
Replies
2
Boosts
1
Views
265
Activity
Jun ’25
The NSTextViewDelegate method textViewDidChangeSelection(:) will not fire, while all other text view delegate methods do.
I am trying to implement the NSTextViewDelegate function textViewDidChangeSelection(_ notification: Notification). My text view's delegate is the Coordinator of my NSViewRepresentable. I've found that this delegate function never fires, but any other delegate function that I implement, as long as it doesn't take a Notification as an argument, does fire (e.g., textView(:willChangeSelectionFromCharacterRange:toCharacterRange:), fires and is called on the delegate exactly when it should be). For context, I've verified all of the below: textView.isSelectable = true textView.isEditable = true textView.delegate === my coordinator I can call textViewDidChangeSelection(:) directly on the delegate without issue. I can select and edit text without issues. I.e., the selections are being set correctly. But the delegate method is never called when they are. I am able to add the intended delegate as an observer for the selector textViewDidChangeSelection via NotificationCenter. If I do this, the function executes when it should, but fires for every text view in my view hierarchy, which can number in the hundreds. I'm using an NSLayoutManager, so I figure this should only fire once. I've added a check within my code: func textViewDidChangeSelection(_ notification: Notification) { guard let textView = notification.object as? NSTextView, textView === layoutManager.firstTextView else { return } // Any code I want to execute... } But the above guard check lets through every notification, so, no matter what, my closure executes hundreds of times if I have hundreds of text views, all of them being sent by textView === layoutManager.firstTextView, but once for each and every text view managed by that layoutManager. Does anyone know why this method isn't ever called on the delegate, while seemingly all other delegate methods are? I could go the NotificationCenter route, but I'd love to know why this won't execute as a delegate method when documentation says that it should, and I don't want to have to implement a counter to make sure my code only executes once per selection update. And for more reasons than that, implementing via delegate method is preferable to using notifications for my use case. Thanks for any help!
Replies
3
Boosts
0
Views
267
Activity
May ’25
Search in a bottom toolbar
Dear all, The Search fields documentation appears to make a distinction between putting a search in a tab bar and in a bottom toolbar in an iOS device. Putting a search in a tab bar in iOS26 appears to be quick and easy: Tab(role: .search) { // Search } I cannot find, however, a way on how to put a search bar in a bottom toolbar (as illustrated here). The following code puts it in the top toolbar: .searchable(text: $searchQuery, placement: .toolbar) Same as this one: .searchable(text: $searchQuery, placement: .toolbarPrincipal) Do I miss something in this regard? Thanks!
Replies
1
Boosts
0
Views
292
Activity
Jun ’25
NSLayoutManager Bug -- layout manager re-laying out overlapping text into the same container.
I've posted a couple times now about major issues I'm having with NSLayoutManager and have written to Apple for code-level support, but no one at Apple has responded to me in more than two weeks. So I'm turning to the community again for any help whatsoever. I'm fairly certain it's a real bug in TextKit. If I'm right about that, I'd love for anyone at Apple to take an interest. And better yet, if I'm wrong (and I hope I am), I'd be incredibly grateful to anyone who can point out where my mistake lies! I've been stuck with this bug for weeks on end. The crux of the issue is that I'm getting what seemed to be totally incompatible results from back to back calls to textContainer(forGlyphAt:effectiveRange:) and lineFragmentRect(forGlyphAt:effectiveRange:withoutAdditionalLayout:)... I'd lay out my text into a fairly tall container of standard page width and then query the layout manager for the text container and line fragment rect for a particular glyph (a glyph that happens to fall after many newlines). Impossibly, the layout manager would report that that glyph was in said very tall container, but that the maxY of its lineFragmentRect was only at 14 points (my NSTextView's isFlipped is true, so that's 14 points measuring from the top down). After investigating, it appears that what is happening under the hood is NSLayoutManager is for some reason laying out text back into the first container in my series of containers, rather than overflowing it into the next container(s) and/or giving me a nil result for textContainer(forGlyphAt:...) I've created a totally stripped down version of my project that recreates this issue reliably and I'm hoping literally anyone at Apple will respond to me. In order to recreate the bug, I've had to build a very specific set of preview data - namely some NSTextStorage content and a unique set of NSTextViews / NSTextContainers. Because of the unique and particular setup required to recreate this bug, the code is too much to paste here (my preview data definition is a little unwieldy but the code that actually processes/parses it is not). I can share the project if anyone is able and willing to look into this with me. It seems I'm not able to share a .zip of the project folder here but am happy to email or share a dropbox link.
Replies
7
Boosts
0
Views
343
Activity
May ’25