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

Mac Catalyst SplitViewController, UITitlebar bugs?
Bringing my iPad app to Mac Catalyst as iPad idiom. Primary interface is a UISplitViewController. Two things I think are bugs unless someone replies with a fix. SplitViewController is setup in two column with left column as sidebar: split.setViewController(primary, for: .primary) split.setViewController(secondary, for: .secondary) split.preferredDisplayMode = .oneBesideSecondary split.preferredSplitBehavior = .tile split.presentsWithGesture = true #if targetEnvironment(macCatalyst) split.primaryBackgroundStyle = .sidebar split.displayModeButtonVisibility = .never #endif The displayMode button aligns vertically with the navigation bar and below the 3 window control buttons (close, minimize, full screen), whereas on other macOS apps using SplitViewController such as Apple Notes app, the displayMode button aligns vertically and just to the right of the the 3 window control buttons (close, minimize, full screen). I downloaded the Apple Example app called Menus that is supposed to be a prime example of a Mac Catalyst app, and I see author must have faced the same bug and instead created their own displayMode button and placed it on the UITitlebar's toolBar. In my secondary ViewController which is a subclass of a UITableViewController, tapping a row, calls show and in a SplitViewController, that pushes another detailVC onto the Nav stack as expected. The UIWindowScene's UITitlebar which appears over the top of the secondary VC looks correct. This detailVC is a subclass of a UITableViewController. Finally, tapping a row in the table of the detailVC calls show but this time, the ViewController is actually a UIHostingViewController wrapping a SwiftUI View. At this point the UIWindowScene's UITitlebar changes appearance and takes on the same lightened color similar to the sidebar (primary) appearance. With UITitlebarTitleVisibility set to hidden and if I set the titlebar.toolbar to nil, (which removes the UITitlebar, there is no appearance issue. Running on iPad, with no UITitlebar, there is no odd lightening experienced when the UIHostingController is shown. I think this has something to do with the UIHostingController within Mac Catalyst.
1
0
229
May ’25
Crash due to likely infinitely recursive call in SwiftUI `Color.Resolved.init`
So I'm dealing with a really obtuse crash that appears to be a stack overflow in an internal SwiftUI code path creating a Color.Resolved. I haven't found anyone one else with this issue online, and I cannot get it to reproduce on my own device. Interestingly enough, it is only happening on 1 device in the field (according to XCode crash logs). Here are some lines from the crashed thread. You can see that my code is never called, and it appears to be starting in some Array equality check checking the equality of colors (which I can't think of anywhere in my app I am doing anyway). You can see from this trace here that it appears to be a recursive call through Color.Resolved and NSColor.withColorAppearance. I don't have any idea how to solve this, but it keeps happening with at least one in-the-field device across multiple app updates. So my whole app is open source on github at https://github.com/msdrigg/roam, but I don't even use NSColor explicitly anywhere except for here which doesn't match the stack trace. I also tried changing the accent color of the app with defaults write com.msdrigg.roam AppleAccentColor -integer 1 to see if that somehow caused the crash, but my app opened up totally fine (and respected the change). Besides this, the only places I think I could be using dynamic colors is I when define an AccentColor and a WidgetBackground color for my app using xcassets, and then I use these colors from SwiftUI. In most of my app I stick to the system colors (Color.gray and such). Thread 0 Crashed: 0 libsystem_pthread.dylib 0x000000018601213c ___chkstk_darwin + 60 1 CoreFoundation 0x0000000186108434 -[NSArray isEqualToArray:] + 52 (NSArray.m:454) 2 AppKit 0x000000018a21fcd4 -[NSCoreUICatalogColor resolvedCUINamedColorForAppearance:] + 164 (NSColor.m:5057) 3 AppKit 0x0000000189c32cd4 -[NSCoreUICatalogColor resolvedColor] + 48 (NSColor.m:5148) 4 AppKit 0x0000000189c31e74 -[NSDynamicNamedColor colorUsingColorSpace:] + 32 (NSColor.m:4410) 5 SwiftUICore 0x0000000221ca9fd8 CoreColorPlatformColorGetComponents + 116 (CoreColorFunctions.m:149) 6 SwiftUICore 0x0000000221faaf28 specialized Color.Resolved.init(platformColor:) + 92 (CoreColor.swift:14) 7 SwiftUICore 0x0000000221faa5b0 Color.Resolved.init(platformColor:) + 16 (<compiler-generated>:0) 8 SwiftUI 0x00000001b53b1dc4 closure #1 in NSColor.resolve(in:) + 20 (AppKitColorConversions.swift:156) 9 SwiftUI 0x00000001b53b222c partial apply for closure #1 in static NSColor.withColorAppearance(in:_:) + 32 (<compiler-generated>:0) 10 SwiftUI 0x00000001b46b1e54 closure #1 in SubmitTriggerSource.dispatchUpdate(_:) + 28 (PlatformViewCoordinator.swift:12) 11 SwiftUI 0x00000001b5484488 thunk for @escaping @callee_guaranteed () -> () + 28 (<compiler-generated>:0) 12 AppKit 0x0000000189c174a4 +[NSAppearance _performWithCurrentAppearance:usingBlock:] + 72 (NSAppearance.m:2408) 13 SwiftUI 0x00000001b53b2088 specialized static NSColor.withColorAppearance(in:_:) + 324 (AppKitColorConversions.swift:142) 14 SwiftUI 0x00000001b53b1e7c protocol witness for ColorProvider.resolve(in:) in conformance NSColor + 68 (<compiler-generated>:151) 15 SwiftUICore 0x0000000222436e6c ColorBox.resolve(in:) + 124 (Color.swift:288) 16 SwiftUICore 0x0000000222435e30 Color.resolve(in:) + 72 (Color.swift:87) 17 SwiftUI 0x00000001b53b1c88 closure #1 in NSColor.init(_:) + 196 (AppKitColorConversions.swift:124) 18 SwiftUI 0x00000001b4542714 thunk for @escaping @callee_guaranteed (@guaranteed NSAppearance) -> (@owned NSColor) + 56 (<compiler-generated>:0) 19 AppKit 0x0000000189c31e74 -[NSDynamicNamedColor colorUsingColorSpace:] + 32 (NSColor.m:4410) //// ... Repeating for 500 lines 500 SwiftUICore 0x0000000221ca9fd8 CoreColorPlatformColorGetComponents + 116 (CoreColorFunctions.m:149) 501 SwiftUICore 0x0000000221faaf28 specialized Color.Resolved.init(platformColor:) + 92 (CoreColor.swift:14) 502 SwiftUICore 0x0000000221faa5b0 Color.Resolved.init(platformColor:) + 16 (<compiler-generated>:0) 503 SwiftUI 0x00000001b53b1dc4 closure #1 in NSColor.resolve(in:) + 20 (AppKitColorConversions.swift:156) 504 SwiftUI 0x00000001b53b222c partial apply for closure #1 in static NSColor.withColorAppearance(in:_:) + 32 (<compiler-generated>:0) 505 SwiftUI 0x00000001b46b1e54 closure #1 in SubmitTriggerSource.dispatchUpdate(_:) + 28 (PlatformViewCoordinator.swift:12) 506 SwiftUI 0x00000001b5484488 thunk for @escaping @callee_guaranteed () -> () + 28 (<compiler-generated>:0) 507 AppKit 0x0000000189c174a4 +[NSAppearance _performWithCurrentAppearance:usingBlock:] + 72 (NSAppearance.m:2408) 508 SwiftUI 0x00000001b53b2088 specialized static NSColor.withColorAppearance(in:_:) + 324 (AppKitColorConversions.swift:142) 509 SwiftUI 0x00000001b53b1e7c protocol witness for ColorProvider.resolve(in:) in conformance NSColor + 68 (<compiler-generated>:151) 510 SwiftUICore 0x0000000222436e6c ColorBox.resolve(in:) + 124 (Color.swift:288) full-log.crash
0
0
145
May ’25
UIPanGestureRecognizer is broken on iPadOS26
import UIKit class ViewController: UIViewController { var panGesture = UIPanGestureRecognizer() override func viewDidLoad() { super.viewDidLoad() panGesture.isEnabled = true panGesture.minimumNumberOfTouches = 0 panGesture.maximumNumberOfTouches = 5 panGesture.allowedScrollTypesMask = .continuous panGesture.addTarget(self, action: #selector(gestureUpdate(_:))) view.addGestureRecognizer(panGesture) } @objc private func gestureUpdate(_ gesture: UIPanGestureRecognizer) { print("OS: \(osVersion), date: \(Date.now), numberOfTouches: \(gesture.numberOfTouches)") } private var osVersion: String { let osVersion = ProcessInfo.processInfo.operatingSystemVersion return "\(osVersion.majorVersion).\(osVersion.minorVersion).\(osVersion.patchVersion)" } } it's hard to recognize 3 or more fingers gesture on iPadOS26.
Topic: UI Frameworks SubTopic: UIKit
0
1
101
Jun ’25
viewIsAppearing not be called in children Controllers below iOS 16?
I see viewIsAppearing is available on iOS 13 and above, but when I use it, found that the function not be called below iOS 16 https://developer.apple.com/documentation/uikit/uiviewcontroller/4195485-viewisappearing environment: Macos 14.4.1, Xcode 15.3 import UIKit class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() let sub = SubViewController() addChild(sub) view.addSubview(sub.view) } @available(iOS 13.0, *) override func viewIsAppearing(_ animated: Bool) { super.viewIsAppearing(animated) print("ViewController viewIsAppearing") } } class SubViewController: UIViewController { @available(iOS 13.0, *) override func viewIsAppearing(_ animated: Bool) { super.viewIsAppearing(animated) print("SubViewController viewIsAppearing") } } In iOS 15 devcice console log: ViewController viewIsAppearing iOS 16, 17: ViewController viewIsAppearing SubViewController viewIsAppearing
Topic: UI Frameworks SubTopic: UIKit Tags:
3
0
1k
May ’25
Applying the `.prominent` modifier to a toolbar action
Hi y'all! I'm creating an iOS app with SwiftUI. Part of the app's layout will have a toolbar. Per the HIG's Toolbar article, under the section titled "Actions", the primary action in the toolbar should use the .prominent modifier. Unfortunately, I'm having issues finding information about this modifier in the SwiftUI reference documentation, and Xcode's code completion (the standard completions; I don't use the language model version) doesn't reveal anything that seems to be usable to create the desired effect. For reference, this is what the view currently looks like: VStack { } .toolbar { ToolbarItem(placement: .topBarTrailing) { Button("Add Something", systemImage: "plus") { print("perform action") } } } Is this modifier added to the button itself as .buttonStyle(.borderedProminent)? This seems to create an odd off-center layout shift in the Xcode preview, the Simulator, and my physical device. Is it added to the toolbar item with a similarly-named modifier? Thanks all! :)
1
1
121
Jun ’25
The URL authorization read and write obtained by UIDocumentPickerViewController
The URL directory obtained by UIDocumentPickerVieweController can be read and written in the directory after calling startAccessingDecurityScopeResource. However, after restarting the app, if the URL saved in the package is called startAccessingDecurityScopeResource again and returns NO, UIDocumentPickerVieweController must be called again to retrieve the URL, and then startAccessingDecurityScopeResource must be called again before continuing the operation. This is too troublesome. Is there a way to continue reading and writing operations in the URL directory after restarting the app?
1
0
84
May ’25
How to move from Share Extension to the main screen
My app is designed to share and import images with apps such as the File app. I created a program after looking at various information, but the app from which the images are shared does not work, and the screen cannot be moved to the main screen of my app. The program is as follows. How should I modify it? import UIKit import MobileCoreServices import UniformTypeIdentifiers class ShareViewController: UIViewController { let suiteName: String = "group.com.valida.pettyGeneral" let keyString: String = "share-general" override func viewDidLoad() { var nameArray: [String] = [String]() let sharedDefaults: UserDefaults = UserDefaults(suiteName: self.suiteName)! guard let inputItem = self.extensionContext?.inputItems.first as? NSExtensionItem, let attachments = inputItem.attachments else { return } let identifier = UTType.image.identifier let imgAttachments = attachments.filter { $0.hasItemConformingToTypeIdentifier(identifier) } let dispatchGroup = DispatchGroup() for (no, itemProvider) in imgAttachments.enumerated() { dispatchGroup.enter() itemProvider.loadItem(forTypeIdentifier: identifier, options: nil) { [self] item, error in do { if let error = error { throw error } else if let url = item as? URL { let data = try Data(contentsOf: url) let fileManager = FileManager.default let url = fileManager.containerURL(forSecurityApplicationGroupIdentifier: suiteName) if let url = url?.appendingPathComponent(String(no)) { try! data.write(to: url) } nameArray.append(String(no)) } do { dispatchGroup.leave() } } catch { print("Error") do { dispatchGroup.leave() } } } } dispatchGroup.notify(queue: .main) { [self] in // 全ての画像を保存 sharedDefaults.set(nameArray, forKey: self.keyString) sharedDefaults.synchronize() // メニュー画面に移動する openUrl(url: URL(string: "container-general://")) self.extensionContext!.completeRequest(returningItems: [], completionHandler: nil) } } //#selector(openURL(_:))はこの関数がないと作れない @objc func open(_ url: URL) {} func openUrl(url: URL?) { let selector = #selector(open(_ : )) var responder = (self as UIResponder).next while let r = responder, !r.responds(to: selector) { responder = r.next } _ = responder?.perform(selector, with: url) } func openContainerApp() { let url = URL(string: "container-general://") // カスタムスキームを作って指定する var responder: UIResponder? = self while responder != nil { if let application = responder as? UIApplication { let selector = sel_registerName("openURL:") application.perform(selector, with: url) break } responder = responder?.next } } }
0
0
157
Jun ’25
iOS app crash with UIKitcore - UIAlertController
I have recently submitted a new app version to the Appstore with Xcode 15.0. Unfortunately, I have started to see the below crash in the Xcode organiser &gt; Crashes section occurring for more number of times. UIKitCore: +[UIAlertController _alertControllerContainedInViewController:] + 160 The exception trace is not leading to main() function but not pointing to any of the code line. I had used UIAlertController in the past versions to show the alerts but there is no code written in the current version code related to UIAlertController. Only from the latest version, this kind of crash started to surface. In the latest release, We have added a third party SDK and while implementing the SDK, we had added the Location and Bluetooth Permissions in Info.plist file. But as we don't want to use/track the Location and Bluetooth details from the app, the SDK team has disabled the Location and Bluetooth settings to not reflect in the tracked data. Is this behaviour creating any conflict with the UIAlertController and logging the crash? Because by default the OS tries to show the alert when the permissions exist in the plist file, but the alert will not come as the service is disabled on the SDK server settings. Is this creating any conflict and logging the crash. Please extend your help.
3
0
904
May ’25
iOS26 beta ToolbarItem with placement to principal width is not fill to screen
I’m trying to add a TextField to the toolbar using .principal placement, and I want it to either fill the screen width or expand based on the surrounding content. However, it’s not resizing as expected — the TextField only resizes correctly when I provide a hardcoded width value. This behavior was working fine in previous versions of Xcode, but seems to be broken in Xcode 26. Not sure if this is an intentional change or a bug. i am using iOS26 beta and Xcode 26 beta struct ContentView: View { var body: some View { VStack { Image(systemName: "globe") .imageScale(.large) .foregroundStyle(.tint) Text("Hello, world!") } .padding() .toolbar { ToolbarItem(placement: .principal) { HStack { TextField("Search", text: .constant("")) .textFieldStyle(.roundedBorder) .frame(maxWidth: .infinity) // .frame(width: 300) Button("cancel") { } } .frame(maxWidth: .infinity) } } } } #Preview { NavigationView { ContentView() } }
0
0
338
Jun ’25
CATiledLayer flashes and re-draws entirely when re-drawing a single tile
I have filed a bug report for this (FB17734946), but I'm posting it here verbatim in case others have the same issue and in hopes of getting attention from an Apple engineer sooner. When calling setNeedsDisplayInRect on a CATiledLayer - or a UIView whose backing layer is CATiledLayer - one would expect to re-draw only a region identified by the rect passed to the method. This is even written in the documentation for the class: "Regions of the layer may be invalidated using the setNeedsDisplayInRect: method however the update will be asynchronous. While the next display update will most likely not contain the updated content, a future update will." However, upon calling this method, CATiledLayer redraws whole contents instead of just the tile at the specified rect, and it flashes when doing so. It behaves exactly the same as if one had called setNeedsDisplay without passing any rect; all contents are cleared and re-drawn again. I'm 100% sure I've passed in the correct rect of the exact tile that I need to redraw. I have even tried passing much smaller rects, but still the same. (And yes, the rect I've passed accounts for the current level of detail.) I have found this GitHub repo https://github.com/frankus/NetPhotoScroller, which based on discussion from here https://forums.macrumors.com/threads/catiledlayer-blanks-out-tiles-when-redrawing.1333948/ aims at solving these issues by using two private methods on CATiledLayer class: (void)setNeedsDisplayInRect:(CGRect)r levelOfDetail:(int)level; (BOOL)canDrawRect:(CGRect)rect levelOfDetail:(int)level; I have explored the repo in detail, however I wasn't able to test exactly this code from the GitHub repo. I have tried using those two private methods myself (through an Objective-C class that defines the methods in the header file and then a swift class which inherits it), but I couldn't solve the issue; the flashing and the full re-draw is still there. After doing a lot of research, the conclusion seems to be that one cannot use CATiledLayer with contents that are downloaded remotely, on demand, as tiles are being requested. I have, however, found one interesting thing which seems to work so far: before calling setNeedsDisplayInRect (or just setNeedsDisplay, as they behave the same for CATiledLayer in my testing), cache the current layer's contents, and after calling setNeedsDisplay (or setNeedsDisplayInRect), restore the contents back to the layer. This prevents flashing and preserves any tiles that were drawn at the time of the re-draw. let c = tiledLayer.contents tiledLayer.setNeedsDisplay(tileRect) tiledLayer.contents = c However! Docs clearly state the warning: Do not attempt to directly modify the contents property of a CATiledLayer object. Doing so disables the ability of a tiled layer to asynchronously provide tiled content, effectively turning the layer into a regular CALayer object. I believe this message implies modifying the contents property with some raw content, like image data, and that it may be safe to re-apply the existing contents (which are in my testing of type CAImageProvider) -- but I can't rely on an implementation detail in my production app. I have tested this and confirmed that the bug appears on: iPhone 14 Pro, iOS 18.5 iPhone 13 Pro, iOS 17.5.1 iPhone 5s, iOS 15.8.3 iPad Pro 1st gen, iPadOS 18.4.1 a couple simulator versions I can also confirm that the fix (to re-apply contents property) is also working properly on all these versions. Is this expected behavior, that tiled layer redraws itself entirely instead of redrawing specific tiles? Is it safe to modify contents of a CATiledLayer by re-applying the existing contents? If not, is there an alternative to avoid flashing?
3
0
212
May ’25
Additional Questions Regarding App Launch Timing
I found the following statement on the site TN3187: Migrating to the UIKit scene-based life cycle | Apple Developer Documentation: "Soon, all UIKit based apps will be required to adopt the scene-based life-cycle, after which your app won’t launch if you don’t. While supporting multiple scenes is encouraged, only adoption of scene life-cycle is required." In this post, you mentioned that the timing is undecided. https://developer.apple.com/forums/thread/785588 I would like to confirm the following two points additionally. Could you please confirm whether the timing when the app will not be able to launch is during an iOS update or at another specific time? This will change our response policy. Does "your app won’t launch" mean that already distributed apps will also not be able to launch? Or does it mean that newly developed apps will fail to build or be rejected during app review?
Topic: UI Frameworks SubTopic: UIKit Tags:
2
0
347
Jun ’25
AppIntent complie issue & manual remove AppIntent dialog
1.When I attempted to open the subsequent AppIntent within the perform method of the AppIntent instance, I always received the following error: How to solve the problems of inconsistency of this type? I couldn't find any sample code. 2.When I used method 'Button(intent: OpenAppIntent())' to open my app through the dialog custom view of AppIntent, but I couldn't find a way to close this AppIntent dialog. How can i remove this dialog?
Topic: UI Frameworks SubTopic: General
2
0
90
May ’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
openURL:options:completionHandler: Not Opening tel:// Link on iPad with Cellular Data
We are using openURL:options:completionHandler: to open a tel:// number in the dialer to place a call. This works on iPhones and WiFi-only iPads (tested with a iPad Mini 6th Gen), but it is failing to open on an iPad 8th Gen (WiFi + Cellular) running iPadOS 18.5 being used by a customer. Prior to updating the iPad to iPadOS 18, the call worked on iPadOS 15.2 and opened the call in FaceTime as expected. Despite not opening the dialer in iPadOS 18, the completionHandler returns the success parameter as true. canOpenUrl also returns true. We created a small test application that reproduces the issue using the code snippet below in a new application, with the tel schema added to the info.plist Queried URL Schemes. We are currently using Xcode 16.3. Test Steps: Create a new blank application and replace ContentView.swift with the code snippet below Run the test app on a physical iPad 8th Gen (WiFi + Cellular) Tap the "place a test call" button Expected Results: The user is prompted to call the number and is taken to FaceTime to attempt the call. The user may then receive an alert telling them an iPhone must be paired if not already. Alternatively: return success = false in the completionHandler. Actual Results: No action occurs that is visible to the user, and the completionHandler returns success = true. Separately, we should be able to have some method of checking if the device can actually complete a call, i.e. if an iPhone is paired, so that we can correctly show or hide a phone icon in the app based on if the user can place a call. canOpenUrl returns true even if there is not a device paired and the call cannot actually be placed, and there doesn't seem to be a proper method for making that check. Code Snippet: import SwiftUI struct ContentView: View { @State private var showAlert = false var body: some View { VStack { Image(systemName: "globe") .imageScale(.large) .foregroundStyle(.tint) Text("Hello, world!") Button("Place a test call") { if let url = URL(string: "tel://5555554567") { UIApplication.shared.open(url) { success in if success { print("Call initiated successfully.") } else { showAlert = true } } } } } .padding() .alert("Call Failed", isPresented: $showAlert) { Button("OK") { showAlert = false } } message: { Text("The call could not be initiated.") } } } #Preview { ContentView() }
0
1
243
Jun ’25
macOS Sequoia/Xcode 16.2 - Catalyst App Missing Tab Bar
My Objective-C Catalyst app when built with Xcode 16.x/iOS 18 does not have a visible Tab Bar when run on Sequoia. App starts up in first tab, but there is no way to access other tabs. The same app when run on macOS Sonoma (or macOS Catalina) has a normal Tab Bar. The app has an initial View UITabBarController with 3 tabs. The main tab is a UiSplitViewController. Minimum macOS deployment 10.5. If app is built on Sonoma with Xcode 15.x/iOS 17 the Tab Bar is normal on macOS Sonoma, Sequoia, and Catalina. I've tried without success: if (@available(macCatalyst 18.0, *)) { self.tabBarController.tabBarHidden = false; } else { // Fallback on earlier versions } I wonder if this console log message has anything to do with the problem: CLIENT OF UIKIT REQUIRES UPDATE: This process does not adopt UIScene lifecycle. This will become an assert in a future version.
2
0
286
Jun ’25
A wrinkle converting a UIKit Document-based app to SwiftUI Document Group
The app I'm converting includes two unique document types. UI-wise they have key similarities (eg contents are password protected) But serialization/model - wise. they are different documents. I have not been able to find any documentation on options for implementing this (eg use a (abstract?) base class derived from FileDocument, with two concrete sub classes? maybe just a single subclass of FileDocument that contains model details for both file types?) Stepping back from implementation options, am I crazy for attempting to use DocumentGroup to create a single app that would need to be able to open/modify/save multiple unique document types? any/all guidance much appreciated.
Topic: UI Frameworks SubTopic: SwiftUI
0
0
80
May ’25
How can I make a new item from within a navigationlink?
Sorry if this is too basic, but I really can't figure out how to make this work. I am trying to make a journal app and I want to have a button that creates a new journalentry and then loads it. This code snippet (I removed irrelevant bits) shows how I'm trying to go about it. Basically, the newEntryButtons should launch a JournalPromptRoute for one of the different options: that's the method argument. But putting .createNewEntry() inside the argument means that new entries are being constantly created. I want the system to create a new entry once on the button press and then go to it from the navigationDestination area. Can anyone please explain to me how this is supposed to work? I believe the code snippet is detailed enough to get the point across but please let me know if you need more info. case library case blank(entry: Entry) case mystery case summary(entry: Entry) case entry(entry: Entry) } struct JournalHome: View { @ObservedObject var viewModel: JournalViewModel var mainContent: some View { ScrollView { newEntryButtons LazyVStack { ForEach(filteredEntries) { entry in NavigationLink( value: JournalPromptRoute.entry(entry: entry) ) { JournalCard(entry) } } } } } var body: some View { NavigationStack(path: $path) { mainContent .navigationDestination(for: JournalPromptRoute.self) { route in switch route { case .blank(let entry): JournalEntryView( entry: entry, index: 0, viewModel: viewModel ) } } } } var newEntryButtons: some View { ScrollView(.horizontal) { HStack(spacing: 15) { EntryButton( description: "Add blank entry", method: JournalPromptRoute.blank(entry: viewModel.createNewEntry()), viewModel: viewModel, path: $path ) EntryButton( description: "Select a Journey", method: JournalPromptRoute.library, viewModel: viewModel, path: $path ) EntryButton( description: "Let the Journey find you", method: JournalPromptRoute.mystery, viewModel: viewModel, path: $path ) } } } }
Topic: UI Frameworks SubTopic: SwiftUI
2
0
102
Jun ’25
Mac Catalyst SplitViewController, UITitlebar bugs?
Bringing my iPad app to Mac Catalyst as iPad idiom. Primary interface is a UISplitViewController. Two things I think are bugs unless someone replies with a fix. SplitViewController is setup in two column with left column as sidebar: split.setViewController(primary, for: .primary) split.setViewController(secondary, for: .secondary) split.preferredDisplayMode = .oneBesideSecondary split.preferredSplitBehavior = .tile split.presentsWithGesture = true #if targetEnvironment(macCatalyst) split.primaryBackgroundStyle = .sidebar split.displayModeButtonVisibility = .never #endif The displayMode button aligns vertically with the navigation bar and below the 3 window control buttons (close, minimize, full screen), whereas on other macOS apps using SplitViewController such as Apple Notes app, the displayMode button aligns vertically and just to the right of the the 3 window control buttons (close, minimize, full screen). I downloaded the Apple Example app called Menus that is supposed to be a prime example of a Mac Catalyst app, and I see author must have faced the same bug and instead created their own displayMode button and placed it on the UITitlebar's toolBar. In my secondary ViewController which is a subclass of a UITableViewController, tapping a row, calls show and in a SplitViewController, that pushes another detailVC onto the Nav stack as expected. The UIWindowScene's UITitlebar which appears over the top of the secondary VC looks correct. This detailVC is a subclass of a UITableViewController. Finally, tapping a row in the table of the detailVC calls show but this time, the ViewController is actually a UIHostingViewController wrapping a SwiftUI View. At this point the UIWindowScene's UITitlebar changes appearance and takes on the same lightened color similar to the sidebar (primary) appearance. With UITitlebarTitleVisibility set to hidden and if I set the titlebar.toolbar to nil, (which removes the UITitlebar, there is no appearance issue. Running on iPad, with no UITitlebar, there is no odd lightening experienced when the UIHostingController is shown. I think this has something to do with the UIHostingController within Mac Catalyst.
Replies
1
Boosts
0
Views
229
Activity
May ’25
iOS 26 List selection radius
Is there any way to influence the corner radius of a selection in the list? Looking at the native Apple Mail app in the iOS 26, it should be.
Topic: UI Frameworks SubTopic: SwiftUI
Replies
0
Boosts
1
Views
171
Activity
Jun ’25
Crash due to likely infinitely recursive call in SwiftUI `Color.Resolved.init`
So I'm dealing with a really obtuse crash that appears to be a stack overflow in an internal SwiftUI code path creating a Color.Resolved. I haven't found anyone one else with this issue online, and I cannot get it to reproduce on my own device. Interestingly enough, it is only happening on 1 device in the field (according to XCode crash logs). Here are some lines from the crashed thread. You can see that my code is never called, and it appears to be starting in some Array equality check checking the equality of colors (which I can't think of anywhere in my app I am doing anyway). You can see from this trace here that it appears to be a recursive call through Color.Resolved and NSColor.withColorAppearance. I don't have any idea how to solve this, but it keeps happening with at least one in-the-field device across multiple app updates. So my whole app is open source on github at https://github.com/msdrigg/roam, but I don't even use NSColor explicitly anywhere except for here which doesn't match the stack trace. I also tried changing the accent color of the app with defaults write com.msdrigg.roam AppleAccentColor -integer 1 to see if that somehow caused the crash, but my app opened up totally fine (and respected the change). Besides this, the only places I think I could be using dynamic colors is I when define an AccentColor and a WidgetBackground color for my app using xcassets, and then I use these colors from SwiftUI. In most of my app I stick to the system colors (Color.gray and such). Thread 0 Crashed: 0 libsystem_pthread.dylib 0x000000018601213c ___chkstk_darwin + 60 1 CoreFoundation 0x0000000186108434 -[NSArray isEqualToArray:] + 52 (NSArray.m:454) 2 AppKit 0x000000018a21fcd4 -[NSCoreUICatalogColor resolvedCUINamedColorForAppearance:] + 164 (NSColor.m:5057) 3 AppKit 0x0000000189c32cd4 -[NSCoreUICatalogColor resolvedColor] + 48 (NSColor.m:5148) 4 AppKit 0x0000000189c31e74 -[NSDynamicNamedColor colorUsingColorSpace:] + 32 (NSColor.m:4410) 5 SwiftUICore 0x0000000221ca9fd8 CoreColorPlatformColorGetComponents + 116 (CoreColorFunctions.m:149) 6 SwiftUICore 0x0000000221faaf28 specialized Color.Resolved.init(platformColor:) + 92 (CoreColor.swift:14) 7 SwiftUICore 0x0000000221faa5b0 Color.Resolved.init(platformColor:) + 16 (<compiler-generated>:0) 8 SwiftUI 0x00000001b53b1dc4 closure #1 in NSColor.resolve(in:) + 20 (AppKitColorConversions.swift:156) 9 SwiftUI 0x00000001b53b222c partial apply for closure #1 in static NSColor.withColorAppearance(in:_:) + 32 (<compiler-generated>:0) 10 SwiftUI 0x00000001b46b1e54 closure #1 in SubmitTriggerSource.dispatchUpdate(_:) + 28 (PlatformViewCoordinator.swift:12) 11 SwiftUI 0x00000001b5484488 thunk for @escaping @callee_guaranteed () -> () + 28 (<compiler-generated>:0) 12 AppKit 0x0000000189c174a4 +[NSAppearance _performWithCurrentAppearance:usingBlock:] + 72 (NSAppearance.m:2408) 13 SwiftUI 0x00000001b53b2088 specialized static NSColor.withColorAppearance(in:_:) + 324 (AppKitColorConversions.swift:142) 14 SwiftUI 0x00000001b53b1e7c protocol witness for ColorProvider.resolve(in:) in conformance NSColor + 68 (<compiler-generated>:151) 15 SwiftUICore 0x0000000222436e6c ColorBox.resolve(in:) + 124 (Color.swift:288) 16 SwiftUICore 0x0000000222435e30 Color.resolve(in:) + 72 (Color.swift:87) 17 SwiftUI 0x00000001b53b1c88 closure #1 in NSColor.init(_:) + 196 (AppKitColorConversions.swift:124) 18 SwiftUI 0x00000001b4542714 thunk for @escaping @callee_guaranteed (@guaranteed NSAppearance) -> (@owned NSColor) + 56 (<compiler-generated>:0) 19 AppKit 0x0000000189c31e74 -[NSDynamicNamedColor colorUsingColorSpace:] + 32 (NSColor.m:4410) //// ... Repeating for 500 lines 500 SwiftUICore 0x0000000221ca9fd8 CoreColorPlatformColorGetComponents + 116 (CoreColorFunctions.m:149) 501 SwiftUICore 0x0000000221faaf28 specialized Color.Resolved.init(platformColor:) + 92 (CoreColor.swift:14) 502 SwiftUICore 0x0000000221faa5b0 Color.Resolved.init(platformColor:) + 16 (<compiler-generated>:0) 503 SwiftUI 0x00000001b53b1dc4 closure #1 in NSColor.resolve(in:) + 20 (AppKitColorConversions.swift:156) 504 SwiftUI 0x00000001b53b222c partial apply for closure #1 in static NSColor.withColorAppearance(in:_:) + 32 (<compiler-generated>:0) 505 SwiftUI 0x00000001b46b1e54 closure #1 in SubmitTriggerSource.dispatchUpdate(_:) + 28 (PlatformViewCoordinator.swift:12) 506 SwiftUI 0x00000001b5484488 thunk for @escaping @callee_guaranteed () -> () + 28 (<compiler-generated>:0) 507 AppKit 0x0000000189c174a4 +[NSAppearance _performWithCurrentAppearance:usingBlock:] + 72 (NSAppearance.m:2408) 508 SwiftUI 0x00000001b53b2088 specialized static NSColor.withColorAppearance(in:_:) + 324 (AppKitColorConversions.swift:142) 509 SwiftUI 0x00000001b53b1e7c protocol witness for ColorProvider.resolve(in:) in conformance NSColor + 68 (<compiler-generated>:151) 510 SwiftUICore 0x0000000222436e6c ColorBox.resolve(in:) + 124 (Color.swift:288) full-log.crash
Replies
0
Boosts
0
Views
145
Activity
May ’25
UIPanGestureRecognizer is broken on iPadOS26
import UIKit class ViewController: UIViewController { var panGesture = UIPanGestureRecognizer() override func viewDidLoad() { super.viewDidLoad() panGesture.isEnabled = true panGesture.minimumNumberOfTouches = 0 panGesture.maximumNumberOfTouches = 5 panGesture.allowedScrollTypesMask = .continuous panGesture.addTarget(self, action: #selector(gestureUpdate(_:))) view.addGestureRecognizer(panGesture) } @objc private func gestureUpdate(_ gesture: UIPanGestureRecognizer) { print("OS: \(osVersion), date: \(Date.now), numberOfTouches: \(gesture.numberOfTouches)") } private var osVersion: String { let osVersion = ProcessInfo.processInfo.operatingSystemVersion return "\(osVersion.majorVersion).\(osVersion.minorVersion).\(osVersion.patchVersion)" } } it's hard to recognize 3 or more fingers gesture on iPadOS26.
Topic: UI Frameworks SubTopic: UIKit
Replies
0
Boosts
1
Views
101
Activity
Jun ’25
viewIsAppearing not be called in children Controllers below iOS 16?
I see viewIsAppearing is available on iOS 13 and above, but when I use it, found that the function not be called below iOS 16 https://developer.apple.com/documentation/uikit/uiviewcontroller/4195485-viewisappearing environment: Macos 14.4.1, Xcode 15.3 import UIKit class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() let sub = SubViewController() addChild(sub) view.addSubview(sub.view) } @available(iOS 13.0, *) override func viewIsAppearing(_ animated: Bool) { super.viewIsAppearing(animated) print("ViewController viewIsAppearing") } } class SubViewController: UIViewController { @available(iOS 13.0, *) override func viewIsAppearing(_ animated: Bool) { super.viewIsAppearing(animated) print("SubViewController viewIsAppearing") } } In iOS 15 devcice console log: ViewController viewIsAppearing iOS 16, 17: ViewController viewIsAppearing SubViewController viewIsAppearing
Topic: UI Frameworks SubTopic: UIKit Tags:
Replies
3
Boosts
0
Views
1k
Activity
May ’25
Applying the `.prominent` modifier to a toolbar action
Hi y'all! I'm creating an iOS app with SwiftUI. Part of the app's layout will have a toolbar. Per the HIG's Toolbar article, under the section titled "Actions", the primary action in the toolbar should use the .prominent modifier. Unfortunately, I'm having issues finding information about this modifier in the SwiftUI reference documentation, and Xcode's code completion (the standard completions; I don't use the language model version) doesn't reveal anything that seems to be usable to create the desired effect. For reference, this is what the view currently looks like: VStack { } .toolbar { ToolbarItem(placement: .topBarTrailing) { Button("Add Something", systemImage: "plus") { print("perform action") } } } Is this modifier added to the button itself as .buttonStyle(.borderedProminent)? This seems to create an odd off-center layout shift in the Xcode preview, the Simulator, and my physical device. Is it added to the toolbar item with a similarly-named modifier? Thanks all! :)
Replies
1
Boosts
1
Views
121
Activity
Jun ’25
The URL authorization read and write obtained by UIDocumentPickerViewController
The URL directory obtained by UIDocumentPickerVieweController can be read and written in the directory after calling startAccessingDecurityScopeResource. However, after restarting the app, if the URL saved in the package is called startAccessingDecurityScopeResource again and returns NO, UIDocumentPickerVieweController must be called again to retrieve the URL, and then startAccessingDecurityScopeResource must be called again before continuing the operation. This is too troublesome. Is there a way to continue reading and writing operations in the URL directory after restarting the app?
Replies
1
Boosts
0
Views
84
Activity
May ’25
How to move from Share Extension to the main screen
My app is designed to share and import images with apps such as the File app. I created a program after looking at various information, but the app from which the images are shared does not work, and the screen cannot be moved to the main screen of my app. The program is as follows. How should I modify it? import UIKit import MobileCoreServices import UniformTypeIdentifiers class ShareViewController: UIViewController { let suiteName: String = "group.com.valida.pettyGeneral" let keyString: String = "share-general" override func viewDidLoad() { var nameArray: [String] = [String]() let sharedDefaults: UserDefaults = UserDefaults(suiteName: self.suiteName)! guard let inputItem = self.extensionContext?.inputItems.first as? NSExtensionItem, let attachments = inputItem.attachments else { return } let identifier = UTType.image.identifier let imgAttachments = attachments.filter { $0.hasItemConformingToTypeIdentifier(identifier) } let dispatchGroup = DispatchGroup() for (no, itemProvider) in imgAttachments.enumerated() { dispatchGroup.enter() itemProvider.loadItem(forTypeIdentifier: identifier, options: nil) { [self] item, error in do { if let error = error { throw error } else if let url = item as? URL { let data = try Data(contentsOf: url) let fileManager = FileManager.default let url = fileManager.containerURL(forSecurityApplicationGroupIdentifier: suiteName) if let url = url?.appendingPathComponent(String(no)) { try! data.write(to: url) } nameArray.append(String(no)) } do { dispatchGroup.leave() } } catch { print("Error") do { dispatchGroup.leave() } } } } dispatchGroup.notify(queue: .main) { [self] in // 全ての画像を保存 sharedDefaults.set(nameArray, forKey: self.keyString) sharedDefaults.synchronize() // メニュー画面に移動する openUrl(url: URL(string: "container-general://")) self.extensionContext!.completeRequest(returningItems: [], completionHandler: nil) } } //#selector(openURL(_:))はこの関数がないと作れない @objc func open(_ url: URL) {} func openUrl(url: URL?) { let selector = #selector(open(_ : )) var responder = (self as UIResponder).next while let r = responder, !r.responds(to: selector) { responder = r.next } _ = responder?.perform(selector, with: url) } func openContainerApp() { let url = URL(string: "container-general://") // カスタムスキームを作って指定する var responder: UIResponder? = self while responder != nil { if let application = responder as? UIApplication { let selector = sel_registerName("openURL:") application.perform(selector, with: url) break } responder = responder?.next } } }
Replies
0
Boosts
0
Views
157
Activity
Jun ’25
iOS app crash with UIKitcore - UIAlertController
I have recently submitted a new app version to the Appstore with Xcode 15.0. Unfortunately, I have started to see the below crash in the Xcode organiser &gt; Crashes section occurring for more number of times. UIKitCore: +[UIAlertController _alertControllerContainedInViewController:] + 160 The exception trace is not leading to main() function but not pointing to any of the code line. I had used UIAlertController in the past versions to show the alerts but there is no code written in the current version code related to UIAlertController. Only from the latest version, this kind of crash started to surface. In the latest release, We have added a third party SDK and while implementing the SDK, we had added the Location and Bluetooth Permissions in Info.plist file. But as we don't want to use/track the Location and Bluetooth details from the app, the SDK team has disabled the Location and Bluetooth settings to not reflect in the tracked data. Is this behaviour creating any conflict with the UIAlertController and logging the crash? Because by default the OS tries to show the alert when the permissions exist in the plist file, but the alert will not come as the service is disabled on the SDK server settings. Is this creating any conflict and logging the crash. Please extend your help.
Replies
3
Boosts
0
Views
904
Activity
May ’25
iOS26 beta ToolbarItem with placement to principal width is not fill to screen
I’m trying to add a TextField to the toolbar using .principal placement, and I want it to either fill the screen width or expand based on the surrounding content. However, it’s not resizing as expected — the TextField only resizes correctly when I provide a hardcoded width value. This behavior was working fine in previous versions of Xcode, but seems to be broken in Xcode 26. Not sure if this is an intentional change or a bug. i am using iOS26 beta and Xcode 26 beta struct ContentView: View { var body: some View { VStack { Image(systemName: "globe") .imageScale(.large) .foregroundStyle(.tint) Text("Hello, world!") } .padding() .toolbar { ToolbarItem(placement: .principal) { HStack { TextField("Search", text: .constant("")) .textFieldStyle(.roundedBorder) .frame(maxWidth: .infinity) // .frame(width: 300) Button("cancel") { } } .frame(maxWidth: .infinity) } } } } #Preview { NavigationView { ContentView() } }
Replies
0
Boosts
0
Views
338
Activity
Jun ’25
CATiledLayer flashes and re-draws entirely when re-drawing a single tile
I have filed a bug report for this (FB17734946), but I'm posting it here verbatim in case others have the same issue and in hopes of getting attention from an Apple engineer sooner. When calling setNeedsDisplayInRect on a CATiledLayer - or a UIView whose backing layer is CATiledLayer - one would expect to re-draw only a region identified by the rect passed to the method. This is even written in the documentation for the class: "Regions of the layer may be invalidated using the setNeedsDisplayInRect: method however the update will be asynchronous. While the next display update will most likely not contain the updated content, a future update will." However, upon calling this method, CATiledLayer redraws whole contents instead of just the tile at the specified rect, and it flashes when doing so. It behaves exactly the same as if one had called setNeedsDisplay without passing any rect; all contents are cleared and re-drawn again. I'm 100% sure I've passed in the correct rect of the exact tile that I need to redraw. I have even tried passing much smaller rects, but still the same. (And yes, the rect I've passed accounts for the current level of detail.) I have found this GitHub repo https://github.com/frankus/NetPhotoScroller, which based on discussion from here https://forums.macrumors.com/threads/catiledlayer-blanks-out-tiles-when-redrawing.1333948/ aims at solving these issues by using two private methods on CATiledLayer class: (void)setNeedsDisplayInRect:(CGRect)r levelOfDetail:(int)level; (BOOL)canDrawRect:(CGRect)rect levelOfDetail:(int)level; I have explored the repo in detail, however I wasn't able to test exactly this code from the GitHub repo. I have tried using those two private methods myself (through an Objective-C class that defines the methods in the header file and then a swift class which inherits it), but I couldn't solve the issue; the flashing and the full re-draw is still there. After doing a lot of research, the conclusion seems to be that one cannot use CATiledLayer with contents that are downloaded remotely, on demand, as tiles are being requested. I have, however, found one interesting thing which seems to work so far: before calling setNeedsDisplayInRect (or just setNeedsDisplay, as they behave the same for CATiledLayer in my testing), cache the current layer's contents, and after calling setNeedsDisplay (or setNeedsDisplayInRect), restore the contents back to the layer. This prevents flashing and preserves any tiles that were drawn at the time of the re-draw. let c = tiledLayer.contents tiledLayer.setNeedsDisplay(tileRect) tiledLayer.contents = c However! Docs clearly state the warning: Do not attempt to directly modify the contents property of a CATiledLayer object. Doing so disables the ability of a tiled layer to asynchronously provide tiled content, effectively turning the layer into a regular CALayer object. I believe this message implies modifying the contents property with some raw content, like image data, and that it may be safe to re-apply the existing contents (which are in my testing of type CAImageProvider) -- but I can't rely on an implementation detail in my production app. I have tested this and confirmed that the bug appears on: iPhone 14 Pro, iOS 18.5 iPhone 13 Pro, iOS 17.5.1 iPhone 5s, iOS 15.8.3 iPad Pro 1st gen, iPadOS 18.4.1 a couple simulator versions I can also confirm that the fix (to re-apply contents property) is also working properly on all these versions. Is this expected behavior, that tiled layer redraws itself entirely instead of redrawing specific tiles? Is it safe to modify contents of a CATiledLayer by re-applying the existing contents? If not, is there an alternative to avoid flashing?
Replies
3
Boosts
0
Views
212
Activity
May ’25
Additional Questions Regarding App Launch Timing
I found the following statement on the site TN3187: Migrating to the UIKit scene-based life cycle | Apple Developer Documentation: "Soon, all UIKit based apps will be required to adopt the scene-based life-cycle, after which your app won’t launch if you don’t. While supporting multiple scenes is encouraged, only adoption of scene life-cycle is required." In this post, you mentioned that the timing is undecided. https://developer.apple.com/forums/thread/785588 I would like to confirm the following two points additionally. Could you please confirm whether the timing when the app will not be able to launch is during an iOS update or at another specific time? This will change our response policy. Does "your app won’t launch" mean that already distributed apps will also not be able to launch? Or does it mean that newly developed apps will fail to build or be rejected during app review?
Topic: UI Frameworks SubTopic: UIKit Tags:
Replies
2
Boosts
0
Views
347
Activity
Jun ’25
AppIntent complie issue & manual remove AppIntent dialog
1.When I attempted to open the subsequent AppIntent within the perform method of the AppIntent instance, I always received the following error: How to solve the problems of inconsistency of this type? I couldn't find any sample code. 2.When I used method 'Button(intent: OpenAppIntent())' to open my app through the dialog custom view of AppIntent, but I couldn't find a way to close this AppIntent dialog. How can i remove this dialog?
Topic: UI Frameworks SubTopic: General
Replies
2
Boosts
0
Views
90
Activity
May ’25
Ios 26 clock widget not dynamically updating in mobile.
Ios 26 clock widget not dynamically updating in mobile.
Replies
1
Boosts
0
Views
155
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
openURL:options:completionHandler: Not Opening tel:// Link on iPad with Cellular Data
We are using openURL:options:completionHandler: to open a tel:// number in the dialer to place a call. This works on iPhones and WiFi-only iPads (tested with a iPad Mini 6th Gen), but it is failing to open on an iPad 8th Gen (WiFi + Cellular) running iPadOS 18.5 being used by a customer. Prior to updating the iPad to iPadOS 18, the call worked on iPadOS 15.2 and opened the call in FaceTime as expected. Despite not opening the dialer in iPadOS 18, the completionHandler returns the success parameter as true. canOpenUrl also returns true. We created a small test application that reproduces the issue using the code snippet below in a new application, with the tel schema added to the info.plist Queried URL Schemes. We are currently using Xcode 16.3. Test Steps: Create a new blank application and replace ContentView.swift with the code snippet below Run the test app on a physical iPad 8th Gen (WiFi + Cellular) Tap the "place a test call" button Expected Results: The user is prompted to call the number and is taken to FaceTime to attempt the call. The user may then receive an alert telling them an iPhone must be paired if not already. Alternatively: return success = false in the completionHandler. Actual Results: No action occurs that is visible to the user, and the completionHandler returns success = true. Separately, we should be able to have some method of checking if the device can actually complete a call, i.e. if an iPhone is paired, so that we can correctly show or hide a phone icon in the app based on if the user can place a call. canOpenUrl returns true even if there is not a device paired and the call cannot actually be placed, and there doesn't seem to be a proper method for making that check. Code Snippet: import SwiftUI struct ContentView: View { @State private var showAlert = false var body: some View { VStack { Image(systemName: "globe") .imageScale(.large) .foregroundStyle(.tint) Text("Hello, world!") Button("Place a test call") { if let url = URL(string: "tel://5555554567") { UIApplication.shared.open(url) { success in if success { print("Call initiated successfully.") } else { showAlert = true } } } } } .padding() .alert("Call Failed", isPresented: $showAlert) { Button("OK") { showAlert = false } } message: { Text("The call could not be initiated.") } } } #Preview { ContentView() }
Replies
0
Boosts
1
Views
243
Activity
Jun ’25
Xcode 16.2, UITabBar, UITabBarItem badge is cut, iPadOS 18.0
The badge is cut if it's assigned to the last item. Is it a known issue? Thank you.
Topic: UI Frameworks SubTopic: UIKit Tags:
Replies
2
Boosts
0
Views
105
Activity
May ’25
macOS Sequoia/Xcode 16.2 - Catalyst App Missing Tab Bar
My Objective-C Catalyst app when built with Xcode 16.x/iOS 18 does not have a visible Tab Bar when run on Sequoia. App starts up in first tab, but there is no way to access other tabs. The same app when run on macOS Sonoma (or macOS Catalina) has a normal Tab Bar. The app has an initial View UITabBarController with 3 tabs. The main tab is a UiSplitViewController. Minimum macOS deployment 10.5. If app is built on Sonoma with Xcode 15.x/iOS 17 the Tab Bar is normal on macOS Sonoma, Sequoia, and Catalina. I've tried without success: if (@available(macCatalyst 18.0, *)) { self.tabBarController.tabBarHidden = false; } else { // Fallback on earlier versions } I wonder if this console log message has anything to do with the problem: CLIENT OF UIKIT REQUIRES UPDATE: This process does not adopt UIScene lifecycle. This will become an assert in a future version.
Replies
2
Boosts
0
Views
286
Activity
Jun ’25
A wrinkle converting a UIKit Document-based app to SwiftUI Document Group
The app I'm converting includes two unique document types. UI-wise they have key similarities (eg contents are password protected) But serialization/model - wise. they are different documents. I have not been able to find any documentation on options for implementing this (eg use a (abstract?) base class derived from FileDocument, with two concrete sub classes? maybe just a single subclass of FileDocument that contains model details for both file types?) Stepping back from implementation options, am I crazy for attempting to use DocumentGroup to create a single app that would need to be able to open/modify/save multiple unique document types? any/all guidance much appreciated.
Topic: UI Frameworks SubTopic: SwiftUI
Replies
0
Boosts
0
Views
80
Activity
May ’25
How can I make a new item from within a navigationlink?
Sorry if this is too basic, but I really can't figure out how to make this work. I am trying to make a journal app and I want to have a button that creates a new journalentry and then loads it. This code snippet (I removed irrelevant bits) shows how I'm trying to go about it. Basically, the newEntryButtons should launch a JournalPromptRoute for one of the different options: that's the method argument. But putting .createNewEntry() inside the argument means that new entries are being constantly created. I want the system to create a new entry once on the button press and then go to it from the navigationDestination area. Can anyone please explain to me how this is supposed to work? I believe the code snippet is detailed enough to get the point across but please let me know if you need more info. case library case blank(entry: Entry) case mystery case summary(entry: Entry) case entry(entry: Entry) } struct JournalHome: View { @ObservedObject var viewModel: JournalViewModel var mainContent: some View { ScrollView { newEntryButtons LazyVStack { ForEach(filteredEntries) { entry in NavigationLink( value: JournalPromptRoute.entry(entry: entry) ) { JournalCard(entry) } } } } } var body: some View { NavigationStack(path: $path) { mainContent .navigationDestination(for: JournalPromptRoute.self) { route in switch route { case .blank(let entry): JournalEntryView( entry: entry, index: 0, viewModel: viewModel ) } } } } var newEntryButtons: some View { ScrollView(.horizontal) { HStack(spacing: 15) { EntryButton( description: "Add blank entry", method: JournalPromptRoute.blank(entry: viewModel.createNewEntry()), viewModel: viewModel, path: $path ) EntryButton( description: "Select a Journey", method: JournalPromptRoute.library, viewModel: viewModel, path: $path ) EntryButton( description: "Let the Journey find you", method: JournalPromptRoute.mystery, viewModel: viewModel, path: $path ) } } } }
Topic: UI Frameworks SubTopic: SwiftUI
Replies
2
Boosts
0
Views
102
Activity
Jun ’25