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

SwiftUI Gestures prevent scrolling with iOS 18
I added gesture support to my app that supports iOS 16 and 17 and have never had issues with it. However, when I compiled my app with Xcode 16 I immediately noticed a problem with the app when I ran it in the simulator. I couldn't scroll up or down. I figured out it’s because of my gesture support. My gesture support is pretty simple. let myDragGesture = DragGesture() .onChanged { gesture in self.offset = gesture.translation } .onEnded { _ in if self.offset.width > threshold { ...some logic } else if self.offset.width < -threshold { ...some other logic } logitUI.debug("drag gesture width was \(self.offset.width)") self.offset = .zero } If I pass nil to .gesture instead of myDragGesture then scrolling starts working again. Here’s some example output when I’m trying to scroll down. These messages do NOT appear when I run my app on an iOS 16/17 simulator with Xcode 15. drag gesture width was 5.333328 drag gesture width was -15.333344 drag gesture width was -3.000000 drag gesture width was -24.333328 drag gesture width was -30.666656 I opened FB14205678 about this.
17
21
11k
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
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
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
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
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
158
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
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
iOS UILabel textAlignment .justified results in wrong rect by layoutManager.boundingRect
I have a UILabel subclass showing NSAttributedString in which I need to draw a rounded rectangle background color around links: import UIKit class MyLabel: UILabel { private var linkRects = [[CGRect]]() private let layoutManager = NSLayoutManager() private let textContainer = NSTextContainer(size: .zero) private let textStorage = NSTextStorage() override func draw(_ rect: CGRect) { let path = UIBezierPath() linkRects.forEach { rects in rects.forEach { linkPieceRect in path.append(UIBezierPath(roundedRect: linkPieceRect, cornerRadius: 2)) } } UIColor.systemGreen.withAlphaComponent(0.4).setFill() path.fill() super.draw(rect) } override init(frame: CGRect) { super.init(frame: frame) setup() } required init?(coder: NSCoder) { super.init(coder: coder) setup() } private func setup() { numberOfLines = 0 adjustsFontForContentSizeCategory = true isUserInteractionEnabled = true lineBreakMode = .byWordWrapping contentMode = .redraw clearsContextBeforeDrawing = true isMultipleTouchEnabled = false backgroundColor = .red.withAlphaComponent(0.1) textContainer.lineFragmentPadding = 0 textContainer.maximumNumberOfLines = numberOfLines textContainer.lineBreakMode = lineBreakMode textContainer.layoutManager = layoutManager layoutManager.textStorage = textStorage layoutManager.addTextContainer(textContainer) textStorage.addLayoutManager(layoutManager) } override func layoutSubviews() { super.layoutSubviews() calculateRects() } private func calculateRects(){ linkRects.removeAll() guard let attributedString = attributedText else { return } textStorage.setAttributedString(attributedString) let labelSize = frame.size textContainer.size = labelSize layoutManager.ensureLayout(for: textContainer) let textBoundingBox = layoutManager.usedRect(for: textContainer) print("labelSize: \(labelSize)") print("textBoundingBox: \(textBoundingBox)") var wholeLineRanges = [NSRange]() layoutManager.enumerateLineFragments(forGlyphRange: NSRange(0 ..< layoutManager.numberOfGlyphs)) { _, rect, _, range, _ in wholeLineRanges.append(range) print("Whole line: \(rect), \(range)") } attributedString.enumerateAttribute(.link, in: NSRange(location: 0, length: attributedString.length)) { value, clickableRange, _ in if value != nil { var rectsForCurrentLink = [CGRect]() wholeLineRanges.forEach { wholeLineRange in if let linkPartIntersection = wholeLineRange.intersection(clickableRange) { var rectForLinkPart = layoutManager.boundingRect(forGlyphRange: linkPartIntersection, in: textContainer) rectForLinkPart.origin.y = rectForLinkPart.origin.y + (textContainer.size.height - textBoundingBox.height) / 2 // Adjust for vertical alignment rectsForCurrentLink.append(rectForLinkPart) print("Link rect: \(rectForLinkPart), \(linkPartIntersection)") } } if !rectsForCurrentLink.isEmpty { linkRects.append(rectsForCurrentLink) } } } print("linkRects: \(linkRects)") setNeedsDisplay() } } And I use this as such: let label = MyLabel() label.setContentHuggingPriority(.required, for: .vertical) label.setContentHuggingPriority(.required, for: .horizontal) view.addSubview(label) label.snp.makeConstraints { make in make.width.lessThanOrEqualTo(view.safeAreaLayoutGuide.snp.width).priority(.required) make.horizontalEdges.greaterThanOrEqualTo(view.safeAreaLayoutGuide).priority(.required) make.center.equalTo(view.safeAreaLayoutGuide).priority(.required) } let paragraphStyle = NSMutableParagraphStyle() paragraphStyle.alignment = .justified let s = NSMutableAttributedString(string: "Lorem Ipsum: ", attributes: [.font: UIFont.systemFont(ofSize: 17, weight: .regular), .paragraphStyle: paragraphStyle]) s.append(NSAttributedString(string: "This property controls the maximum number of lines to use in order to fit the label's text into its bounding rectangle.", attributes: [.link: URL(string: "https://news.ycombinator.com/") as Any, .foregroundColor: UIColor.link, .font: UIFont.systemFont(ofSize: 14, weight: .regular), .paragraphStyle: paragraphStyle])) label.attributedText = s Notice the paragraphStyle.alignment = .justified This results in: As you can see, the green rect background is starting a bit further to the right and also ending much further to the right. If I set the alignment to be .left or .center, then it gives me the correct rects: Also note that if I keep .justified but change the font size for the "Lorem Ipsom:" part to be a bit different, lets say 16 instead of 17, then it gives me the correct rect too: Also note that if we remove some word from the string, then also it starts giving correct rect. It seems like if the first line is too squished, then it reports wrong rects. Why is .justified text alignment giving me wrong rects? How can I fix it?
Topic: UI Frameworks SubTopic: UIKit
0
0
116
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
Alert structure and playing sound
Hello, I'm working on an SwiftUI iOS app that shows a list of timers. When the timer is up then I pop up an alert struct. The user hits "ok" to dismiss the alert. I am trying to include an alarm sound using AVFoundation. I can get the sounds to play if I change the code to play when a button clicks so I believe I have the url path correct. But I really want it to play during the alert pop up. I have not been able to find examples where this is done using an alert so I suspect I need a custom view but thought I'd try the alert route first. Anyone try this before? @State var audioPlayer: AVAudioPlayer? .alert(isPresented: $showAlarmAlert) { playSound() -- Calls AVFoundation return Alert(title: Text("Time's Up!")) } func playSound() { let alertSoundPath = Bundle.main.url(forResource: "classicAlarm", withExtension: "mp3")! do { audioPlayer = try AVAudioPlayer(contentsOf: alertSoundPath) audioPlayer?.play() } catch { appData.logger.debug("Error playing sound: \(alertSoundPath)") } }
4
0
174
Jun ’25
.roundedCorners instead of .cornerRadius(?)
In WWDC 25's session Get to Know the Design system, Maria mentions that corner radius should match it's parent view or the iPhone's corners if its the outermost view. Rather than trying to figure out what number to pass into .cornerRadius(15), why not have a .roundedCorner modifier and have the system do this geometry work? See my feedback also FB17947241
Topic: UI Frameworks SubTopic: SwiftUI
2
2
200
Jun ’25
Best Way to Help Users Diagnose iOS App Crashes with No UI Feedback
Hi all, We're working on an iOS application and would like to improve our ability to diagnose failures - especially in scenarios where the app crashes before it can present any UI to the user. A few specific questions: In case of an exception or crash, is there a way to log the issue so the user (or our support team) can understand the cause of the failure? If the app crashes abruptly (e.g., due to a runtime exception or crash during launch), is there a recommended way to persist error information before the process terminates? Are there Apple-supported mechanisms (like crash reporting tools or APIs) we can integrate that would help us capture such issues? What’s the best practice for enabling support teams to assist users based on crash reports - especially for crashes that happen before any user interaction? Our goal is to make sure users aren't left in the dark if the app fails to start, and to allow us to deliver timely updates or support based on the cause of the crash. Thanks in advance for your guidance!
Topic: UI Frameworks SubTopic: General Tags:
0
0
121
May ’25
Old style tab bar
I am maintaining an enterprise iOS app that does a lot of customization to the tab bar's colors based on the organization signed into the app. Is there a way to revert back to the old style full bottom tab bar rather than the new iOS 26 floating version? I know last year in iPad OS you could force the bottom tab using traitOverrides, but I'm not seeing a similar option for this. If anyone has any ideas it would be greatly appreciated.
Topic: UI Frameworks SubTopic: UIKit Tags:
4
1
240
Jun ’25
FamilyActivityTitleView Label has wrong text color when app is using different than system theme
Hello, In a new app I am working on I noticed the FamilyActivityTitleView that displays "ApplicationToken" has wrong (black) color when phone is set to light mode but app is using dark mode via override. We display user's selected apps and the labels are rendered correctly at first, but then when user updates selection with FamilyActivityPicker, then those newly added apps are rendered with black titles. The problem goes away when I close the screen and open it again. It also doesn't happen when phone is set to dark theme. I am currently noticing the issue on iOS 18.4.1. I have tried various workarounds like forcing white text in the custom label style, forcing re-render with custom .id value but nothing helped. Is there any way how to fix this?
0
0
156
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
103
Jun ’25
App Name Display
For now, my app name length is more than 20 characters, so the iPhone app name displays without a space, and uses the range operator to ensure showing the rest in the next line. Is it possible to show space and name with 2 lines?
Topic: UI Frameworks SubTopic: General Tags:
0
0
95
May ’25
SwiftUI internal crash when interacting with long list quickly
Hello! We encountered a very intermittent crash with our application starting with devices running iOS 18.4. We have a screen that can display a long list of products in 2 states (expanded or collapsed) based off of a boolean if the user has interacted with that product yet. With this list, we very intermittently encounter a crash when we scroll like crazy up and down the list search the list quickly (search is performed each character change and list is filtered) Our project has iOS 17.0 as a minimum deployment target, and is Swift 6 enabled. Again, this started happening only with iOS 18.4, and is still visible (handful of occurrences each week). The crash report seems to be very internal to SwiftUI/Obj-c runtime. 5895AC17-6886-4070-BC80-8912E8394BDB.crash Any insights would be greatly appreciated!
3
0
204
Jun ’25
SwiftUI Gestures prevent scrolling with iOS 18
I added gesture support to my app that supports iOS 16 and 17 and have never had issues with it. However, when I compiled my app with Xcode 16 I immediately noticed a problem with the app when I ran it in the simulator. I couldn't scroll up or down. I figured out it’s because of my gesture support. My gesture support is pretty simple. let myDragGesture = DragGesture() .onChanged { gesture in self.offset = gesture.translation } .onEnded { _ in if self.offset.width > threshold { ...some logic } else if self.offset.width < -threshold { ...some other logic } logitUI.debug("drag gesture width was \(self.offset.width)") self.offset = .zero } If I pass nil to .gesture instead of myDragGesture then scrolling starts working again. Here’s some example output when I’m trying to scroll down. These messages do NOT appear when I run my app on an iOS 16/17 simulator with Xcode 15. drag gesture width was 5.333328 drag gesture width was -15.333344 drag gesture width was -3.000000 drag gesture width was -24.333328 drag gesture width was -30.666656 I opened FB14205678 about this.
Replies
17
Boosts
21
Views
11k
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
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
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
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
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
158
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
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
iOS UILabel textAlignment .justified results in wrong rect by layoutManager.boundingRect
I have a UILabel subclass showing NSAttributedString in which I need to draw a rounded rectangle background color around links: import UIKit class MyLabel: UILabel { private var linkRects = [[CGRect]]() private let layoutManager = NSLayoutManager() private let textContainer = NSTextContainer(size: .zero) private let textStorage = NSTextStorage() override func draw(_ rect: CGRect) { let path = UIBezierPath() linkRects.forEach { rects in rects.forEach { linkPieceRect in path.append(UIBezierPath(roundedRect: linkPieceRect, cornerRadius: 2)) } } UIColor.systemGreen.withAlphaComponent(0.4).setFill() path.fill() super.draw(rect) } override init(frame: CGRect) { super.init(frame: frame) setup() } required init?(coder: NSCoder) { super.init(coder: coder) setup() } private func setup() { numberOfLines = 0 adjustsFontForContentSizeCategory = true isUserInteractionEnabled = true lineBreakMode = .byWordWrapping contentMode = .redraw clearsContextBeforeDrawing = true isMultipleTouchEnabled = false backgroundColor = .red.withAlphaComponent(0.1) textContainer.lineFragmentPadding = 0 textContainer.maximumNumberOfLines = numberOfLines textContainer.lineBreakMode = lineBreakMode textContainer.layoutManager = layoutManager layoutManager.textStorage = textStorage layoutManager.addTextContainer(textContainer) textStorage.addLayoutManager(layoutManager) } override func layoutSubviews() { super.layoutSubviews() calculateRects() } private func calculateRects(){ linkRects.removeAll() guard let attributedString = attributedText else { return } textStorage.setAttributedString(attributedString) let labelSize = frame.size textContainer.size = labelSize layoutManager.ensureLayout(for: textContainer) let textBoundingBox = layoutManager.usedRect(for: textContainer) print("labelSize: \(labelSize)") print("textBoundingBox: \(textBoundingBox)") var wholeLineRanges = [NSRange]() layoutManager.enumerateLineFragments(forGlyphRange: NSRange(0 ..< layoutManager.numberOfGlyphs)) { _, rect, _, range, _ in wholeLineRanges.append(range) print("Whole line: \(rect), \(range)") } attributedString.enumerateAttribute(.link, in: NSRange(location: 0, length: attributedString.length)) { value, clickableRange, _ in if value != nil { var rectsForCurrentLink = [CGRect]() wholeLineRanges.forEach { wholeLineRange in if let linkPartIntersection = wholeLineRange.intersection(clickableRange) { var rectForLinkPart = layoutManager.boundingRect(forGlyphRange: linkPartIntersection, in: textContainer) rectForLinkPart.origin.y = rectForLinkPart.origin.y + (textContainer.size.height - textBoundingBox.height) / 2 // Adjust for vertical alignment rectsForCurrentLink.append(rectForLinkPart) print("Link rect: \(rectForLinkPart), \(linkPartIntersection)") } } if !rectsForCurrentLink.isEmpty { linkRects.append(rectsForCurrentLink) } } } print("linkRects: \(linkRects)") setNeedsDisplay() } } And I use this as such: let label = MyLabel() label.setContentHuggingPriority(.required, for: .vertical) label.setContentHuggingPriority(.required, for: .horizontal) view.addSubview(label) label.snp.makeConstraints { make in make.width.lessThanOrEqualTo(view.safeAreaLayoutGuide.snp.width).priority(.required) make.horizontalEdges.greaterThanOrEqualTo(view.safeAreaLayoutGuide).priority(.required) make.center.equalTo(view.safeAreaLayoutGuide).priority(.required) } let paragraphStyle = NSMutableParagraphStyle() paragraphStyle.alignment = .justified let s = NSMutableAttributedString(string: "Lorem Ipsum: ", attributes: [.font: UIFont.systemFont(ofSize: 17, weight: .regular), .paragraphStyle: paragraphStyle]) s.append(NSAttributedString(string: "This property controls the maximum number of lines to use in order to fit the label's text into its bounding rectangle.", attributes: [.link: URL(string: "https://news.ycombinator.com/") as Any, .foregroundColor: UIColor.link, .font: UIFont.systemFont(ofSize: 14, weight: .regular), .paragraphStyle: paragraphStyle])) label.attributedText = s Notice the paragraphStyle.alignment = .justified This results in: As you can see, the green rect background is starting a bit further to the right and also ending much further to the right. If I set the alignment to be .left or .center, then it gives me the correct rects: Also note that if I keep .justified but change the font size for the "Lorem Ipsom:" part to be a bit different, lets say 16 instead of 17, then it gives me the correct rect too: Also note that if we remove some word from the string, then also it starts giving correct rect. It seems like if the first line is too squished, then it reports wrong rects. Why is .justified text alignment giving me wrong rects? How can I fix it?
Topic: UI Frameworks SubTopic: UIKit
Replies
0
Boosts
0
Views
116
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
Alert structure and playing sound
Hello, I'm working on an SwiftUI iOS app that shows a list of timers. When the timer is up then I pop up an alert struct. The user hits "ok" to dismiss the alert. I am trying to include an alarm sound using AVFoundation. I can get the sounds to play if I change the code to play when a button clicks so I believe I have the url path correct. But I really want it to play during the alert pop up. I have not been able to find examples where this is done using an alert so I suspect I need a custom view but thought I'd try the alert route first. Anyone try this before? @State var audioPlayer: AVAudioPlayer? .alert(isPresented: $showAlarmAlert) { playSound() -- Calls AVFoundation return Alert(title: Text("Time's Up!")) } func playSound() { let alertSoundPath = Bundle.main.url(forResource: "classicAlarm", withExtension: "mp3")! do { audioPlayer = try AVAudioPlayer(contentsOf: alertSoundPath) audioPlayer?.play() } catch { appData.logger.debug("Error playing sound: \(alertSoundPath)") } }
Replies
4
Boosts
0
Views
174
Activity
Jun ’25
.roundedCorners instead of .cornerRadius(?)
In WWDC 25's session Get to Know the Design system, Maria mentions that corner radius should match it's parent view or the iPhone's corners if its the outermost view. Rather than trying to figure out what number to pass into .cornerRadius(15), why not have a .roundedCorner modifier and have the system do this geometry work? See my feedback also FB17947241
Topic: UI Frameworks SubTopic: SwiftUI
Replies
2
Boosts
2
Views
200
Activity
Jun ’25
Best Way to Help Users Diagnose iOS App Crashes with No UI Feedback
Hi all, We're working on an iOS application and would like to improve our ability to diagnose failures - especially in scenarios where the app crashes before it can present any UI to the user. A few specific questions: In case of an exception or crash, is there a way to log the issue so the user (or our support team) can understand the cause of the failure? If the app crashes abruptly (e.g., due to a runtime exception or crash during launch), is there a recommended way to persist error information before the process terminates? Are there Apple-supported mechanisms (like crash reporting tools or APIs) we can integrate that would help us capture such issues? What’s the best practice for enabling support teams to assist users based on crash reports - especially for crashes that happen before any user interaction? Our goal is to make sure users aren't left in the dark if the app fails to start, and to allow us to deliver timely updates or support based on the cause of the crash. Thanks in advance for your guidance!
Topic: UI Frameworks SubTopic: General Tags:
Replies
0
Boosts
0
Views
121
Activity
May ’25
Old style tab bar
I am maintaining an enterprise iOS app that does a lot of customization to the tab bar's colors based on the organization signed into the app. Is there a way to revert back to the old style full bottom tab bar rather than the new iOS 26 floating version? I know last year in iPad OS you could force the bottom tab using traitOverrides, but I'm not seeing a similar option for this. If anyone has any ideas it would be greatly appreciated.
Topic: UI Frameworks SubTopic: UIKit Tags:
Replies
4
Boosts
1
Views
240
Activity
Jun ’25
FamilyActivityTitleView Label has wrong text color when app is using different than system theme
Hello, In a new app I am working on I noticed the FamilyActivityTitleView that displays "ApplicationToken" has wrong (black) color when phone is set to light mode but app is using dark mode via override. We display user's selected apps and the labels are rendered correctly at first, but then when user updates selection with FamilyActivityPicker, then those newly added apps are rendered with black titles. The problem goes away when I close the screen and open it again. It also doesn't happen when phone is set to dark theme. I am currently noticing the issue on iOS 18.4.1. I have tried various workarounds like forcing white text in the custom label style, forcing re-render with custom .id value but nothing helped. Is there any way how to fix this?
Replies
0
Boosts
0
Views
156
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
103
Activity
Jun ’25
App Name Display
For now, my app name length is more than 20 characters, so the iPhone app name displays without a space, and uses the range operator to ensure showing the rest in the next line. Is it possible to show space and name with 2 lines?
Topic: UI Frameworks SubTopic: General Tags:
Replies
0
Boosts
0
Views
95
Activity
May ’25
Status Bar Driving Orientation
With CarPlay, is it possible to programmatically know which side of the screen the status bar is placed on?
Topic: UI Frameworks SubTopic: UIKit Tags:
Replies
2
Boosts
0
Views
260
Activity
Jun ’25
May I ask what the official term is for the top indicator that appears during background recording? I haven't been able to find it in the official documentation.
May I ask what the official term is for the top indicator that appears during background recording? I haven't been able to find it in the official documentation.
Topic: UI Frameworks SubTopic: General
Replies
1
Boosts
0
Views
82
Activity
May ’25
SwiftUI internal crash when interacting with long list quickly
Hello! We encountered a very intermittent crash with our application starting with devices running iOS 18.4. We have a screen that can display a long list of products in 2 states (expanded or collapsed) based off of a boolean if the user has interacted with that product yet. With this list, we very intermittently encounter a crash when we scroll like crazy up and down the list search the list quickly (search is performed each character change and list is filtered) Our project has iOS 17.0 as a minimum deployment target, and is Swift 6 enabled. Again, this started happening only with iOS 18.4, and is still visible (handful of occurrences each week). The crash report seems to be very internal to SwiftUI/Obj-c runtime. 5895AC17-6886-4070-BC80-8912E8394BDB.crash Any insights would be greatly appreciated!
Replies
3
Boosts
0
Views
204
Activity
Jun ’25