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

How to customize item transitions inside a Picker View?
I have a simple Picker where the options available change by the view state. I would like to have the transition animated but the default animation is not good so I tried setting a .transition() and or an .animation() inside an item on the picker but it is ignored. The same happens if the transition is set on the picker itself since it's always present. Am I doing it right and is just not posible or is there something else to do? Code to reproduce the issue: struct ContentView: View { @State var list: [String] = [ "Item 4", "Item 5", "Item 6", "Item 7", "Item 8", ] @State var selected: String? @State var toggle: Bool = false var body: some View { VStack { Picker("List", selection: $selected) { ForEach(list, id: \.self) { Text($0).tag($0) // .transition(.opacity) } } .pickerStyle(.segmented) // .transition(.opacity) HStack { Button(action: swapOptions) { Text("Swap") } } } .padding() } } extension ContentView { func swapOptions() { withAnimation { toggle.toggle() switch toggle { case true: list = [ "Item 1", "Item 2", "Item 3", "Item 4", "Item 5", ] case false: list = [ "Item 4", "Item 5", "Item 6", "Item 7", "Item 8", ] } } } } ``
Topic: UI Frameworks SubTopic: SwiftUI
0
0
99
May ’25
NSLayoutManager returning inconsistent values for a glyph's text container and its line fragment rect
TLDR: NSLayoutManager's textContainer(forGlyphAt:effectiveRange:) and lineFragmentRect(forGlyphRange:effectiveRange:) are returning inconsistent results. Context: I'm developing a word processing app that paginates from an NSTextStorage using NSLayoutManager. My app uses a text attribute (.columnType) to paginate sub-ranges of the text at a time, ensuring that each columnRange gets a container (or series of containers across page breaks) to fit. This is to support both multi-column and standard full-page-width content. After any user edit, I update pagination data in my Paginator model class. I calcuate frames/sizes for the views/containers, along with what superview they belong to (page). The UI updates accordingly. In order to determine whether the columnRange has overflowed from a container due to a page break OR whether the range of text hasn't overflowed its container and is actually using less space than available and should be sized down, I call both: layoutManager.textContainer(forGlyphAt: lastGlyphOfColumn, effectiveRange: &actualGlyphRangeInContainer)` // and `layoutManager.lineFragmentRect(forGlyphAt: lastGlyphOfColumn, effectiveRange: nil) Apple Documentation notes that both these calls force glyph generation and layout. As I'm in early development, I have not set non-contiguous layout. So these should be causing full layout, assuring accurate return values. Or so I'd hoped. This does work fine in many cases. I edit. Pagination works. But then I'll encounter UI-breaking inconsistent returns from these two calls. By inconsistent, I mean that the second call returns a line fragment rect that is in the container coordinates of A DIFFERENT container than the container returned by the first call. To be specific, the line fragment rect seems to be in the coordinates of the container that comes next in layoutManager.textContainers. Example Code: if !layoutManager.textContainers.indices.contains(i) { containerToUse = createTextContainer(with: availableSize) layoutManager.addTextContainer(containerToUse) } else { // We have a container already but it may be // the wrong size. containerToUse = layoutManager.textContainers[i] if containerToUse.size.width != availableSize.width { // Mandatory that we resize if we don't have // a matching width. Height resizing is not // mandatory and requires a layout check below. containerToUse.size = availableSize } } let glyphRange = layoutManager.glyphRange(forCharacterRange: remainingColumnRange, actualCharacterRange: nil) let lastGlyphOfColumn = NSMaxRange(glyphRange) - 1 var containerForLastGlyphOfColumn = layoutManager.textContainer(forGlyphAt: lastGlyphOfColumn, effectiveRange: &actualGlyphRangeInContainer) if containerForLastGlyphOfColumn != containerToUse && containerToUse.size.height < availableSize.height { // If we are here, we overflowed the container, // BUT the container we overflowed didn't use // the maximum remaining page space (this // means it was a pre-existing container that // needs to be sized up and checked once more). // NOTE RE: THE BUG: // at this point, prints show... // containerToUse.size.height // =628 // availableSize.height // =648 containerToUse.size = availableSize containerForLastGlyphOfColumn = layoutManager.textContainer(forGlyphAt: lastGlyphOfColumn, effectiveRange: &actualGlyphRangeInContainer) } // We now check again, knowing that the container we // are testing flow into is the max size it can be. if containerForLastGlyphOfColumn != containerToUse { // If we are here, we have overflowed the // container, so containerToUse size SHOULD be // final/accurate, since it is fully used. actualCharRangeInContainer = layoutManager.characterRange(forGlyphRange: actualGlyphRangeInContainer, actualGlyphRange: nil) // Start of overflow range is the first character // in the container that was overflowed into. let overflowLoc = actualCharRangeInContainer.location remainingColumnRange = NSRange(location: overflowLoc, length: remainingColumnRange.length - overflowLoc) // Update page count as we have broken to a new page currentPage += 1 } else { // If we are here, we have NOT overflowed // from the container. BUT... // THE BUG: // ***** HERE IS THE BUG! ***** lineFragmentRectForLastChar = layoutManager.lineFragmentRect(forGlyphAt: lastGlyphOfColumn, effectiveRange: nil) let usedHeight = lineFragmentRectForLastChar.maxY // BUG: ^The lines of code above return a // fragment rect that is in the coordinates // of the WRONG text container. Prints show: // usedHeight // =14 // usedHeight shouldn't be just 14 if this is // the SAME container that, when it was 628 // high, resulted in text overflowing. // Therefore, the line fragment here seems // to be in the coordinates of the ENSUING // container that we overflowed INTO, but // that shouldn't be possible, since we're in // a closure for which we know: // // containerForLastGlyphOfColumn == containerToUse // // If the last glyph container is the container // we just had to size UP, why does the final // glyph line fragment rect have a maxY of 14!? // Including ensuing code below only for context. if usedHeight < containerToUse.size.height { // Adjust container size down to usedRect containerToUse.size = CGSize(width: containerToUse.size.width, height: usedHeight) } else if usedHeight == availableSize.height { // We didn't force break to a new page BUT // we've used exactly the height of our page // to layout this column range, so need to // break to a new page for any ensuing text // columns. currentPage += 1 } else if usedHeight > containerToUse.size.height { // We should have caught this earlier. Text // has overflowed, but this should've been // caught when we checked // containerForLastGlyphOfColumn != // containerToUse. // // Note: this error has never thrown. throw PaginationError.unknownError("Oops.") } } Per my comments in the code block above, I don't understand why the very same text container that just overflowed and so had to be sized up from 628 to 648 in order to try to fit a glyph would now report that same glyph as both being IN that same container and having a line fragment rect with a maxY of just 14. A glyph couldn't fit in a container when it was 628 high, but if I size it up to 648, it only needs 14? There's something very weird going on here. Working with NSLayoutManager is a bit of a nightmare given the unclear documentation. Any help or insight here would be massively, massively appreciated.
2
0
541
Apr ’25
Xcode 16.3(16E140) failing to debug run but succeeding to build.
Reproduction procedure Launch Xcode and press shift+command+N to create a macOS App project. Edit the generated ContentView.swift to the following content: struct ContentView: View { @State var txt: String = “” var body: some View { VStack { Text(“Hello, world!\(txt)”) TextField(“input”, text: $txt) onSubmit { // lack of a period letter. // .onSubmit { // Correct code print(“onSubmit\(txt)”) } } } } Build with command+B and it succeeds. Debug with command+R, but a rainbow wheel appears and the window does not show. An error is displayed in Xcode’s Preview Canvas, preventing preview.
1
0
119
May ’25
Live Activity fails to start with "unsupportedTarget" error on iOS 18 beta
Hi all, I’m developing a timer app with Live Activity support. On iOS 18.5 (iPhone 14 Pro Max), I cannot get Live Activity to start. When I call Activity.request(...) in my main app, it throws an unsupportedTarget error, and nothing appears on the Lock Screen or Dynamic Island. What I’ve done: Widget Extension Info.plist: <key>NSExtension</key> <dict> <key>NSExtensionPointIdentifier</key> <string>com.apple.widgetkit-extension</string> </dict> <key>NSSupportsLiveActivities</key> <true/> <key>NSSupportsLiveActivitiesFrequentUpdates</key> <true/> Live Activity UI: Implemented with ActivityConfiguration(for: xxx_Clock_liveactivitiesAttributes.self) and Dynamic Island support. App Group: Both main app and extension use the same App Group, and it’s enabled in Apple Developer Center and Xcode. Tested on: iPhone 14 Pro Max, iOS 18.5 (official release) Xcode [your version] (I have not tested on iOS 17.x, so I am not sure if this issue is specific to iOS 18.5.) What I’ve tried: Cleaned build folder, deleted Derived Data, uninstalled and reinstalled app. Rebooted device. Double-checked all Info.plist and entitlements settings. Tried creating a new Widget Extension from scratch. Problem: Activity.request always throws unsupportedTarget. No Live Activity appears on Lock Screen or Dynamic Island. No other errors or crashes. Questions: Has anyone encountered this issue on iOS 18.5? Are there any new requirements or changes for Live Activity in iOS 18.5? Any suggestions or workarounds to make Live Activity work? Any help or suggestions would be greatly appreciated!
2
0
209
Jun ’25
cannot save event
iOS 18.4.1 When I change a Google type event to an iCloud type, a "Cannot Save Event" prompt box pops up. We have also received user feedback that recurring events also fail to save. After updating to iOS 18.4 when trying to save changes to an existing repeating event, the message "Cannot Save Event" will appear. EventKitUI
Topic: UI Frameworks SubTopic: UIKit
0
0
68
May ’25
Dynamic island not displaying UI views
i finally got previews for dynamic island to work and I'm just trying to first work on adding a static UI elements to my dynamic island like i did for my live screen live activity, but my dynamic island view is showing up totally empty, if i add my app icon image to the compact leading closure, it doesn't appear, if i ad text to an expanded region closure it doesn't appear. am really stuck on this and would approeciate the help. var body: some View { Image("dynamicrep") .resizable() .scaledToFit() .clipShape(.circle) } } struct DynamicRepLiveActivity: Widget { var body: some WidgetConfiguration { ActivityConfiguration(for: DynamicRepAttributes.self) { context in VStack { HStack(spacing: 257) { Text("from \(context.attributes.titleName ?? "no title")") .fontWeight(.light) .font(.system(size: 16)) .foregroundStyle(Color.gray) Circle() .frame(width: 53, height: 50) .foregroundStyle(Color.gray).opacity(0.23) .overlay { Image("mmicon") } } .frame(maxWidth: 500, maxHeight: 210) Spacer() Text("\(context.attributes.contentBody ?? "no content")") } .activityBackgroundTint(Color.cyan) .activitySystemActionForegroundColor(Color.black) .frame(width: 500, height: 300) } dynamicIsland: { context in DynamicIsland { // Expanded UI goes here. Compose the expanded UI through // various regions, like leading/trailing/center/bottom DynamicIslandExpandedRegion(.leading) { Text("from \(context.attributes.titleName ?? "no title")") } DynamicIslandExpandedRegion(.trailing) { Circle() } DynamicIslandExpandedRegion(.bottom) { Text("\(context.attributes.contentBody ?? "no content")") } } compactLeading: { AppLogo() } compactTrailing: { Text("") //empty for now } minimal: { Text("hello") //empty for now } .widgetURL(URL(string: "MuscleMemory.KimchiLabs.com")) .keylineTint(Color.white) } } }
1
0
149
Apr ’25
Lists, Generics, Views, Navigation Link, SwiftData - ForEach can't pass a binding anymore.
I'm trying out putting most of my business logic in a Protocol that my @Model can conform to, but I'm running into a SwiftUI problem with a Binding that does not get magically offered up like it does when it the subview is not generic. I have a pretty basic List with a ForEach that now can't properly pass to a generic view based on a protocol. When I try to make a binding manually in the row it says that "item is immutable"... but that also doesn't help me with the NavigationLink? Which is seeing the Binding not the ? But before when the subview was concrete to Thing, it took in the and made its own Binding once it hit the view. I'm unclear on precisely where the change happens and what I can do to work around it. Before I go rearchitecting everything... is there a fix to get the NavigationLink to take on the object like before? What needs to be different? I've tried a number of crazy inits on the subview and they all seem to come back to saying either it can't figure out how to pass the type or I'm trying to use the value before it's been initialized. Have I characterized the problem correctly? Thanks! (let me know if I forgot a piece of code, but this should be the List, the Model/Protocol and the subview) import SwiftUI import SwiftData struct ThingsView: View {     @Environment(\.modelContext) var modelContext     @Query var items: [Thing]          var body: some View {         NavigationStack {             List {                 ForEach(items) { item in                     NavigationLink(value: item) {                         VStack(alignment: .leading) {                             Text(item.textInfo)                                 .font(.headline)                                                          Text(item.timestamp.formatted(date: .long, time: .shortened))                         }                     }                 }.onDelete(perform: deleteItems)             }             .navigationTitle("Fliiiing!") //PROBLEM HERE: Cannot convert value of type '(Binding<Thing>) -> EditThingableView<Thing>' to expected argument type '(Thing) -> EditThingableView<Thing>'             .navigationDestination(for: Thing.self, destination: EditThingableView<Thing>.init) #if os(macOS)             .navigationSplitViewColumnWidth(min: 180, ideal: 200) #endif             .toolbar { #if os(iOS)                 ToolbarItem(placement: .navigationBarTrailing) {                     EditButton()                                      } #endif                 ToolbarItem {                     Button(action: addItem) {                         Label("Add Item", systemImage: "plus")                     }                 }                 ToolbarItem {                     Button("Add Samples", action: addSamples)                 }             }         }     }          func addSamples() {         withAnimation {             ItemSDMC.addSamples(context: modelContext)         }     }          private func addItem() {         withAnimation {             let newItem = ItemSDMC("I did a thing!")             modelContext.insert(newItem)         }     }          func deleteItems(_ indexSet:IndexSet) {         withAnimation {             for index in indexSet {                 items[index].delete(from: modelContext)             }         }     } } #Preview {     ThingsView().modelContainer(for: ItemSDMC.self, inMemory: true) } import Foundation import SwiftData protocol Thingable:Identifiable {     var textInfo:String { get set }     var timestamp:Date { get set } } extension Thingable {     var thingDisplay:String {         "\(textInfo) with \(id) at \(timestamp.formatted(date: .long, time: .shortened))"     } } extension Thingable where Self:PersistentModel {     var thingDisplayWithID:String {         "\(textInfo) with modelID \(self.persistentModelID.id) in \(String(describing: self.persistentModelID.storeIdentifier)) at \(timestamp.formatted(date: .long, time: .shortened))"     } } struct ThingLite:Thingable, Codable, Sendable {     var textInfo: String     var timestamp: Date     var id: Int } @Model final class Thing:Thingable {     //using this default value requires writng some clean up logic looking for empty text info.     var textInfo:String = ""     //using this default value would require writing some data clean up functions looking for out of bound dates.     var timestamp:Date = Date.distantPast          init(textInfo: String, timestamp: Date) {         self.textInfo = textInfo         self.timestamp = timestamp     } } extension Thing {     var LiteThing:ThingLite {         ThingLite(textInfo: textInfo, timestamp: timestamp, id: persistentModelID.hashValue)     } } import SwiftUI struct EditThingableView<DisplayItemType:Thingable>: View {     @Binding var thingHolder: DisplayItemType          var body: some View {                  VStack {             Text(thingHolder.thingDisplay)             Form {                 TextField("text", text:$thingHolder.textInfo)                 DatePicker("Date", selection: $thingHolder.timestamp)             }                      } #if os(iOS)         .navigationTitle("Edit Item")         .navigationBarTitleDisplayMode(.inline) #endif     } } //NOTE: First sign of trouble //#Preview { //    @Previewable var myItem = Thing(textInfo: "Example Item for Preview", timestamp:Date()) //    EditThingableView<Thing>(thingHolder: myItem) //}
4
0
206
May ’25
PKPass Framework
I am trying to work with the data inside the barcode string in shared PKPass. The documentation shows that is should look for @property (nonatomic, readonly, nullable) PKBarcode *primaryBarcode; I have tried to use it like this guard let code = pass.primaryBarcode?.message else { return } I get a constant message that PKPass has no member primaryBarcode The PKPass.h file in my IOS SDK does not seem to include the @property primaryBarcode or @property barcode. I am running Xcode 16.4 (16F6) and my app target is 17.6 + Is there a restriction on this property? I cannot find an SDK later than mine - the App Store does not offer one. I am unsure of this is a public or private issue - does anyone know? Thanks for reading this. Max
Topic: UI Frameworks SubTopic: SwiftUI
0
0
100
Jun ’25
Severe hangs with LazyHStack inside ScrollView
Hi, I got a problem with severe hangs when I use code like this on tvOS 18.2 If I try to use HStack instead of LazyHStack inside the scrollview then the problem does not occur any more but then the scroll performance is compromised and the vertical scroll is no longer that smooth. Does someone has any experience with this? Is this SwiftUI problem or am I missing something? ScrollView { LazyVStack { ForEach(0...100, id: \.self) { _ in ScrollView { LazyHStack { ForEach(0...20, id: \.self) { _ in Color.red.frame(height: 300) } } } } } }
2
0
186
Apr ’25
.onTapGesture does not work when SwiftUI component sits in a flipped NSVIew
Take a look at this simple code: import Cocoa import SwiftUI struct DemoView: View { var body: some View { Text("Click me!") .onTapGesture { print("Clicked") } } } class FlippedView: NSView { override var isFlipped: Bool { return true } } class ViewController: NSViewController { override func viewDidLoad() { super.viewDidLoad() let stackView = NSStackView() stackView.orientation = .vertical stackView.alignment = .leading stackView.spacing = 0 stackView.translatesAutoresizingMaskIntoConstraints = false let hostView = NSHostingView(rootView: DemoView()) stackView.addArrangedSubview(hostView) let scrollView = NSScrollView() scrollView.translatesAutoresizingMaskIntoConstraints = false let flippedView = FlippedView() flippedView.addSubview(stackView) scrollView.documentView = flippedView view.addSubview(scrollView) NSLayoutConstraint.activate([ scrollView.topAnchor.constraint(equalTo: view.topAnchor), scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor), scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor), scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor), ]) } } I need my scroll view to start at the very top, so i put it inside a flipped document view. But now .onTapGesture does not fire.
1
0
168
Apr ’25
UIScrollView in UIViewControllerRepresentable - UI freezes when content touches bottom SafeArea
The SwiftUI ScrollView lacks some features I need and so I created a custom MyScrollView based on UIScrollView wrapped within a UIViewControllerRepresentable. While this works fine in general I know came across a very strange problem: When MyScrollView is used in a sheet and its content touches bottom SafeArea, the UI freezes as soon as the should be displayed. The code below shows the problem as well in preview as on the simulator and on devices. Please note that the code is tuned do the display size of an iPhone 16 Pro. When running on different devices one might need to adjust height of the Color.yellow. In the demo code the UI freezes if the Color.yellow has a height between 738 to 771 pixels. Every other height is fine. Is there something wrong with my implementation of MyScrollView? When using ScrollView instead, everything works fine. Code: struct ContentView: View { @State private var showSheet: Bool = false var body: some View { ZStack { Button("Show Sheet") { showSheet = true } } .sheet(isPresented: $showSheet) { VStack { Text("Some Header Content") MyScrollView { VStack { Color.yellow //.frame(height: 737) // works .frame(height: 738) // does NOT works // ... //.frame(height: 771) // does NOT works //.frame(height: 772) // works } } .ignoresSafeArea() } } } } struct MyScrollView<Content: View>: UIViewControllerRepresentable { let content: Content init(@ViewBuilder content: () -> Content) { self.content = content() } func makeUIViewController(context: Context) -> UIViewController { let scrollViewVC = UIViewController() scrollViewVC.view.backgroundColor = .clear let scrollView = UIScrollView() scrollView.backgroundColor = .clear let contentVC = UIHostingController(rootView: self.content) contentVC.view.backgroundColor = .clear context.coordinator.contentVC = contentVC context.coordinator.scrollView = scrollView scrollView.translatesAutoresizingMaskIntoConstraints = false scrollViewVC.view.addSubview(scrollView) NSLayoutConstraint.activate([ scrollView.topAnchor.constraint(equalTo: scrollViewVC.view.topAnchor), scrollView.bottomAnchor.constraint(equalTo: scrollViewVC.view.bottomAnchor), scrollView.leadingAnchor.constraint(equalTo: scrollViewVC.view.leadingAnchor), scrollView.trailingAnchor.constraint(equalTo: scrollViewVC.view.trailingAnchor) ]) contentVC.willMove(toParent: scrollViewVC) scrollViewVC.addChild(contentVC) contentVC.view.translatesAutoresizingMaskIntoConstraints = false scrollView.addSubview(contentVC.view) NSLayoutConstraint.activate([ contentVC.view.topAnchor.constraint(equalTo: scrollView.contentLayoutGuide.topAnchor), contentVC.view.bottomAnchor.constraint(equalTo: scrollView.contentLayoutGuide.bottomAnchor), contentVC.view.leadingAnchor.constraint(equalTo: scrollView.contentLayoutGuide.leadingAnchor), contentVC.view.trailingAnchor.constraint(equalTo: scrollView.contentLayoutGuide.trailingAnchor), contentVC.view.widthAnchor.constraint(equalTo: scrollView.frameLayoutGuide.widthAnchor) ]) contentVC.didMove(toParent: scrollViewVC) return scrollViewVC } func updateUIViewController(_ uiViewController: UIViewController, context: Context) { context.coordinator.contentVC?.rootView = content } func makeCoordinator() -> Coordinator { return Coordinator() } class Coordinator { var contentVC: UIHostingController<Content>? var scrollView: UIScrollView? init() { //... } } } #Preview { ContentView() }
Topic: UI Frameworks SubTopic: SwiftUI
2
0
116
Apr ’25
visionOS 26.0 beta does not call .onTapGesture
Prior to visionOS 2.5, .onTapGesture was called with the following structure, but in visionOS 26.0 beta, it is no longer called. Is .onTapGesture deprecated in visionOS 26.0 and above? Or is it a bug? TabView(selection: $selectedTab) { WebViewView(selectedTab: $selectedTab) .onTapGesture { viewModel.userDidInteract = true } }
2
0
104
Jun ’25
Access DocumentGroup container by external WindowGroup
Hi, I am currently developing a document-based application for macOS and have encountered a challenge related to document container management. Specifically, I need to open a windowGroup that shares the same container as the one used in the DocumentGroup. However, my current approach of using a global shared model container has led to unintended behavior: any new document created is linked to existing ones, and changes made in one document are reflected across all documents. To address this issue, I am looking for a solution that allows each newly created document to be individualized while still sharing the document container with all relevant WindowGroups that require access to the data it holds. I would greatly appreciate any insights or recommendations you might have on how to achieve this. Thank you for your time and assistance. Best regards, Something like: @main struct Todo: App { var body: some Scene { DocumentGroup(editing: Item.self, contentType: .item) { ContentView() } WindowGroup { UndockView() .modelContainer(of documentGroup above) } } }
0
0
90
Apr ’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
254
Jun ’25
Apple Pay
I'm implementing Apple Pay in a Flutter iOS app using the pay plugin and Braintree as the payment processor. I have followed all necessary steps as outlined by Apple and community resources (e.g., Medium articles, official Apple Developer documentation), but the Apple Pay button does not appear on a real device. Here's what I've completed: Created an Apple Pay Merchant ID Created and downloaded the Apple Pay Payment Processing Certificate, then uploaded it to Braintree Downloaded the Braintree-signed certificate and confirmed it's active in the Apple Developer portal Added the Merchant ID under Signing & Capabilities in Xcode Enabled Apple Pay capability in Xcode Added the Merchant ID to Info.plist Installed required Flutter packages (e.g., pay) Using a valid Apple Pay payment configuration file in Flutter (see below) Tested on a real iOS device with a valid Apple Pay test card added to Wallet Flutter Payment Configuration (in Dart JSON): json Copy Edit { "provider": "apple_pay", "data": { "merchantIdentifier": "merchant.com.example", "displayName": "My Store", "merchantCapabilities": ["3DS", "debit", "credit"], "supportedNetworks": ["visa", "masterCard", "amex"], "countryCode": "US", "currencyCode": "USD" } } Despite this complete setup, the ApplePayButton widget remains invisible There are no errors in the console. Can you help identify what may be missing or misconfigured at the code or configuration level?
2
0
205
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
97
Jun ’25
ObservableObjects get retained after a TextField is focused
When presenting a SwiftUI sheet containing ObservableObject's injected using environmentObject(_) modifier, the objects are unexpectedly retained after the sheet is dismissed if a TextField within the sheet gains focus or is edited. This issue occurs on iOS and iPadOS (on macOS the objects are always released), observable both in the simulator and on physical devices, and happens even when the view does not explicitly reference these environment objects, and the TextField's content isn't bound to them. Expected Results: When the sheet is dismissed, all environment objects passed to the sheet’s content view should be released (deinitialized), regardless of whether the TextField was focused or edited. Actual Results: If the TextField was focused or edited, environment objects (ObservableA and ObservableB) are retained after the sheet is dismissed. They are not deinitialized as expected, leading to unintended retention. Interestingly, previously retained copies of these environment objects, if any, are released precisely at the moment the TextField becomes focused on subsequent presentations, indicating an inconsistent lifecycle behavior. I have filed an issue FB17226970 Sample Code Below is a sample code that consistently shows the issue on iOS 18.3+. Steps to Reproduce: Run the attached SwiftUI sample. Tap the button labeled “Show Sheet” to present a sheet. Tap on the TextField to focus or begin editing. Dismiss the sheet by dragging it down or by other dismissal methods (e.g., tapping outside on iPadOS). import SwiftUI struct ContentView: View { @State private var showSheet: Bool = false var body: some View { VStack { Button("Show Sheet") { showSheet = true } } .sheet(isPresented: $showSheet) { SheetContentView() .environmentObject(ObservableA()) .environmentObject(ObservableB()) } } } struct SheetContentView: View { @State private var text: String = "" var body: some View { TextField("Select to retain observable objects", text: $text) .textFieldStyle(.roundedBorder) } } final class ObservableA: ObservableObject { init() { print(type(of: self), #function) } deinit { print(type(of: self), #function) } } final class ObservableB: ObservableObject { init() { print(type(of: self), #function) } deinit { print(type(of: self), #function) } } #Preview { ContentView() }
2
0
201
Apr ’25
Live activity widget not updated locally after server update
I am using live activity in my app. Functionality is start, update & end events are started from the server. There is one interaction button added using app intent in live activity widget. That button needs to update widget ui locally using activity kit. Issue is when os receives first start event push then update ui works fine and reflecting on live activity widget but when update notification receives by os after 1 mins then action button stops updating the ui locally. Can anyone please add some suggestions to fix this.
0
0
139
May ’25
List Layout Breaks in NavigationStack When a View Exceeds Screen Width
This is a bug report. FB17433985 The layout of the following ContentView appears correctly when it is outside a NavigationStack. However, when the same view is placed inside a NavigationStack, the layout breaks. It seems that the width of the List is being affected by the width of the buttonsView, which exceeds the screen width. In my testing, this issue occurs on iOS 18.4 and later, but does not occur on iOS 18.2 or iOS 17.5. Workaround I found: Remove the fixed width modifier from the Button If anyone knows of other ways to resolve this issue without affecting the layout, I would appreciate it if you could share them. import SwiftUI let values = (1...100).map { $0 } let buttonTitles = (1...9).map { "Button\($0)" } struct ContentView: View { var body: some View { VStack { List { Section { ForEach(values.indices, id: \.self) { val in HStack { Text("Index: \(val)") } } } } buttonsView } } private var buttonsView: some View { HStack { ForEach(0..<buttonTitles.count, id: \.self) { index in Button() { } label: { Image(systemName: "square.and.arrow.up") .resizable() .frame(width: 48, height: 48) } } } } } @main struct ButtonShapeBugApp: App { var body: some Scene { WindowGroup { if true { NavigationStack { ContentView() } } else { ContentView() } } } } Environment: Xcode Version 16.3 (16E140) iPhone 18.4.1 real device iPhone SE3rd 18.4 simulator Expect layout Broken layout(9 buttons) Broken layout(10 buttons)
2
0
95
May ’25
How to customize item transitions inside a Picker View?
I have a simple Picker where the options available change by the view state. I would like to have the transition animated but the default animation is not good so I tried setting a .transition() and or an .animation() inside an item on the picker but it is ignored. The same happens if the transition is set on the picker itself since it's always present. Am I doing it right and is just not posible or is there something else to do? Code to reproduce the issue: struct ContentView: View { @State var list: [String] = [ "Item 4", "Item 5", "Item 6", "Item 7", "Item 8", ] @State var selected: String? @State var toggle: Bool = false var body: some View { VStack { Picker("List", selection: $selected) { ForEach(list, id: \.self) { Text($0).tag($0) // .transition(.opacity) } } .pickerStyle(.segmented) // .transition(.opacity) HStack { Button(action: swapOptions) { Text("Swap") } } } .padding() } } extension ContentView { func swapOptions() { withAnimation { toggle.toggle() switch toggle { case true: list = [ "Item 1", "Item 2", "Item 3", "Item 4", "Item 5", ] case false: list = [ "Item 4", "Item 5", "Item 6", "Item 7", "Item 8", ] } } } } ``
Topic: UI Frameworks SubTopic: SwiftUI
Replies
0
Boosts
0
Views
99
Activity
May ’25
NSLayoutManager returning inconsistent values for a glyph's text container and its line fragment rect
TLDR: NSLayoutManager's textContainer(forGlyphAt:effectiveRange:) and lineFragmentRect(forGlyphRange:effectiveRange:) are returning inconsistent results. Context: I'm developing a word processing app that paginates from an NSTextStorage using NSLayoutManager. My app uses a text attribute (.columnType) to paginate sub-ranges of the text at a time, ensuring that each columnRange gets a container (or series of containers across page breaks) to fit. This is to support both multi-column and standard full-page-width content. After any user edit, I update pagination data in my Paginator model class. I calcuate frames/sizes for the views/containers, along with what superview they belong to (page). The UI updates accordingly. In order to determine whether the columnRange has overflowed from a container due to a page break OR whether the range of text hasn't overflowed its container and is actually using less space than available and should be sized down, I call both: layoutManager.textContainer(forGlyphAt: lastGlyphOfColumn, effectiveRange: &actualGlyphRangeInContainer)` // and `layoutManager.lineFragmentRect(forGlyphAt: lastGlyphOfColumn, effectiveRange: nil) Apple Documentation notes that both these calls force glyph generation and layout. As I'm in early development, I have not set non-contiguous layout. So these should be causing full layout, assuring accurate return values. Or so I'd hoped. This does work fine in many cases. I edit. Pagination works. But then I'll encounter UI-breaking inconsistent returns from these two calls. By inconsistent, I mean that the second call returns a line fragment rect that is in the container coordinates of A DIFFERENT container than the container returned by the first call. To be specific, the line fragment rect seems to be in the coordinates of the container that comes next in layoutManager.textContainers. Example Code: if !layoutManager.textContainers.indices.contains(i) { containerToUse = createTextContainer(with: availableSize) layoutManager.addTextContainer(containerToUse) } else { // We have a container already but it may be // the wrong size. containerToUse = layoutManager.textContainers[i] if containerToUse.size.width != availableSize.width { // Mandatory that we resize if we don't have // a matching width. Height resizing is not // mandatory and requires a layout check below. containerToUse.size = availableSize } } let glyphRange = layoutManager.glyphRange(forCharacterRange: remainingColumnRange, actualCharacterRange: nil) let lastGlyphOfColumn = NSMaxRange(glyphRange) - 1 var containerForLastGlyphOfColumn = layoutManager.textContainer(forGlyphAt: lastGlyphOfColumn, effectiveRange: &actualGlyphRangeInContainer) if containerForLastGlyphOfColumn != containerToUse && containerToUse.size.height < availableSize.height { // If we are here, we overflowed the container, // BUT the container we overflowed didn't use // the maximum remaining page space (this // means it was a pre-existing container that // needs to be sized up and checked once more). // NOTE RE: THE BUG: // at this point, prints show... // containerToUse.size.height // =628 // availableSize.height // =648 containerToUse.size = availableSize containerForLastGlyphOfColumn = layoutManager.textContainer(forGlyphAt: lastGlyphOfColumn, effectiveRange: &actualGlyphRangeInContainer) } // We now check again, knowing that the container we // are testing flow into is the max size it can be. if containerForLastGlyphOfColumn != containerToUse { // If we are here, we have overflowed the // container, so containerToUse size SHOULD be // final/accurate, since it is fully used. actualCharRangeInContainer = layoutManager.characterRange(forGlyphRange: actualGlyphRangeInContainer, actualGlyphRange: nil) // Start of overflow range is the first character // in the container that was overflowed into. let overflowLoc = actualCharRangeInContainer.location remainingColumnRange = NSRange(location: overflowLoc, length: remainingColumnRange.length - overflowLoc) // Update page count as we have broken to a new page currentPage += 1 } else { // If we are here, we have NOT overflowed // from the container. BUT... // THE BUG: // ***** HERE IS THE BUG! ***** lineFragmentRectForLastChar = layoutManager.lineFragmentRect(forGlyphAt: lastGlyphOfColumn, effectiveRange: nil) let usedHeight = lineFragmentRectForLastChar.maxY // BUG: ^The lines of code above return a // fragment rect that is in the coordinates // of the WRONG text container. Prints show: // usedHeight // =14 // usedHeight shouldn't be just 14 if this is // the SAME container that, when it was 628 // high, resulted in text overflowing. // Therefore, the line fragment here seems // to be in the coordinates of the ENSUING // container that we overflowed INTO, but // that shouldn't be possible, since we're in // a closure for which we know: // // containerForLastGlyphOfColumn == containerToUse // // If the last glyph container is the container // we just had to size UP, why does the final // glyph line fragment rect have a maxY of 14!? // Including ensuing code below only for context. if usedHeight < containerToUse.size.height { // Adjust container size down to usedRect containerToUse.size = CGSize(width: containerToUse.size.width, height: usedHeight) } else if usedHeight == availableSize.height { // We didn't force break to a new page BUT // we've used exactly the height of our page // to layout this column range, so need to // break to a new page for any ensuing text // columns. currentPage += 1 } else if usedHeight > containerToUse.size.height { // We should have caught this earlier. Text // has overflowed, but this should've been // caught when we checked // containerForLastGlyphOfColumn != // containerToUse. // // Note: this error has never thrown. throw PaginationError.unknownError("Oops.") } } Per my comments in the code block above, I don't understand why the very same text container that just overflowed and so had to be sized up from 628 to 648 in order to try to fit a glyph would now report that same glyph as both being IN that same container and having a line fragment rect with a maxY of just 14. A glyph couldn't fit in a container when it was 628 high, but if I size it up to 648, it only needs 14? There's something very weird going on here. Working with NSLayoutManager is a bit of a nightmare given the unclear documentation. Any help or insight here would be massively, massively appreciated.
Replies
2
Boosts
0
Views
541
Activity
Apr ’25
Xcode 16.3(16E140) failing to debug run but succeeding to build.
Reproduction procedure Launch Xcode and press shift+command+N to create a macOS App project. Edit the generated ContentView.swift to the following content: struct ContentView: View { @State var txt: String = “” var body: some View { VStack { Text(“Hello, world!\(txt)”) TextField(“input”, text: $txt) onSubmit { // lack of a period letter. // .onSubmit { // Correct code print(“onSubmit\(txt)”) } } } } Build with command+B and it succeeds. Debug with command+R, but a rainbow wheel appears and the window does not show. An error is displayed in Xcode’s Preview Canvas, preventing preview.
Replies
1
Boosts
0
Views
119
Activity
May ’25
Live Activity fails to start with "unsupportedTarget" error on iOS 18 beta
Hi all, I’m developing a timer app with Live Activity support. On iOS 18.5 (iPhone 14 Pro Max), I cannot get Live Activity to start. When I call Activity.request(...) in my main app, it throws an unsupportedTarget error, and nothing appears on the Lock Screen or Dynamic Island. What I’ve done: Widget Extension Info.plist: <key>NSExtension</key> <dict> <key>NSExtensionPointIdentifier</key> <string>com.apple.widgetkit-extension</string> </dict> <key>NSSupportsLiveActivities</key> <true/> <key>NSSupportsLiveActivitiesFrequentUpdates</key> <true/> Live Activity UI: Implemented with ActivityConfiguration(for: xxx_Clock_liveactivitiesAttributes.self) and Dynamic Island support. App Group: Both main app and extension use the same App Group, and it’s enabled in Apple Developer Center and Xcode. Tested on: iPhone 14 Pro Max, iOS 18.5 (official release) Xcode [your version] (I have not tested on iOS 17.x, so I am not sure if this issue is specific to iOS 18.5.) What I’ve tried: Cleaned build folder, deleted Derived Data, uninstalled and reinstalled app. Rebooted device. Double-checked all Info.plist and entitlements settings. Tried creating a new Widget Extension from scratch. Problem: Activity.request always throws unsupportedTarget. No Live Activity appears on Lock Screen or Dynamic Island. No other errors or crashes. Questions: Has anyone encountered this issue on iOS 18.5? Are there any new requirements or changes for Live Activity in iOS 18.5? Any suggestions or workarounds to make Live Activity work? Any help or suggestions would be greatly appreciated!
Replies
2
Boosts
0
Views
209
Activity
Jun ’25
cannot save event
iOS 18.4.1 When I change a Google type event to an iCloud type, a "Cannot Save Event" prompt box pops up. We have also received user feedback that recurring events also fail to save. After updating to iOS 18.4 when trying to save changes to an existing repeating event, the message "Cannot Save Event" will appear. EventKitUI
Topic: UI Frameworks SubTopic: UIKit
Replies
0
Boosts
0
Views
68
Activity
May ’25
Dynamic island not displaying UI views
i finally got previews for dynamic island to work and I'm just trying to first work on adding a static UI elements to my dynamic island like i did for my live screen live activity, but my dynamic island view is showing up totally empty, if i add my app icon image to the compact leading closure, it doesn't appear, if i ad text to an expanded region closure it doesn't appear. am really stuck on this and would approeciate the help. var body: some View { Image("dynamicrep") .resizable() .scaledToFit() .clipShape(.circle) } } struct DynamicRepLiveActivity: Widget { var body: some WidgetConfiguration { ActivityConfiguration(for: DynamicRepAttributes.self) { context in VStack { HStack(spacing: 257) { Text("from \(context.attributes.titleName ?? "no title")") .fontWeight(.light) .font(.system(size: 16)) .foregroundStyle(Color.gray) Circle() .frame(width: 53, height: 50) .foregroundStyle(Color.gray).opacity(0.23) .overlay { Image("mmicon") } } .frame(maxWidth: 500, maxHeight: 210) Spacer() Text("\(context.attributes.contentBody ?? "no content")") } .activityBackgroundTint(Color.cyan) .activitySystemActionForegroundColor(Color.black) .frame(width: 500, height: 300) } dynamicIsland: { context in DynamicIsland { // Expanded UI goes here. Compose the expanded UI through // various regions, like leading/trailing/center/bottom DynamicIslandExpandedRegion(.leading) { Text("from \(context.attributes.titleName ?? "no title")") } DynamicIslandExpandedRegion(.trailing) { Circle() } DynamicIslandExpandedRegion(.bottom) { Text("\(context.attributes.contentBody ?? "no content")") } } compactLeading: { AppLogo() } compactTrailing: { Text("") //empty for now } minimal: { Text("hello") //empty for now } .widgetURL(URL(string: "MuscleMemory.KimchiLabs.com")) .keylineTint(Color.white) } } }
Replies
1
Boosts
0
Views
149
Activity
Apr ’25
Lists, Generics, Views, Navigation Link, SwiftData - ForEach can't pass a binding anymore.
I'm trying out putting most of my business logic in a Protocol that my @Model can conform to, but I'm running into a SwiftUI problem with a Binding that does not get magically offered up like it does when it the subview is not generic. I have a pretty basic List with a ForEach that now can't properly pass to a generic view based on a protocol. When I try to make a binding manually in the row it says that "item is immutable"... but that also doesn't help me with the NavigationLink? Which is seeing the Binding not the ? But before when the subview was concrete to Thing, it took in the and made its own Binding once it hit the view. I'm unclear on precisely where the change happens and what I can do to work around it. Before I go rearchitecting everything... is there a fix to get the NavigationLink to take on the object like before? What needs to be different? I've tried a number of crazy inits on the subview and they all seem to come back to saying either it can't figure out how to pass the type or I'm trying to use the value before it's been initialized. Have I characterized the problem correctly? Thanks! (let me know if I forgot a piece of code, but this should be the List, the Model/Protocol and the subview) import SwiftUI import SwiftData struct ThingsView: View {     @Environment(\.modelContext) var modelContext     @Query var items: [Thing]          var body: some View {         NavigationStack {             List {                 ForEach(items) { item in                     NavigationLink(value: item) {                         VStack(alignment: .leading) {                             Text(item.textInfo)                                 .font(.headline)                                                          Text(item.timestamp.formatted(date: .long, time: .shortened))                         }                     }                 }.onDelete(perform: deleteItems)             }             .navigationTitle("Fliiiing!") //PROBLEM HERE: Cannot convert value of type '(Binding<Thing>) -> EditThingableView<Thing>' to expected argument type '(Thing) -> EditThingableView<Thing>'             .navigationDestination(for: Thing.self, destination: EditThingableView<Thing>.init) #if os(macOS)             .navigationSplitViewColumnWidth(min: 180, ideal: 200) #endif             .toolbar { #if os(iOS)                 ToolbarItem(placement: .navigationBarTrailing) {                     EditButton()                                      } #endif                 ToolbarItem {                     Button(action: addItem) {                         Label("Add Item", systemImage: "plus")                     }                 }                 ToolbarItem {                     Button("Add Samples", action: addSamples)                 }             }         }     }          func addSamples() {         withAnimation {             ItemSDMC.addSamples(context: modelContext)         }     }          private func addItem() {         withAnimation {             let newItem = ItemSDMC("I did a thing!")             modelContext.insert(newItem)         }     }          func deleteItems(_ indexSet:IndexSet) {         withAnimation {             for index in indexSet {                 items[index].delete(from: modelContext)             }         }     } } #Preview {     ThingsView().modelContainer(for: ItemSDMC.self, inMemory: true) } import Foundation import SwiftData protocol Thingable:Identifiable {     var textInfo:String { get set }     var timestamp:Date { get set } } extension Thingable {     var thingDisplay:String {         "\(textInfo) with \(id) at \(timestamp.formatted(date: .long, time: .shortened))"     } } extension Thingable where Self:PersistentModel {     var thingDisplayWithID:String {         "\(textInfo) with modelID \(self.persistentModelID.id) in \(String(describing: self.persistentModelID.storeIdentifier)) at \(timestamp.formatted(date: .long, time: .shortened))"     } } struct ThingLite:Thingable, Codable, Sendable {     var textInfo: String     var timestamp: Date     var id: Int } @Model final class Thing:Thingable {     //using this default value requires writng some clean up logic looking for empty text info.     var textInfo:String = ""     //using this default value would require writing some data clean up functions looking for out of bound dates.     var timestamp:Date = Date.distantPast          init(textInfo: String, timestamp: Date) {         self.textInfo = textInfo         self.timestamp = timestamp     } } extension Thing {     var LiteThing:ThingLite {         ThingLite(textInfo: textInfo, timestamp: timestamp, id: persistentModelID.hashValue)     } } import SwiftUI struct EditThingableView<DisplayItemType:Thingable>: View {     @Binding var thingHolder: DisplayItemType          var body: some View {                  VStack {             Text(thingHolder.thingDisplay)             Form {                 TextField("text", text:$thingHolder.textInfo)                 DatePicker("Date", selection: $thingHolder.timestamp)             }                      } #if os(iOS)         .navigationTitle("Edit Item")         .navigationBarTitleDisplayMode(.inline) #endif     } } //NOTE: First sign of trouble //#Preview { //    @Previewable var myItem = Thing(textInfo: "Example Item for Preview", timestamp:Date()) //    EditThingableView<Thing>(thingHolder: myItem) //}
Replies
4
Boosts
0
Views
206
Activity
May ’25
PKPass Framework
I am trying to work with the data inside the barcode string in shared PKPass. The documentation shows that is should look for @property (nonatomic, readonly, nullable) PKBarcode *primaryBarcode; I have tried to use it like this guard let code = pass.primaryBarcode?.message else { return } I get a constant message that PKPass has no member primaryBarcode The PKPass.h file in my IOS SDK does not seem to include the @property primaryBarcode or @property barcode. I am running Xcode 16.4 (16F6) and my app target is 17.6 + Is there a restriction on this property? I cannot find an SDK later than mine - the App Store does not offer one. I am unsure of this is a public or private issue - does anyone know? Thanks for reading this. Max
Topic: UI Frameworks SubTopic: SwiftUI
Replies
0
Boosts
0
Views
100
Activity
Jun ’25
Severe hangs with LazyHStack inside ScrollView
Hi, I got a problem with severe hangs when I use code like this on tvOS 18.2 If I try to use HStack instead of LazyHStack inside the scrollview then the problem does not occur any more but then the scroll performance is compromised and the vertical scroll is no longer that smooth. Does someone has any experience with this? Is this SwiftUI problem or am I missing something? ScrollView { LazyVStack { ForEach(0...100, id: \.self) { _ in ScrollView { LazyHStack { ForEach(0...20, id: \.self) { _ in Color.red.frame(height: 300) } } } } } }
Replies
2
Boosts
0
Views
186
Activity
Apr ’25
.onTapGesture does not work when SwiftUI component sits in a flipped NSVIew
Take a look at this simple code: import Cocoa import SwiftUI struct DemoView: View { var body: some View { Text("Click me!") .onTapGesture { print("Clicked") } } } class FlippedView: NSView { override var isFlipped: Bool { return true } } class ViewController: NSViewController { override func viewDidLoad() { super.viewDidLoad() let stackView = NSStackView() stackView.orientation = .vertical stackView.alignment = .leading stackView.spacing = 0 stackView.translatesAutoresizingMaskIntoConstraints = false let hostView = NSHostingView(rootView: DemoView()) stackView.addArrangedSubview(hostView) let scrollView = NSScrollView() scrollView.translatesAutoresizingMaskIntoConstraints = false let flippedView = FlippedView() flippedView.addSubview(stackView) scrollView.documentView = flippedView view.addSubview(scrollView) NSLayoutConstraint.activate([ scrollView.topAnchor.constraint(equalTo: view.topAnchor), scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor), scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor), scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor), ]) } } I need my scroll view to start at the very top, so i put it inside a flipped document view. But now .onTapGesture does not fire.
Replies
1
Boosts
0
Views
168
Activity
Apr ’25
UIScrollView in UIViewControllerRepresentable - UI freezes when content touches bottom SafeArea
The SwiftUI ScrollView lacks some features I need and so I created a custom MyScrollView based on UIScrollView wrapped within a UIViewControllerRepresentable. While this works fine in general I know came across a very strange problem: When MyScrollView is used in a sheet and its content touches bottom SafeArea, the UI freezes as soon as the should be displayed. The code below shows the problem as well in preview as on the simulator and on devices. Please note that the code is tuned do the display size of an iPhone 16 Pro. When running on different devices one might need to adjust height of the Color.yellow. In the demo code the UI freezes if the Color.yellow has a height between 738 to 771 pixels. Every other height is fine. Is there something wrong with my implementation of MyScrollView? When using ScrollView instead, everything works fine. Code: struct ContentView: View { @State private var showSheet: Bool = false var body: some View { ZStack { Button("Show Sheet") { showSheet = true } } .sheet(isPresented: $showSheet) { VStack { Text("Some Header Content") MyScrollView { VStack { Color.yellow //.frame(height: 737) // works .frame(height: 738) // does NOT works // ... //.frame(height: 771) // does NOT works //.frame(height: 772) // works } } .ignoresSafeArea() } } } } struct MyScrollView<Content: View>: UIViewControllerRepresentable { let content: Content init(@ViewBuilder content: () -> Content) { self.content = content() } func makeUIViewController(context: Context) -> UIViewController { let scrollViewVC = UIViewController() scrollViewVC.view.backgroundColor = .clear let scrollView = UIScrollView() scrollView.backgroundColor = .clear let contentVC = UIHostingController(rootView: self.content) contentVC.view.backgroundColor = .clear context.coordinator.contentVC = contentVC context.coordinator.scrollView = scrollView scrollView.translatesAutoresizingMaskIntoConstraints = false scrollViewVC.view.addSubview(scrollView) NSLayoutConstraint.activate([ scrollView.topAnchor.constraint(equalTo: scrollViewVC.view.topAnchor), scrollView.bottomAnchor.constraint(equalTo: scrollViewVC.view.bottomAnchor), scrollView.leadingAnchor.constraint(equalTo: scrollViewVC.view.leadingAnchor), scrollView.trailingAnchor.constraint(equalTo: scrollViewVC.view.trailingAnchor) ]) contentVC.willMove(toParent: scrollViewVC) scrollViewVC.addChild(contentVC) contentVC.view.translatesAutoresizingMaskIntoConstraints = false scrollView.addSubview(contentVC.view) NSLayoutConstraint.activate([ contentVC.view.topAnchor.constraint(equalTo: scrollView.contentLayoutGuide.topAnchor), contentVC.view.bottomAnchor.constraint(equalTo: scrollView.contentLayoutGuide.bottomAnchor), contentVC.view.leadingAnchor.constraint(equalTo: scrollView.contentLayoutGuide.leadingAnchor), contentVC.view.trailingAnchor.constraint(equalTo: scrollView.contentLayoutGuide.trailingAnchor), contentVC.view.widthAnchor.constraint(equalTo: scrollView.frameLayoutGuide.widthAnchor) ]) contentVC.didMove(toParent: scrollViewVC) return scrollViewVC } func updateUIViewController(_ uiViewController: UIViewController, context: Context) { context.coordinator.contentVC?.rootView = content } func makeCoordinator() -> Coordinator { return Coordinator() } class Coordinator { var contentVC: UIHostingController<Content>? var scrollView: UIScrollView? init() { //... } } } #Preview { ContentView() }
Topic: UI Frameworks SubTopic: SwiftUI
Replies
2
Boosts
0
Views
116
Activity
Apr ’25
visionOS 26.0 beta does not call .onTapGesture
Prior to visionOS 2.5, .onTapGesture was called with the following structure, but in visionOS 26.0 beta, it is no longer called. Is .onTapGesture deprecated in visionOS 26.0 and above? Or is it a bug? TabView(selection: $selectedTab) { WebViewView(selectedTab: $selectedTab) .onTapGesture { viewModel.userDidInteract = true } }
Replies
2
Boosts
0
Views
104
Activity
Jun ’25
Access DocumentGroup container by external WindowGroup
Hi, I am currently developing a document-based application for macOS and have encountered a challenge related to document container management. Specifically, I need to open a windowGroup that shares the same container as the one used in the DocumentGroup. However, my current approach of using a global shared model container has led to unintended behavior: any new document created is linked to existing ones, and changes made in one document are reflected across all documents. To address this issue, I am looking for a solution that allows each newly created document to be individualized while still sharing the document container with all relevant WindowGroups that require access to the data it holds. I would greatly appreciate any insights or recommendations you might have on how to achieve this. Thank you for your time and assistance. Best regards, Something like: @main struct Todo: App { var body: some Scene { DocumentGroup(editing: Item.self, contentType: .item) { ContentView() } WindowGroup { UndockView() .modelContainer(of documentGroup above) } } }
Replies
0
Boosts
0
Views
90
Activity
Apr ’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
254
Activity
Jun ’25
Apple Pay
I'm implementing Apple Pay in a Flutter iOS app using the pay plugin and Braintree as the payment processor. I have followed all necessary steps as outlined by Apple and community resources (e.g., Medium articles, official Apple Developer documentation), but the Apple Pay button does not appear on a real device. Here's what I've completed: Created an Apple Pay Merchant ID Created and downloaded the Apple Pay Payment Processing Certificate, then uploaded it to Braintree Downloaded the Braintree-signed certificate and confirmed it's active in the Apple Developer portal Added the Merchant ID under Signing & Capabilities in Xcode Enabled Apple Pay capability in Xcode Added the Merchant ID to Info.plist Installed required Flutter packages (e.g., pay) Using a valid Apple Pay payment configuration file in Flutter (see below) Tested on a real iOS device with a valid Apple Pay test card added to Wallet Flutter Payment Configuration (in Dart JSON): json Copy Edit { "provider": "apple_pay", "data": { "merchantIdentifier": "merchant.com.example", "displayName": "My Store", "merchantCapabilities": ["3DS", "debit", "credit"], "supportedNetworks": ["visa", "masterCard", "amex"], "countryCode": "US", "currencyCode": "USD" } } Despite this complete setup, the ApplePayButton widget remains invisible There are no errors in the console. Can you help identify what may be missing or misconfigured at the code or configuration level?
Replies
2
Boosts
0
Views
205
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
97
Activity
Jun ’25
ObservableObjects get retained after a TextField is focused
When presenting a SwiftUI sheet containing ObservableObject's injected using environmentObject(_) modifier, the objects are unexpectedly retained after the sheet is dismissed if a TextField within the sheet gains focus or is edited. This issue occurs on iOS and iPadOS (on macOS the objects are always released), observable both in the simulator and on physical devices, and happens even when the view does not explicitly reference these environment objects, and the TextField's content isn't bound to them. Expected Results: When the sheet is dismissed, all environment objects passed to the sheet’s content view should be released (deinitialized), regardless of whether the TextField was focused or edited. Actual Results: If the TextField was focused or edited, environment objects (ObservableA and ObservableB) are retained after the sheet is dismissed. They are not deinitialized as expected, leading to unintended retention. Interestingly, previously retained copies of these environment objects, if any, are released precisely at the moment the TextField becomes focused on subsequent presentations, indicating an inconsistent lifecycle behavior. I have filed an issue FB17226970 Sample Code Below is a sample code that consistently shows the issue on iOS 18.3+. Steps to Reproduce: Run the attached SwiftUI sample. Tap the button labeled “Show Sheet” to present a sheet. Tap on the TextField to focus or begin editing. Dismiss the sheet by dragging it down or by other dismissal methods (e.g., tapping outside on iPadOS). import SwiftUI struct ContentView: View { @State private var showSheet: Bool = false var body: some View { VStack { Button("Show Sheet") { showSheet = true } } .sheet(isPresented: $showSheet) { SheetContentView() .environmentObject(ObservableA()) .environmentObject(ObservableB()) } } } struct SheetContentView: View { @State private var text: String = "" var body: some View { TextField("Select to retain observable objects", text: $text) .textFieldStyle(.roundedBorder) } } final class ObservableA: ObservableObject { init() { print(type(of: self), #function) } deinit { print(type(of: self), #function) } } final class ObservableB: ObservableObject { init() { print(type(of: self), #function) } deinit { print(type(of: self), #function) } } #Preview { ContentView() }
Replies
2
Boosts
0
Views
201
Activity
Apr ’25
Live activity widget not updated locally after server update
I am using live activity in my app. Functionality is start, update & end events are started from the server. There is one interaction button added using app intent in live activity widget. That button needs to update widget ui locally using activity kit. Issue is when os receives first start event push then update ui works fine and reflecting on live activity widget but when update notification receives by os after 1 mins then action button stops updating the ui locally. Can anyone please add some suggestions to fix this.
Replies
0
Boosts
0
Views
139
Activity
May ’25
List Layout Breaks in NavigationStack When a View Exceeds Screen Width
This is a bug report. FB17433985 The layout of the following ContentView appears correctly when it is outside a NavigationStack. However, when the same view is placed inside a NavigationStack, the layout breaks. It seems that the width of the List is being affected by the width of the buttonsView, which exceeds the screen width. In my testing, this issue occurs on iOS 18.4 and later, but does not occur on iOS 18.2 or iOS 17.5. Workaround I found: Remove the fixed width modifier from the Button If anyone knows of other ways to resolve this issue without affecting the layout, I would appreciate it if you could share them. import SwiftUI let values = (1...100).map { $0 } let buttonTitles = (1...9).map { "Button\($0)" } struct ContentView: View { var body: some View { VStack { List { Section { ForEach(values.indices, id: \.self) { val in HStack { Text("Index: \(val)") } } } } buttonsView } } private var buttonsView: some View { HStack { ForEach(0..<buttonTitles.count, id: \.self) { index in Button() { } label: { Image(systemName: "square.and.arrow.up") .resizable() .frame(width: 48, height: 48) } } } } } @main struct ButtonShapeBugApp: App { var body: some Scene { WindowGroup { if true { NavigationStack { ContentView() } } else { ContentView() } } } } Environment: Xcode Version 16.3 (16E140) iPhone 18.4.1 real device iPhone SE3rd 18.4 simulator Expect layout Broken layout(9 buttons) Broken layout(10 buttons)
Replies
2
Boosts
0
Views
95
Activity
May ’25
Understanding how to make focusedImage work on CPMapButton
When my CPMapButton is selected/focused, I would like to be able to provide a focusedImage to correctly show the button when the blue focus is shown. Currently I have: What do I need to do to create an image that works more like the panning interface buttons?
Topic: UI Frameworks SubTopic: UIKit Tags:
Replies
0
Boosts
0
Views
176
Activity
Jun ’25