Provide views, controls, and layout structures for declaring your app's user interface using SwiftUI.

SwiftUI Documentation

Posts under SwiftUI subtopic

Post

Replies

Boosts

Views

Activity

Bug Report: Xcode 26.6 Codex Agent Fails with Response Decoding and Model Compatibility Errors
Bug Report: Xcode 26.6 Codex Agent Fails with Response Decoding and Model Compatibility Errors Severity: High — Core agent functionality unavailableComponent: Xcode Intelligence / Codex Agent IntegrationEnvironment: macOS, Xcode 26.6 (17F113)Date reported: November 1, 2026 Summary The built-in Codex coding agent in Xcode consistently fails to process requests, despite successful ChatGPT Pro authentication and a functioning standalone Codex CLI. The problem occurs even with trivial prompts and prevents use of Codex's autonomous development functionality, including the Pursue Goal workflow. The standard ChatGPT integration inside Xcode works correctly. The failure is isolated to the Codex agent integration. Environment ComponentDetailsIDEXcode 26.6 (17F113)Built-in Codex agent0.140.0 (version observed before reinstall)Standalone Codex CLI0.166.0ACP adapter testedcodex-acp 2.5.0AccountChatGPT ProAuthenticationChatGPT account authenticationAffected projectsMultiple SwiftUI projectsModel testedgpt-5.5, gpt-6.1-solActual Behavior When initiating a conversation with the built-in Codex agent in Xcode, the request fails with the following messages: Error 1: Response decoding failure The data couldn’t be read because it isn’t in the correct format.Accompanied by: Your request couldn't be completed.Error 2: Unsupported model With the original model selection: Codex encountered an error: The 'gpt-5.5' model is not supported when using Codex with a ChatGPT account.After explicitly configuring gpt-6.1-sol: Codex encountered an error: The 'gpt-6.1-sol' model is not supported when using Codex with a ChatGPT account.Error 3: ACP communication failure When testing a separately registered Codex ACP adapter: JSON-RPC request with ID [...] failed to produce a response.This was observed in a separate integration experiment and should not automatically be assumed to share the same root cause as the built-in Codex failure. Expected Behavior The built-in Codex agent should: Authenticate with an eligible ChatGPT Pro account. Select a model supported by the account and installed agent version. Correctly initialize the agent and decode its protocol responses. Execute basic prompts without errors. Support Xcode's native agentic development workflows, including Pursue Goal. Present actionable diagnostics when authentication, model selection, or protocol initialization fails. Reproduction Steps Open Xcode 26.6. Open an existing SwiftUI project. Open the Coding Assistant. Start a new conversation. Select Codex under Agents, rather than OpenAI under Chat. Submit a trivial prompt, such as: Reply with exactly OK. Observe the request failing with a response-format error or an unsupported-model error, depending on configuration. The issue is reproducible across multiple attempts and is not specific to a complex coding task. Troubleshooting Performed The following troubleshooting actions have already been attempted: Reauthenticated using the ChatGPT account. Tested configuration-file-based authentication. Reset Codex authentication. Reinstalled Xcode. Reinstalled the Xcode Codex component. Restarted Xcode and created new conversations. Tested explicit model selection through config.toml. Tested standalone Codex with the same ChatGPT Pro account. Tested a separate ACP adapter integration. The built-in Codex agent remains unusable. Confirmed Successful Control Test Standalone Codex CLI 0.166.0 successfully executed a request using GPT-6.1 Sol. Command: codex exec --model gpt-6.1-sol --skip-git-repo-check \ "Reply with exactly OK. Do not edit files or use tools."Observed output: OpenAI Codex v0.166.0 model: gpt-6.1-sol provider: openai reasoning effort: high codex OKThe request completed without an API error. Additionally, Xcode's separate ChatGPT integration displays the ChatGPT Pro account as authenticated, with usage status Under Limit. These observations strongly suggest that the problem is specific to the Xcode Codex integration or its runtime environment, rather than a general account authentication failure. Suspected Root Causes The following are hypotheses requiring investigation, not confirmed causes: 1. Bundled agent version incompatibility Xcode was observed using Codex 0.140.0, while standalone Codex 0.166.0 successfully accessed GPT-6.1 Sol. Please verify whether the bundled Codex agent is compatible with currently available ChatGPT-authenticated models. 2. Model discovery or selection mismatch The bundled agent's model catalog included models that were subsequently rejected by the service. Please investigate whether Xcode refreshes the model catalog, respects model configuration overrides, and selects models based on account eligibility. 3. Agent protocol response decoding The generic data-format error suggests a possible failure to decode an agent response, handle an unsupported response schema, or propagate an underlying API error. Please inspect the agent initialization, response parsing, and error-handling paths. 4. Configuration and authentication isolation The normal ChatGPT integration authenticates successfully, while the Codex agent fails. Please verify how Xcode manages distinct authentication contexts, configuration locations, agent versions, and model capabilities. Requested Engineering Actions Please investigate and address the following: Ensure the Xcode Codex agent is compatible with supported ChatGPT-authenticated models. Verify that the bundled agent version is current and that component updates are correctly delivered. Validate model availability before dispatching requests. Ensure the model selected in Xcode matches the actual model submitted by the agent. Correct any incompatible protocol or JSON response handling. Expose the underlying error details rather than only reporting a generic data-format failure. Confirm that reinstalling or updating the Xcode Codex component restores a functional agent without requiring manual configuration changes. Add regression coverage for ChatGPT Pro authentication, model selection, agent initialization, and basic prompt execution. Impact The issue prevents me from using the Codex agent directly inside Xcode, despite having a ChatGPT Pro subscription and a fully functional standalone Codex CLI. As a result, I cannot use the integrated agentic coding experience or the Pursue Goal workflow that previously worked. Please investigate the bundled Codex runtime, model selection, and protocol compatibility. The successful standalone Codex 0.166.0 test provides a control case for reproducing and isolating the failure.
1
1
323
2h
Tab grayed out, but not disabled
Bug report: FB25495244 This bug also appeared with Xcode 27; it worked previously. scenario: A TabView with, for example, 4 tabs. Data in ContentView is loaded via @Query. In ContentBindingView, the same thing is done, but using a parameter instead of SwiftData. ContentView: If no data is available, the system automatically switches to tab 4 at the start; while you can click on other tabs, they are disabled, and the system will not switch to them. ContentBindingView: When tabDisabled is set to "true", the system automatically switches to Tab 4 upon startup; while it is possible to click on other tabs, they are disabled, and the system will not switch to them. So far, so good. The first three tabs are only active if at least one data record exists or tabDisabled is "false". Tab 4 is always active and is used for data entry. When data is entered in Tab 4, tab 1 to 3 should become active. However, it appears as though tabs 1 through 3 remain disabled—the icons appear grayed out. That is actually not the case; you can click on the tabs, and as soon as you move away from a tab, its icon is displayed correctly. This issue did not exist in Xcode 26. In Xcode 26, all symbols were displayed correctly from the start, once data had been saved. What I noticed on the iPhone Duo: If you open the program on an iPhone Duo while it is closed, enter some data, then move the app to the background, open the iPhone Duo, and bring the application back to the foreground, tabs 1 through 3 will be active. The entire view is being updated, which is why tabs 1 through 3 are now active—though they should have been active already. A side note: The same issue described in the forum post "A layout bug when using Tab View in SwiftUI (FB25490881)" also occurs in this program. The entire view has shifted upward. The text field is no longer visible—only the Add button remains. In the other views, you can only see half of the text. import SwiftUI struct ContentBindingView: View { @State private var tabDisabled: Bool = true @State private var selection: TabSelection = .tab1 private var isTabDisabled: Bool { print("ContentView.isTabDisabled: \(tabDisabled)") return tabDisabled } var body: some View { TabView(selection: $selection) { Tab("Tab 1", systemImage: "waveform.badge.magnifyingglass", value: .tab1) { Text("tab 1") } .disabled(isTabDisabled) Tab("Tab 2", systemImage: "heart", value: .tab2) { Text("tab 2") } .disabled(tabDisabled) Tab("Tab 3", systemImage: "target", value: .tab3) { Text("tab 3") } .disabled(tabDisabled) Tab("Tab 4", systemImage: "gear", value: .tab4) { AddFriendBindingView(tabDisabled: $tabDisabled) } } .onAppear { print("ContentView onAppear disabled: \(tabDisabled)") if tabDisabled { selection = .tab4 } } .onChange(of: selection) { print("ContentView onChange disabled: \(tabDisabled)") } } }struct AddFriendBindingView: View { @Environment(\.dismiss) private var disdmiss @Binding var tabDisabled: Bool @State private var name: String = "" var body: some View { VStack { TextField("Name", text: $name) Button { addFriend() } label: { Text("Add") } .buttonStyle(.borderedProminent) } .padding() .onAppear { print("AddFriendView onAppear disabled: \(tabDisabled)") } } private func addFriend() { tabDisabled = false name = "" disdmiss() } }Christian
1
0
248
12h
A layout bug when using Tab View in SwiftUI
I've been getting some unexpected behavior when using TabView as the root view in SwiftUI, which I believe to be a bug. I created a barebones app to isolate the bug and will paste the code at the end for anyone who wants to try to reproduce it if you have a physical Duo device. Details below copied from my Feedback ticket FB25490881. Xcode 27.1. What's the bug? When you have a TabView as the root view inside the ContentView.swift and you open the app on the outer screen, then swipe it to the background, unfold the phone and tap the app to bring it to the foreground, any UI element without a fixed frame size gets moved off screen. And any UI element with a fixed frame size gets moved to the very top of the screen. See my two screenshots of outer vs inner display. How to reproduce: 1- Unzip the project folder and open it in Xcode. 2- With a physical Duo on hand, run the app on the Duo. 3- On the outer screen, launch the app. 4- Swipe the app to the background (Do not swipe completely to close the app, just swipe it to the background so it is still running) 5- Unfold the iPhone Duo completely open. 6- Tap the app icon to bring it to the foreground. 7- Look at the broken UI. Also note even the side tab bar itself is broken, it has no padding with the edge of the screen. This is managed by the system. The workaround to fix it: 1- Go to the ContentView.Swift in Xcode. 2- Uncomment "NavigationStack {" on line 13. 3- Uncomment the closing bracket "}" on line 2. 4- Repeat the previous from how to reproduce the bug. My hypothesis: The system reports 0 height for the inner screen in that moment you bring the app to the foreground. Anything with a fixed frame will move to the top, anything with flexible height will not be visible. This only happens when TabView is the root of the scene. Other Useful Information: I hit a very similar bug to this in my main app that I'm still developing, unfortunately I was not able to reproduce it in a sandbox simple app. The bug was: 1- Open the app on outer screen 2- While the app is open, tilt the Duo to the back at a certain angle 3- Unfold the Duo 4- You get this exact same bug where everything with a flexible height disappears off screen or collapses to zero if it's in between UI elements with fixed heights. And everything moves to the top of the screen. I'm not sure why I wasn't able to reproduce it on a sandbox app, but the fix was the same, either remove the TabView completely or put it inside a NavigationStack. I want to stress that this one had to do with the backwards tilt of the phone itself while unfolding it, very weird I know. ContentView.swift: import SwiftUI @available(iOS 27.1, *) struct ContentView: View { var body: some View { // NavigationStack { TabView { HomeTabView() .tabItem { Label("Home", systemImage: "house") } StoreView() .tabItem { Label("Store", systemImage: "bag") } } .tint(Color.black) // } } } HomeTabView.swift: import SwiftUI @available(iOS 27.1, *) struct HomeTabView: View { var body: some View { VStack { Text("Jenny") .font(.largeTitle) .fontWeight(.bold) .padding() .frame(maxWidth: .infinity) .frame(height: 200) .background(Color.gray, in: .rect(cornerRadius: 28)) Spacer() Circle() .fill(Color.blue) .frame(width: 100, height: 100) .padding(.bottom, 50) } .contentMargins(for: .container, edges: .horizontal) } } StoreView.swift is just an default empty swiftUI file with the default Text("Hello, World!")
2
0
360
17h
TabView(.page) extended under the tab bar shifts its pages up after the container height shrinks while visible
Summary A page-style TabView that extends under the bottom tab bar with .ignoresSafeArea(edges: .bottom) leaves its pages shifted upward after its height shrinks while it is on screen. The shift is half of the bottom safe area (41.67 pt with an 83.33 pt tab bar area), and the top of each page is hidden. The internal UICollectionView (contentInsetAdjustmentBehavior == .automatic) seems to briefly add the bottom safe area to adjustedContentInset.bottom during the resize. The inset goes back to 0 afterwards, but the visible cell is left at frame.minY == -41.67. Environment Xcode 27.0 (27A266a), iPhone Duo Simulator (iOS 27.1), deployment target iOS 18.0 In a unit test it also reproduces when only the window height shrinks (386×678 → 386×600), so it does not depend on the foldable device Steps to reproduce Run the code below on the iPhone Duo Simulator while it is folded Unfold the device Expected The red "Top of page 0" area stays directly below the yellow header, as it does when the app is launched unfolded. Actual The top of the red area is hidden under the header. Log output: folded (launch): height=628.00 adjustedContentInset.bottom=0.00 cell.minY=0.00 after unfolding: height=619.00 adjustedContentInset.bottom=0.00 cell.minY=-41.67In this sample the page returns to its position when the device is folded again. In our app it stays shifted, and after the shift, tapping to switch pages sometimes stops working until the user swipes. Notes Removing .ignoresSafeArea(edges: .bottom) avoids the issue, but the content then no longer extends under the translucent tab bar Setting edgesForExtendedLayout = [] on the hosting controller also avoids it, with the same visual change. safeAreaRegions = [] and setContentScrollView(nil, for:) do not help A non-transparent background on the TabView or its pages, as suggested in https://developer.apple.com/forums/thread/762286, does not help. The trigger here is a size change, not a page switch, so this seems to be a different issue Current workaround: find the internal UICollectionView through the superview chain and set contentInsetAdjustmentBehavior = .never. This works, but it relies on the private view hierarchy. Is there a supported way to avoid this? Minimal reproduction import SwiftUI import UIKit // A TabView(.page) extended under the tab bar with .ignoresSafeArea(edges: .bottom). // Resizing the window while it is visible (e.g. unfolding) shifts the page up. struct PagerView: View { @State private var selection = 0 var body: some View { VStack(spacing: 0) { Color.yellow.frame(height: 50).overlay(Text("Header")) TabView(selection: $selection) { ForEach(0..<2) { index in ScrollView { Color.red.frame(height: 120).overlay(Text("Top of page \(index)")) ForEach(0..<30) { Text("Row \($0)").frame(maxWidth: .infinity, minHeight: 44) } } .tag(index) } } .tabViewStyle(.page(indexDisplayMode: .never)) } .ignoresSafeArea(edges: .bottom) } } final class PagerViewController: UIHostingController<PagerView> { override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { [weak self] in self?.logCollectionView() } } private func logCollectionView() { func find(_ view: UIView) -> UICollectionView? { view as? UICollectionView ?? view.subviews.lazy.compactMap(find).first } guard let collectionView = find(view) else { return } let cellMinY = collectionView.visibleCells.first?.frame.minY ?? .nan NSLog("FORUM height=%.2f adjustedContentInset.bottom=%.2f cell.minY=%.2f", collectionView.bounds.height, collectionView.adjustedContentInset.bottom, cellMinY) } } @main final class AppDelegate: UIResponder, UIApplicationDelegate { func application(_ application: UIApplication, configurationForConnecting session: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { let configuration = UISceneConfiguration(name: nil, sessionRole: session.role) configuration.delegateClass = SceneDelegate.self return configuration } } final class SceneDelegate: UIResponder, UIWindowSceneDelegate { var window: UIWindow? func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { let pager = PagerViewController(rootView: PagerView()) pager.tabBarItem = UITabBarItem(title: "Pager", image: UIImage(systemName: "square"), tag: 0) let other = UIViewController() other.tabBarItem = UITabBarItem(title: "Other", image: UIImage(systemName: "circle"), tag: 1) let tabBarController = UITabBarController() tabBarController.viewControllers = [pager, other] window = UIWindow(windowScene: scene as! UIWindowScene) window?.rootViewController = tabBarController window?.makeKeyAndVisible() } }
3
2
360
17h
iPhone: Inspector Sheet Issue with Navigation Toolbar Toggle
Hello, I think this might be a bug, but I'm not sure (see the code below). FB25486625 On iPhone, when the inspector is presented as a SHEET, swiping down to dismiss it (instead of tapping the close button inside the inspector) causes the navigation toolbar toggle to stop working properly: tapping it once won't reopen the inspector. You have to tap it twice (turning it on and off again) to make the inspector appear again. This doesn't happen when the inspector is presented as a SIDEBAR on iPad or macOS. import SwiftUI struct ContentView: View { @State private var showInspector = false var body: some View { NavigationStack{ Text("Hello, world!") .padding() .inspector(isPresented: $showInspector) { Button("Close Inspector", role: .cancel) { showInspector.toggle() } Text("On iPhone, with inspector as SHEET, if you swipe to close (instead of tap the close button), the toggle in the navigation toolbar won't open the inspector next time (half the time). It doesn't affect inspector as SIDEBAR on iPad") .padding() Spacer() } .toolbar { Toggle(isOn: $showInspector) { Label("Open", systemImage: "sidebar.trailing") } } } } } #Preview { ContentView() }
0
0
49
1d
iOS 27 regression - minimized search item in top toolbar breaks its state
struct ContentView: View { @State var searchText: String = "" var body: some View { TabView { Tab { NavigationStack { List { Text("Hello!") Text("Hello!") Text("Hello!") Text("Hello!") Text("Hello!") Text("Hello!") } .navigationTitle("Have a title") .searchable(text: $searchText, placement: .toolbar) .searchToolbarBehavior(.minimize) .toolbar { DefaultToolbarItem(kind: .search, placement: .topBarTrailing) } } } } } } In iOS 26, this worked no problem. In iOS 27, this leaves the search bar either unable to collapse (when pressing the close button) or in a broken state where it cannot be opened again.
Topic: UI Frameworks SubTopic: SwiftUI
10
12
1.8k
3d
Charts are broken with Xcode 27, Plotting multiple lines
Hi, Charts—specifically those with multiple lines—are broken in Xcode 27. First, I spotted the bug in my program, and then I checked your example. Your own example Plotting-multiple-lines is not working correctly anymore. It shows 1 line or sometimes no lines at all, depending on the order of the data. It depends on how the data is passed to the chart. If the data is passed as separate series, it works. In Visualizing your app’s data it works, but the data is passed as described before. Don't follow Microslop: have the AI ​​generate the code and then skip the tests. This is a serious bug that requires a lot of work to rearrange the data, just to work around the issue. Christian
9
0
1.8k
3d
CarPlay Video entitlement causes blank screen and no CPTemplateApplicationScene callbacks
I have CarPlay Video enabled for my account and App ID. I tested both my main app and a completely new minimal iOS app with a new Bundle ID. The minimal app only contains: UIApplicationDelegate CPTemplateApplicationScene configuration CPTemplateApplicationSceneDelegate A single CPListTemplate root Results: With com.apple.developer.carplay-audio only, CarPlay launches normally. When com.apple.developer.carplay-video is added, CarPlay opens a blank screen. No CarPlay callbacks are called: application(:configurationForConnecting:options:) CPTemplateApplicationSceneDelegate.templateApplicationScene(:didConnect:) CPApplicationDelegate.didConnectCarInterfaceController The signed app and embedded provisioning profile both contain com.apple.developer.carplay-video. Does CarPlay Video require an additional runtime allowlist, specific head unit support, a different scene configuration, or another entitlement beyond com.apple.developer.carplay-video?
5
1
1.1k
5d
Keyboard Toolbar Padding iOS26
When I create a SwiftUI toolbar item with placement of .keyboard on iOS 26, the item appears directly on top of and in contact with the keyboard. This does not look good visually nor does it match the behavior seen in Apple's apps, such as Reminders. Adding padding to the contents of the toolbar item only expands the size of the item but does not separate the capsule background of the item from the keyboard. How can I add vertical padding or spacing to separate the toolbar item capsule from the keyboard?
Topic: UI Frameworks SubTopic: SwiftUI
15
9
2.4k
6d
iOS 27: SwiftUI TextField text invisible while typing when the app runs in Arabic (FB25410049)
Since iOS 27, if an app runs in Arabic (or, presumably, any right-to-left language), typing digits or Latin letters into a SwiftUI TextField makes the field look empty. The binding updates and the caret shows, but the text isn't drawn until editing ends. What I measured: The text's layout fragment is placed at about x = −39,655 pt in a 370 pt wide field, so it's drawn far outside the field. A plain TextField and one with .environment(\.layoutDirection, .leftToRight) (phone and card numbers) are both affected. A UIKit UITextField on the same screen isn't affected. The same build on iOS 18.0 works, and iOS 27 in English works. Minimal repro: one SwiftUI file with four fields. Run it with App Language set to Arabic, tap the first field and type 523. Launch with -autoProbe to have it type into each field and print where the text was laid out. PROBE iOS 27.0, language ar, layout RTL PROBE field 1 text="523" fieldWidth=370 fragmentX=[-39655] visible=false // SwiftUI TextField PROBE field 2 text="523" fieldWidth=370 fragmentX=[-39655] visible=false // SwiftUI, LTR pinned PROBE field 3 text="523" fieldWidth=370 fragmentX=[314] visible=true // UIKit UITextFieldWorkaround that works for us, installed once at launch: import UIKit enum TextFieldDirection { static func install() { for name in [UITextField.textDidBeginEditingNotification, UITextField.textDidChangeNotification] { NotificationCenter.default.addObserver(forName: name, object: nil, queue: .main) { note in guard let field = note.object as? UITextField else { return } MainActor.assumeIsolated { settle(field) } // SwiftUI rebuilds the paragraph style right after; settle again. DispatchQueue.main.async { MainActor.assumeIsolated { settle(field) } } } } } @MainActor static func settle(_ field: UITextField) { let direction: NSWritingDirection = field.effectiveUserInterfaceLayoutDirection == .rightToLeft ? .rightToLeft : .leftToRight if let whole = field.textRange(from: field.beginningOfDocument, to: field.endOfDocument) { field.setBaseWritingDirection(direction, for: whole) } func directed(_ attributes: [NSAttributedString.Key: Any]) -> [NSAttributedString.Key: Any] { var attributes = attributes let style = (attributes[.paragraphStyle] as? NSParagraphStyle)?.mutableCopy() as? NSMutableParagraphStyle ?? NSMutableParagraphStyle() style.baseWritingDirection = direction attributes[.paragraphStyle] = style return attributes } if let typing = field.typingAttributes { field.typingAttributes = directed(typing) } field.defaultTextAttributes = directed(field.defaultTextAttributes) field.setNeedsLayout() field.layoutIfNeeded() } }Don't pin textAlignment instead. SwiftUI puts .natural back on every keystroke and the caret jumps from side to side. If you see this too, please file a duplicate referencing FB25410049. Duplicates help Apple prioritise it.
1
0
81
6d
How do deal with NavigationSplitView not saving selection on iPhone
I have a detail view that has a @Binding var Thing, which is passed to it from the parent. It has TextFields that need to use that bound object's fields. // Using this to pass the selection around @Observable class AppSelection { var selectedThings:Set<Thing> = Set(); } struct ContentView: View { @State private var selectionStore = AppSelection(); var body: some View { NavigationSplitView { ... } content: { ...list that sets the selectionStore.selectedThings... } detail: { if !selectionStore.selectedThings.isEmpty { DetailView(thing:Binding( get: { selectionStore.selectedThings.first! }, // Crashes here set: { selectionStore.selectedThings = [$0] } )) .frame(maxHeight:.infinity, alignment:.top) } else { Text("Select a thing."); } } } } struct DetailView:View { @Binding var thing:Thing; var body:some View { TextField("Blah", $thing.name); TextField("Blerg", $thing.stuff); } }A crash happens when I navigate back from the DetailView in the line commented as such. I assume the NavigationSplitView is resetting the selection back to an empty state. Why the Binding given to the DetailView is even trying to get its value at that point is beyond me (so much weirdness in SwiftUI). I've taken so many different stabs at trying to make things work differently, but I just don't understand enough about SwiftUI. Like can I make the DetailView take an optional binding? If the Thing is nil, then all the TextFields complain that they require a non-optional binding. I don't even want to show the Detail view if nothing is selected (hence the "Select a thing.").
1
0
867
6d
NavigationSplitView, endless loop detail<->content
Hi, I already had a problem with the NavigationSplitView before, and I'm still working on it. The NavigationSplitView issue on the phone occurs when trying to navigate back from the detail view to the content view; the app automatically navigates straight back to the detail view. I reproduced the issue in a small program and identified the critical section. However, I do not know why the problem is occurring. I did the same thing again, but this time with @Query, and there was no problem. The categories, recipes and single recipe, all loaded by @Query and no side effects. Requirements for the content: A state variable used in the view, e.g., isLoading A task that loads the data from a ModelActor in a ViewModel, setting isLoading to true beforehand and back to false upon completion Subsequently, it is only possible to exit the detail view after many attempts, because the app immediately navigates back to the detail view automatically upon trying to leave it. One issue is changing the isLoading status variable from within the task. That in itself isn't the problem; the issue only arises when reading data via a ModelActor. If the status variable is changed and, for example, the list is modified manually, there is no problem. It only occurs when a ModelActor is used. I based it on the NavigationCookbook: This is the view I use for the content section (list): @State private var vm: RecipeListViewModel = .init() @State var isLoading: Bool = false if isLoading { ProgressView("Loading...") } else { List(selection: $selectedRecipe) { ForEach(vm.recipes) { recipe in NavigationLink(recipe.name, value: recipe) } } } .task { // bug, when used in UI, because of ModelActor isLoading = true await vm.list(context, categoryName: selectedCategory.name) isLoading = false } .task { // works, because manually modifying the list isLoading = true await vm.addRecipe(context, categoryName: selectedCategory.name) isLoading = false } inside ViewModel // bug func list(_ modelContext: ModelContext, categoryName: String) async { recipes.removeAll() let dh: RecipeDataHandler = .init(modelContainer: modelContext.container) let values = await dh.listByName(categoryName: categoryName) for v in values { recipes.append(.init(recipeId: v.recipeId, name: v.name)) } } // works func addRecipe(_ modelContext: ModelContext, categoryName: String) async { isLoading = true defer { isLoading = false } recipes.removeAll() recipes.append(.init(recipeId: "a", name: "Pambazo")) } ModelActor @ModelActor actor RecipeDataHandler { func listByName(categoryName: String) async -> [RecipeData] { var list: [RecipeData] = [] do { let fd = FetchDescriptor<Recipe>(predicate: #Predicate { $0.category.name == categoryName }, sortBy: [SortDescriptor(\Recipe.name)]) let data = try modelContext.fetch(fd) for item in data { let rec: RecipeData = await .init(recipeId: item.recipeId, name: item.name) list.append(rec) } } catch { print("error: \(error.localizedDescription)") } return list } } Recipe is a @Model and RecipeData just a struct. In principle, everything should run on the MainActor, but the inclusion of the ModelActor still leads to this strange behavior. Any idea what the problem might be? Christian
3
0
358
1w
NavigationSplitView Binding to NavigationSplitViewColumn reset with every NavigationStack path change
I try to create a Navigation that works on iPhone, iPhone Duo and iPad. NavigationSplitView collapses for compact form factors and makes iPhone Duo support much simpler. The Problem is the semantic of the collapse. Switch from detail to sidebar on compact is not a 'back' action in my case. It should have my choosen Icon and has a meaning. So i wanted to control this using the NavigationSpliViewColumn Binding. This does work forward and backward as long as no NavigationStack was used before. But it stops working when you return to the detail root from a Navigation-Action. I left the Backbutton visible so you can test, that it continues to work, when no Navigation-Action preceeded the switch. Here is my Code: import SwiftUI @Observable final class Compass { var path: [Route] init() { self.path = [] } } enum Route: Hashable { case goal } struct ContentView: View { @Environment(\.horizontalSizeClass) private var hsize @State private var compass: Compass = Compass() @State var column: NavigationSplitViewColumn = .detail var body: some View { NavigationSplitView(preferredCompactColumn: $column) { OverviewScreen(column: $column) } detail: { TodayScreen() .toolbar { ToolbarItem(placement: .topBarLeading) { Button("overview", systemImage: "calendar") { self.column = .sidebar } } } } .environment(compass) .onChange(of: column) { old, new in print("column:", old, "→", new) } } } struct OverviewScreen: View { @Binding var column: NavigationSplitViewColumn @Environment(Compass.self) var compass var body: some View { @Bindable var compass = self.compass ScrollView { Text("Overview") .font(.largeTitle) .fontWeight(.heavy) Button("Switch") { self.column = .detail } } } } struct TodayScreen: View { @Environment(Compass.self) var compass var body: some View { @Bindable var compass = self.compass NavigationStack(path: $compass.path) { ScrollView { Text("Today") .font(.largeTitle) .fontWeight(.heavy) Button("Goals programtically", systemImage: "flag.fill") { self.compass.path = [.goal] } NavigationLink(value: Route.goal) { Label("Goal Link", systemImage: "flag.fill") } } .navigationDestination(for: Route.self, destination: self.screen) } } @ContentBuilder func screen(for route: Route) -> some View { switch route { case .goal: Text("Goals") } } } #Preview { ContentView() }This seems unexpected behaviour. If you ask AI the mental model is NavigationSplitViewColumn represents which column is currently visible for the user. That model would be wrong. Also i can't understand why a NavigationStack has to change the Binding? What am i missing here? Is my idea of the programmatic switch not supported? There are other ways to push from compact to your detail column again, but they all have trade-offs or run into other problems. I would appreciate any help here. AI has not understood this and only does surface level work arounds that fix nothing.
0
0
58
1w
What pattern to use for an iPhone Tabview app
I have an iPhone tab view application that has not been designed for iPad, and I am aiming to add a left-hand bar that summarises some content and keeps visible what is normally a sheet. What pattern would work best for this? At present, I pass the view to another view with a navigation stack containing an arrangement view with the previous view and then the sidebar as a secondary view within it—would that be the appropriate approach?
Topic: UI Frameworks SubTopic: SwiftUI
3
0
427
1w
Best way to position game touch controls around the iPhone Duo hinge
For a full-screen game with a Metal/Unreal rendering view and a SwiftUI overlay for touch controls, what is the recommended way to keep interactive controls away from the hinge while still allowing the rendered game world to use the full display? Would you recommend querying ReservedRegion in the SwiftUI overlay while allowing the underlying render view to remain edge-to-edge? Also, should control placement respond continuously while the device is being folded, or primarily respond to layout/reserved-region changes once the pose changes?
Topic: UI Frameworks SubTopic: SwiftUI
1
0
111
1w
iPhone Duo: SwiftUI Layout Differs Between Simulator and Physical Device (Tab Bar Placement and Content Cropping)
Hi everyone, I'm experiencing a significant difference in SwiftUI layout behavior between the iPhone Duo simulator and a physical iPhone Duo. I've already adjusted my layout to work correctly in the simulator, but the same app behaves differently on the actual device. 1. Folded Simulator: The tab bar is positioned on the right side, as expected for iPhone Duo. The view respects the right-side layout, and scroll views extend naturally behind the tab bar, behaving as expected. Physical device: The tab bar appears at the bottom, like a regular iPhone, instead of on the right. The view is also cropped on the right side. 2. Unfolded Simulator: The tab bar and navigation view both appear correctly. Physical device: The tab bar remains at the bottom, even in landscape orientation, instead of using the expected Duo layout. The main content also starts from the bottom of the navigation view, resulting in an incorrect layout. The most confusing part is that the layout works correctly in the simulator but not on the physical device. Has anyone encountered this behavior on a physical iPhone Duo? Could this be related to the iOS version, SDK version, SwiftUI's automatic tab bar adaptation, or a device-specific bug? I'd appreciate any insights, especially from developers who have tested their SwiftUI apps on actual iPhone Duo hardware. Environment: Xcode version: 27.1 iOS SDK: 27.1 Physical device iOS version: 27.2 Thanks!
1
0
128
1w
Bug Report: Xcode 26.6 Codex Agent Fails with Response Decoding and Model Compatibility Errors
Bug Report: Xcode 26.6 Codex Agent Fails with Response Decoding and Model Compatibility Errors Severity: High — Core agent functionality unavailableComponent: Xcode Intelligence / Codex Agent IntegrationEnvironment: macOS, Xcode 26.6 (17F113)Date reported: November 1, 2026 Summary The built-in Codex coding agent in Xcode consistently fails to process requests, despite successful ChatGPT Pro authentication and a functioning standalone Codex CLI. The problem occurs even with trivial prompts and prevents use of Codex's autonomous development functionality, including the Pursue Goal workflow. The standard ChatGPT integration inside Xcode works correctly. The failure is isolated to the Codex agent integration. Environment ComponentDetailsIDEXcode 26.6 (17F113)Built-in Codex agent0.140.0 (version observed before reinstall)Standalone Codex CLI0.166.0ACP adapter testedcodex-acp 2.5.0AccountChatGPT ProAuthenticationChatGPT account authenticationAffected projectsMultiple SwiftUI projectsModel testedgpt-5.5, gpt-6.1-solActual Behavior When initiating a conversation with the built-in Codex agent in Xcode, the request fails with the following messages: Error 1: Response decoding failure The data couldn’t be read because it isn’t in the correct format.Accompanied by: Your request couldn't be completed.Error 2: Unsupported model With the original model selection: Codex encountered an error: The 'gpt-5.5' model is not supported when using Codex with a ChatGPT account.After explicitly configuring gpt-6.1-sol: Codex encountered an error: The 'gpt-6.1-sol' model is not supported when using Codex with a ChatGPT account.Error 3: ACP communication failure When testing a separately registered Codex ACP adapter: JSON-RPC request with ID [...] failed to produce a response.This was observed in a separate integration experiment and should not automatically be assumed to share the same root cause as the built-in Codex failure. Expected Behavior The built-in Codex agent should: Authenticate with an eligible ChatGPT Pro account. Select a model supported by the account and installed agent version. Correctly initialize the agent and decode its protocol responses. Execute basic prompts without errors. Support Xcode's native agentic development workflows, including Pursue Goal. Present actionable diagnostics when authentication, model selection, or protocol initialization fails. Reproduction Steps Open Xcode 26.6. Open an existing SwiftUI project. Open the Coding Assistant. Start a new conversation. Select Codex under Agents, rather than OpenAI under Chat. Submit a trivial prompt, such as: Reply with exactly OK. Observe the request failing with a response-format error or an unsupported-model error, depending on configuration. The issue is reproducible across multiple attempts and is not specific to a complex coding task. Troubleshooting Performed The following troubleshooting actions have already been attempted: Reauthenticated using the ChatGPT account. Tested configuration-file-based authentication. Reset Codex authentication. Reinstalled Xcode. Reinstalled the Xcode Codex component. Restarted Xcode and created new conversations. Tested explicit model selection through config.toml. Tested standalone Codex with the same ChatGPT Pro account. Tested a separate ACP adapter integration. The built-in Codex agent remains unusable. Confirmed Successful Control Test Standalone Codex CLI 0.166.0 successfully executed a request using GPT-6.1 Sol. Command: codex exec --model gpt-6.1-sol --skip-git-repo-check \ "Reply with exactly OK. Do not edit files or use tools."Observed output: OpenAI Codex v0.166.0 model: gpt-6.1-sol provider: openai reasoning effort: high codex OKThe request completed without an API error. Additionally, Xcode's separate ChatGPT integration displays the ChatGPT Pro account as authenticated, with usage status Under Limit. These observations strongly suggest that the problem is specific to the Xcode Codex integration or its runtime environment, rather than a general account authentication failure. Suspected Root Causes The following are hypotheses requiring investigation, not confirmed causes: 1. Bundled agent version incompatibility Xcode was observed using Codex 0.140.0, while standalone Codex 0.166.0 successfully accessed GPT-6.1 Sol. Please verify whether the bundled Codex agent is compatible with currently available ChatGPT-authenticated models. 2. Model discovery or selection mismatch The bundled agent's model catalog included models that were subsequently rejected by the service. Please investigate whether Xcode refreshes the model catalog, respects model configuration overrides, and selects models based on account eligibility. 3. Agent protocol response decoding The generic data-format error suggests a possible failure to decode an agent response, handle an unsupported response schema, or propagate an underlying API error. Please inspect the agent initialization, response parsing, and error-handling paths. 4. Configuration and authentication isolation The normal ChatGPT integration authenticates successfully, while the Codex agent fails. Please verify how Xcode manages distinct authentication contexts, configuration locations, agent versions, and model capabilities. Requested Engineering Actions Please investigate and address the following: Ensure the Xcode Codex agent is compatible with supported ChatGPT-authenticated models. Verify that the bundled agent version is current and that component updates are correctly delivered. Validate model availability before dispatching requests. Ensure the model selected in Xcode matches the actual model submitted by the agent. Correct any incompatible protocol or JSON response handling. Expose the underlying error details rather than only reporting a generic data-format failure. Confirm that reinstalling or updating the Xcode Codex component restores a functional agent without requiring manual configuration changes. Add regression coverage for ChatGPT Pro authentication, model selection, agent initialization, and basic prompt execution. Impact The issue prevents me from using the Codex agent directly inside Xcode, despite having a ChatGPT Pro subscription and a fully functional standalone Codex CLI. As a result, I cannot use the integrated agentic coding experience or the Pursue Goal workflow that previously worked. Please investigate the bundled Codex runtime, model selection, and protocol compatibility. The successful standalone Codex 0.166.0 test provides a control case for reproducing and isolating the failure.
Replies
1
Boosts
1
Views
323
Activity
2h
Tab grayed out, but not disabled
Bug report: FB25495244 This bug also appeared with Xcode 27; it worked previously. scenario: A TabView with, for example, 4 tabs. Data in ContentView is loaded via @Query. In ContentBindingView, the same thing is done, but using a parameter instead of SwiftData. ContentView: If no data is available, the system automatically switches to tab 4 at the start; while you can click on other tabs, they are disabled, and the system will not switch to them. ContentBindingView: When tabDisabled is set to "true", the system automatically switches to Tab 4 upon startup; while it is possible to click on other tabs, they are disabled, and the system will not switch to them. So far, so good. The first three tabs are only active if at least one data record exists or tabDisabled is "false". Tab 4 is always active and is used for data entry. When data is entered in Tab 4, tab 1 to 3 should become active. However, it appears as though tabs 1 through 3 remain disabled—the icons appear grayed out. That is actually not the case; you can click on the tabs, and as soon as you move away from a tab, its icon is displayed correctly. This issue did not exist in Xcode 26. In Xcode 26, all symbols were displayed correctly from the start, once data had been saved. What I noticed on the iPhone Duo: If you open the program on an iPhone Duo while it is closed, enter some data, then move the app to the background, open the iPhone Duo, and bring the application back to the foreground, tabs 1 through 3 will be active. The entire view is being updated, which is why tabs 1 through 3 are now active—though they should have been active already. A side note: The same issue described in the forum post "A layout bug when using Tab View in SwiftUI (FB25490881)" also occurs in this program. The entire view has shifted upward. The text field is no longer visible—only the Add button remains. In the other views, you can only see half of the text. import SwiftUI struct ContentBindingView: View { @State private var tabDisabled: Bool = true @State private var selection: TabSelection = .tab1 private var isTabDisabled: Bool { print("ContentView.isTabDisabled: \(tabDisabled)") return tabDisabled } var body: some View { TabView(selection: $selection) { Tab("Tab 1", systemImage: "waveform.badge.magnifyingglass", value: .tab1) { Text("tab 1") } .disabled(isTabDisabled) Tab("Tab 2", systemImage: "heart", value: .tab2) { Text("tab 2") } .disabled(tabDisabled) Tab("Tab 3", systemImage: "target", value: .tab3) { Text("tab 3") } .disabled(tabDisabled) Tab("Tab 4", systemImage: "gear", value: .tab4) { AddFriendBindingView(tabDisabled: $tabDisabled) } } .onAppear { print("ContentView onAppear disabled: \(tabDisabled)") if tabDisabled { selection = .tab4 } } .onChange(of: selection) { print("ContentView onChange disabled: \(tabDisabled)") } } }struct AddFriendBindingView: View { @Environment(\.dismiss) private var disdmiss @Binding var tabDisabled: Bool @State private var name: String = "" var body: some View { VStack { TextField("Name", text: $name) Button { addFriend() } label: { Text("Add") } .buttonStyle(.borderedProminent) } .padding() .onAppear { print("AddFriendView onAppear disabled: \(tabDisabled)") } } private func addFriend() { tabDisabled = false name = "" disdmiss() } }Christian
Replies
1
Boosts
0
Views
248
Activity
12h
A layout bug when using Tab View in SwiftUI
I've been getting some unexpected behavior when using TabView as the root view in SwiftUI, which I believe to be a bug. I created a barebones app to isolate the bug and will paste the code at the end for anyone who wants to try to reproduce it if you have a physical Duo device. Details below copied from my Feedback ticket FB25490881. Xcode 27.1. What's the bug? When you have a TabView as the root view inside the ContentView.swift and you open the app on the outer screen, then swipe it to the background, unfold the phone and tap the app to bring it to the foreground, any UI element without a fixed frame size gets moved off screen. And any UI element with a fixed frame size gets moved to the very top of the screen. See my two screenshots of outer vs inner display. How to reproduce: 1- Unzip the project folder and open it in Xcode. 2- With a physical Duo on hand, run the app on the Duo. 3- On the outer screen, launch the app. 4- Swipe the app to the background (Do not swipe completely to close the app, just swipe it to the background so it is still running) 5- Unfold the iPhone Duo completely open. 6- Tap the app icon to bring it to the foreground. 7- Look at the broken UI. Also note even the side tab bar itself is broken, it has no padding with the edge of the screen. This is managed by the system. The workaround to fix it: 1- Go to the ContentView.Swift in Xcode. 2- Uncomment "NavigationStack {" on line 13. 3- Uncomment the closing bracket "}" on line 2. 4- Repeat the previous from how to reproduce the bug. My hypothesis: The system reports 0 height for the inner screen in that moment you bring the app to the foreground. Anything with a fixed frame will move to the top, anything with flexible height will not be visible. This only happens when TabView is the root of the scene. Other Useful Information: I hit a very similar bug to this in my main app that I'm still developing, unfortunately I was not able to reproduce it in a sandbox simple app. The bug was: 1- Open the app on outer screen 2- While the app is open, tilt the Duo to the back at a certain angle 3- Unfold the Duo 4- You get this exact same bug where everything with a flexible height disappears off screen or collapses to zero if it's in between UI elements with fixed heights. And everything moves to the top of the screen. I'm not sure why I wasn't able to reproduce it on a sandbox app, but the fix was the same, either remove the TabView completely or put it inside a NavigationStack. I want to stress that this one had to do with the backwards tilt of the phone itself while unfolding it, very weird I know. ContentView.swift: import SwiftUI @available(iOS 27.1, *) struct ContentView: View { var body: some View { // NavigationStack { TabView { HomeTabView() .tabItem { Label("Home", systemImage: "house") } StoreView() .tabItem { Label("Store", systemImage: "bag") } } .tint(Color.black) // } } } HomeTabView.swift: import SwiftUI @available(iOS 27.1, *) struct HomeTabView: View { var body: some View { VStack { Text("Jenny") .font(.largeTitle) .fontWeight(.bold) .padding() .frame(maxWidth: .infinity) .frame(height: 200) .background(Color.gray, in: .rect(cornerRadius: 28)) Spacer() Circle() .fill(Color.blue) .frame(width: 100, height: 100) .padding(.bottom, 50) } .contentMargins(for: .container, edges: .horizontal) } } StoreView.swift is just an default empty swiftUI file with the default Text("Hello, World!")
Replies
2
Boosts
0
Views
360
Activity
17h
TabView(.page) extended under the tab bar shifts its pages up after the container height shrinks while visible
Summary A page-style TabView that extends under the bottom tab bar with .ignoresSafeArea(edges: .bottom) leaves its pages shifted upward after its height shrinks while it is on screen. The shift is half of the bottom safe area (41.67 pt with an 83.33 pt tab bar area), and the top of each page is hidden. The internal UICollectionView (contentInsetAdjustmentBehavior == .automatic) seems to briefly add the bottom safe area to adjustedContentInset.bottom during the resize. The inset goes back to 0 afterwards, but the visible cell is left at frame.minY == -41.67. Environment Xcode 27.0 (27A266a), iPhone Duo Simulator (iOS 27.1), deployment target iOS 18.0 In a unit test it also reproduces when only the window height shrinks (386×678 → 386×600), so it does not depend on the foldable device Steps to reproduce Run the code below on the iPhone Duo Simulator while it is folded Unfold the device Expected The red "Top of page 0" area stays directly below the yellow header, as it does when the app is launched unfolded. Actual The top of the red area is hidden under the header. Log output: folded (launch): height=628.00 adjustedContentInset.bottom=0.00 cell.minY=0.00 after unfolding: height=619.00 adjustedContentInset.bottom=0.00 cell.minY=-41.67In this sample the page returns to its position when the device is folded again. In our app it stays shifted, and after the shift, tapping to switch pages sometimes stops working until the user swipes. Notes Removing .ignoresSafeArea(edges: .bottom) avoids the issue, but the content then no longer extends under the translucent tab bar Setting edgesForExtendedLayout = [] on the hosting controller also avoids it, with the same visual change. safeAreaRegions = [] and setContentScrollView(nil, for:) do not help A non-transparent background on the TabView or its pages, as suggested in https://developer.apple.com/forums/thread/762286, does not help. The trigger here is a size change, not a page switch, so this seems to be a different issue Current workaround: find the internal UICollectionView through the superview chain and set contentInsetAdjustmentBehavior = .never. This works, but it relies on the private view hierarchy. Is there a supported way to avoid this? Minimal reproduction import SwiftUI import UIKit // A TabView(.page) extended under the tab bar with .ignoresSafeArea(edges: .bottom). // Resizing the window while it is visible (e.g. unfolding) shifts the page up. struct PagerView: View { @State private var selection = 0 var body: some View { VStack(spacing: 0) { Color.yellow.frame(height: 50).overlay(Text("Header")) TabView(selection: $selection) { ForEach(0..<2) { index in ScrollView { Color.red.frame(height: 120).overlay(Text("Top of page \(index)")) ForEach(0..<30) { Text("Row \($0)").frame(maxWidth: .infinity, minHeight: 44) } } .tag(index) } } .tabViewStyle(.page(indexDisplayMode: .never)) } .ignoresSafeArea(edges: .bottom) } } final class PagerViewController: UIHostingController<PagerView> { override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { [weak self] in self?.logCollectionView() } } private func logCollectionView() { func find(_ view: UIView) -> UICollectionView? { view as? UICollectionView ?? view.subviews.lazy.compactMap(find).first } guard let collectionView = find(view) else { return } let cellMinY = collectionView.visibleCells.first?.frame.minY ?? .nan NSLog("FORUM height=%.2f adjustedContentInset.bottom=%.2f cell.minY=%.2f", collectionView.bounds.height, collectionView.adjustedContentInset.bottom, cellMinY) } } @main final class AppDelegate: UIResponder, UIApplicationDelegate { func application(_ application: UIApplication, configurationForConnecting session: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { let configuration = UISceneConfiguration(name: nil, sessionRole: session.role) configuration.delegateClass = SceneDelegate.self return configuration } } final class SceneDelegate: UIResponder, UIWindowSceneDelegate { var window: UIWindow? func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { let pager = PagerViewController(rootView: PagerView()) pager.tabBarItem = UITabBarItem(title: "Pager", image: UIImage(systemName: "square"), tag: 0) let other = UIViewController() other.tabBarItem = UITabBarItem(title: "Other", image: UIImage(systemName: "circle"), tag: 1) let tabBarController = UITabBarController() tabBarController.viewControllers = [pager, other] window = UIWindow(windowScene: scene as! UIWindowScene) window?.rootViewController = tabBarController window?.makeKeyAndVisible() } }
Replies
3
Boosts
2
Views
360
Activity
17h
iPhone: Inspector Sheet Issue with Navigation Toolbar Toggle
Hello, I think this might be a bug, but I'm not sure (see the code below). FB25486625 On iPhone, when the inspector is presented as a SHEET, swiping down to dismiss it (instead of tapping the close button inside the inspector) causes the navigation toolbar toggle to stop working properly: tapping it once won't reopen the inspector. You have to tap it twice (turning it on and off again) to make the inspector appear again. This doesn't happen when the inspector is presented as a SIDEBAR on iPad or macOS. import SwiftUI struct ContentView: View { @State private var showInspector = false var body: some View { NavigationStack{ Text("Hello, world!") .padding() .inspector(isPresented: $showInspector) { Button("Close Inspector", role: .cancel) { showInspector.toggle() } Text("On iPhone, with inspector as SHEET, if you swipe to close (instead of tap the close button), the toggle in the navigation toolbar won't open the inspector next time (half the time). It doesn't affect inspector as SIDEBAR on iPad") .padding() Spacer() } .toolbar { Toggle(isOn: $showInspector) { Label("Open", systemImage: "sidebar.trailing") } } } } } #Preview { ContentView() }
Replies
0
Boosts
0
Views
49
Activity
1d
iOS 27 regression - minimized search item in top toolbar breaks its state
struct ContentView: View { @State var searchText: String = "" var body: some View { TabView { Tab { NavigationStack { List { Text("Hello!") Text("Hello!") Text("Hello!") Text("Hello!") Text("Hello!") Text("Hello!") } .navigationTitle("Have a title") .searchable(text: $searchText, placement: .toolbar) .searchToolbarBehavior(.minimize) .toolbar { DefaultToolbarItem(kind: .search, placement: .topBarTrailing) } } } } } } In iOS 26, this worked no problem. In iOS 27, this leaves the search bar either unable to collapse (when pressing the close button) or in a broken state where it cannot be opened again.
Topic: UI Frameworks SubTopic: SwiftUI
Replies
10
Boosts
12
Views
1.8k
Activity
3d
Charts are broken with Xcode 27, Plotting multiple lines
Hi, Charts—specifically those with multiple lines—are broken in Xcode 27. First, I spotted the bug in my program, and then I checked your example. Your own example Plotting-multiple-lines is not working correctly anymore. It shows 1 line or sometimes no lines at all, depending on the order of the data. It depends on how the data is passed to the chart. If the data is passed as separate series, it works. In Visualizing your app’s data it works, but the data is passed as described before. Don't follow Microslop: have the AI ​​generate the code and then skip the tests. This is a serious bug that requires a lot of work to rearrange the data, just to work around the issue. Christian
Replies
9
Boosts
0
Views
1.8k
Activity
3d
`presentationPlacement(_:)` support on Catalyst
presentationPlacement(_:) is a great addition and brings us very close to being able to deprecate a custom side sheet we wrote, but one missing piece we found is that it isn't yet honored on Catalyst. It would be great if support for this could be added!
Topic: UI Frameworks SubTopic: SwiftUI
Replies
0
Boosts
0
Views
43
Activity
4d
CarPlay Video entitlement causes blank screen and no CPTemplateApplicationScene callbacks
I have CarPlay Video enabled for my account and App ID. I tested both my main app and a completely new minimal iOS app with a new Bundle ID. The minimal app only contains: UIApplicationDelegate CPTemplateApplicationScene configuration CPTemplateApplicationSceneDelegate A single CPListTemplate root Results: With com.apple.developer.carplay-audio only, CarPlay launches normally. When com.apple.developer.carplay-video is added, CarPlay opens a blank screen. No CarPlay callbacks are called: application(:configurationForConnecting:options:) CPTemplateApplicationSceneDelegate.templateApplicationScene(:didConnect:) CPApplicationDelegate.didConnectCarInterfaceController The signed app and embedded provisioning profile both contain com.apple.developer.carplay-video. Does CarPlay Video require an additional runtime allowlist, specific head unit support, a different scene configuration, or another entitlement beyond com.apple.developer.carplay-video?
Replies
5
Boosts
1
Views
1.1k
Activity
5d
Keyboard Toolbar Padding iOS26
When I create a SwiftUI toolbar item with placement of .keyboard on iOS 26, the item appears directly on top of and in contact with the keyboard. This does not look good visually nor does it match the behavior seen in Apple's apps, such as Reminders. Adding padding to the contents of the toolbar item only expands the size of the item but does not separate the capsule background of the item from the keyboard. How can I add vertical padding or spacing to separate the toolbar item capsule from the keyboard?
Topic: UI Frameworks SubTopic: SwiftUI
Replies
15
Boosts
9
Views
2.4k
Activity
6d
iOS 27: SwiftUI TextField text invisible while typing when the app runs in Arabic (FB25410049)
Since iOS 27, if an app runs in Arabic (or, presumably, any right-to-left language), typing digits or Latin letters into a SwiftUI TextField makes the field look empty. The binding updates and the caret shows, but the text isn't drawn until editing ends. What I measured: The text's layout fragment is placed at about x = −39,655 pt in a 370 pt wide field, so it's drawn far outside the field. A plain TextField and one with .environment(\.layoutDirection, .leftToRight) (phone and card numbers) are both affected. A UIKit UITextField on the same screen isn't affected. The same build on iOS 18.0 works, and iOS 27 in English works. Minimal repro: one SwiftUI file with four fields. Run it with App Language set to Arabic, tap the first field and type 523. Launch with -autoProbe to have it type into each field and print where the text was laid out. PROBE iOS 27.0, language ar, layout RTL PROBE field 1 text="523" fieldWidth=370 fragmentX=[-39655] visible=false // SwiftUI TextField PROBE field 2 text="523" fieldWidth=370 fragmentX=[-39655] visible=false // SwiftUI, LTR pinned PROBE field 3 text="523" fieldWidth=370 fragmentX=[314] visible=true // UIKit UITextFieldWorkaround that works for us, installed once at launch: import UIKit enum TextFieldDirection { static func install() { for name in [UITextField.textDidBeginEditingNotification, UITextField.textDidChangeNotification] { NotificationCenter.default.addObserver(forName: name, object: nil, queue: .main) { note in guard let field = note.object as? UITextField else { return } MainActor.assumeIsolated { settle(field) } // SwiftUI rebuilds the paragraph style right after; settle again. DispatchQueue.main.async { MainActor.assumeIsolated { settle(field) } } } } } @MainActor static func settle(_ field: UITextField) { let direction: NSWritingDirection = field.effectiveUserInterfaceLayoutDirection == .rightToLeft ? .rightToLeft : .leftToRight if let whole = field.textRange(from: field.beginningOfDocument, to: field.endOfDocument) { field.setBaseWritingDirection(direction, for: whole) } func directed(_ attributes: [NSAttributedString.Key: Any]) -> [NSAttributedString.Key: Any] { var attributes = attributes let style = (attributes[.paragraphStyle] as? NSParagraphStyle)?.mutableCopy() as? NSMutableParagraphStyle ?? NSMutableParagraphStyle() style.baseWritingDirection = direction attributes[.paragraphStyle] = style return attributes } if let typing = field.typingAttributes { field.typingAttributes = directed(typing) } field.defaultTextAttributes = directed(field.defaultTextAttributes) field.setNeedsLayout() field.layoutIfNeeded() } }Don't pin textAlignment instead. SwiftUI puts .natural back on every keystroke and the caret jumps from side to side. If you see this too, please file a duplicate referencing FB25410049. Duplicates help Apple prioritise it.
Replies
1
Boosts
0
Views
81
Activity
6d
How do deal with NavigationSplitView not saving selection on iPhone
I have a detail view that has a @Binding var Thing, which is passed to it from the parent. It has TextFields that need to use that bound object's fields. // Using this to pass the selection around @Observable class AppSelection { var selectedThings:Set<Thing> = Set(); } struct ContentView: View { @State private var selectionStore = AppSelection(); var body: some View { NavigationSplitView { ... } content: { ...list that sets the selectionStore.selectedThings... } detail: { if !selectionStore.selectedThings.isEmpty { DetailView(thing:Binding( get: { selectionStore.selectedThings.first! }, // Crashes here set: { selectionStore.selectedThings = [$0] } )) .frame(maxHeight:.infinity, alignment:.top) } else { Text("Select a thing."); } } } } struct DetailView:View { @Binding var thing:Thing; var body:some View { TextField("Blah", $thing.name); TextField("Blerg", $thing.stuff); } }A crash happens when I navigate back from the DetailView in the line commented as such. I assume the NavigationSplitView is resetting the selection back to an empty state. Why the Binding given to the DetailView is even trying to get its value at that point is beyond me (so much weirdness in SwiftUI). I've taken so many different stabs at trying to make things work differently, but I just don't understand enough about SwiftUI. Like can I make the DetailView take an optional binding? If the Thing is nil, then all the TextFields complain that they require a non-optional binding. I don't even want to show the Detail view if nothing is selected (hence the "Select a thing.").
Replies
1
Boosts
0
Views
867
Activity
6d
NavigationSplitView, endless loop detail<->content
Hi, I already had a problem with the NavigationSplitView before, and I'm still working on it. The NavigationSplitView issue on the phone occurs when trying to navigate back from the detail view to the content view; the app automatically navigates straight back to the detail view. I reproduced the issue in a small program and identified the critical section. However, I do not know why the problem is occurring. I did the same thing again, but this time with @Query, and there was no problem. The categories, recipes and single recipe, all loaded by @Query and no side effects. Requirements for the content: A state variable used in the view, e.g., isLoading A task that loads the data from a ModelActor in a ViewModel, setting isLoading to true beforehand and back to false upon completion Subsequently, it is only possible to exit the detail view after many attempts, because the app immediately navigates back to the detail view automatically upon trying to leave it. One issue is changing the isLoading status variable from within the task. That in itself isn't the problem; the issue only arises when reading data via a ModelActor. If the status variable is changed and, for example, the list is modified manually, there is no problem. It only occurs when a ModelActor is used. I based it on the NavigationCookbook: This is the view I use for the content section (list): @State private var vm: RecipeListViewModel = .init() @State var isLoading: Bool = false if isLoading { ProgressView("Loading...") } else { List(selection: $selectedRecipe) { ForEach(vm.recipes) { recipe in NavigationLink(recipe.name, value: recipe) } } } .task { // bug, when used in UI, because of ModelActor isLoading = true await vm.list(context, categoryName: selectedCategory.name) isLoading = false } .task { // works, because manually modifying the list isLoading = true await vm.addRecipe(context, categoryName: selectedCategory.name) isLoading = false } inside ViewModel // bug func list(_ modelContext: ModelContext, categoryName: String) async { recipes.removeAll() let dh: RecipeDataHandler = .init(modelContainer: modelContext.container) let values = await dh.listByName(categoryName: categoryName) for v in values { recipes.append(.init(recipeId: v.recipeId, name: v.name)) } } // works func addRecipe(_ modelContext: ModelContext, categoryName: String) async { isLoading = true defer { isLoading = false } recipes.removeAll() recipes.append(.init(recipeId: "a", name: "Pambazo")) } ModelActor @ModelActor actor RecipeDataHandler { func listByName(categoryName: String) async -> [RecipeData] { var list: [RecipeData] = [] do { let fd = FetchDescriptor<Recipe>(predicate: #Predicate { $0.category.name == categoryName }, sortBy: [SortDescriptor(\Recipe.name)]) let data = try modelContext.fetch(fd) for item in data { let rec: RecipeData = await .init(recipeId: item.recipeId, name: item.name) list.append(rec) } } catch { print("error: \(error.localizedDescription)") } return list } } Recipe is a @Model and RecipeData just a struct. In principle, everything should run on the MainActor, but the inclusion of the ModelActor still leads to this strange behavior. Any idea what the problem might be? Christian
Replies
3
Boosts
0
Views
358
Activity
1w
Non-collapsing title
In the Photos app, the Collections title doesn't collapse into a small inline title when scrolling, unlike a standard inline large title display mode. How is this implemented?
Replies
2
Boosts
0
Views
197
Activity
1w
NavigationSplitView Binding to NavigationSplitViewColumn reset with every NavigationStack path change
I try to create a Navigation that works on iPhone, iPhone Duo and iPad. NavigationSplitView collapses for compact form factors and makes iPhone Duo support much simpler. The Problem is the semantic of the collapse. Switch from detail to sidebar on compact is not a 'back' action in my case. It should have my choosen Icon and has a meaning. So i wanted to control this using the NavigationSpliViewColumn Binding. This does work forward and backward as long as no NavigationStack was used before. But it stops working when you return to the detail root from a Navigation-Action. I left the Backbutton visible so you can test, that it continues to work, when no Navigation-Action preceeded the switch. Here is my Code: import SwiftUI @Observable final class Compass { var path: [Route] init() { self.path = [] } } enum Route: Hashable { case goal } struct ContentView: View { @Environment(\.horizontalSizeClass) private var hsize @State private var compass: Compass = Compass() @State var column: NavigationSplitViewColumn = .detail var body: some View { NavigationSplitView(preferredCompactColumn: $column) { OverviewScreen(column: $column) } detail: { TodayScreen() .toolbar { ToolbarItem(placement: .topBarLeading) { Button("overview", systemImage: "calendar") { self.column = .sidebar } } } } .environment(compass) .onChange(of: column) { old, new in print("column:", old, "→", new) } } } struct OverviewScreen: View { @Binding var column: NavigationSplitViewColumn @Environment(Compass.self) var compass var body: some View { @Bindable var compass = self.compass ScrollView { Text("Overview") .font(.largeTitle) .fontWeight(.heavy) Button("Switch") { self.column = .detail } } } } struct TodayScreen: View { @Environment(Compass.self) var compass var body: some View { @Bindable var compass = self.compass NavigationStack(path: $compass.path) { ScrollView { Text("Today") .font(.largeTitle) .fontWeight(.heavy) Button("Goals programtically", systemImage: "flag.fill") { self.compass.path = [.goal] } NavigationLink(value: Route.goal) { Label("Goal Link", systemImage: "flag.fill") } } .navigationDestination(for: Route.self, destination: self.screen) } } @ContentBuilder func screen(for route: Route) -> some View { switch route { case .goal: Text("Goals") } } } #Preview { ContentView() }This seems unexpected behaviour. If you ask AI the mental model is NavigationSplitViewColumn represents which column is currently visible for the user. That model would be wrong. Also i can't understand why a NavigationStack has to change the Binding? What am i missing here? Is my idea of the programmatic switch not supported? There are other ways to push from compact to your detail column again, but they all have trade-offs or run into other problems. I would appreciate any help here. AI has not understood this and only does surface level work arounds that fix nothing.
Replies
0
Boosts
0
Views
58
Activity
1w
What pattern to use for an iPhone Tabview app
I have an iPhone tab view application that has not been designed for iPad, and I am aiming to add a left-hand bar that summarises some content and keeps visible what is normally a sheet. What pattern would work best for this? At present, I pass the view to another view with a navigation stack containing an arrangement view with the previous view and then the sidebar as a secondary view within it—would that be the appropriate approach?
Topic: UI Frameworks SubTopic: SwiftUI
Replies
3
Boosts
0
Views
427
Activity
1w
Best way to position game touch controls around the iPhone Duo hinge
For a full-screen game with a Metal/Unreal rendering view and a SwiftUI overlay for touch controls, what is the recommended way to keep interactive controls away from the hinge while still allowing the rendered game world to use the full display? Would you recommend querying ReservedRegion in the SwiftUI overlay while allowing the underlying render view to remain edge-to-edge? Also, should control placement respond continuously while the device is being folded, or primarily respond to layout/reserved-region changes once the pose changes?
Topic: UI Frameworks SubTopic: SwiftUI
Replies
1
Boosts
0
Views
111
Activity
1w
iPhone Duo: SwiftUI Layout Differs Between Simulator and Physical Device (Tab Bar Placement and Content Cropping)
Hi everyone, I'm experiencing a significant difference in SwiftUI layout behavior between the iPhone Duo simulator and a physical iPhone Duo. I've already adjusted my layout to work correctly in the simulator, but the same app behaves differently on the actual device. 1. Folded Simulator: The tab bar is positioned on the right side, as expected for iPhone Duo. The view respects the right-side layout, and scroll views extend naturally behind the tab bar, behaving as expected. Physical device: The tab bar appears at the bottom, like a regular iPhone, instead of on the right. The view is also cropped on the right side. 2. Unfolded Simulator: The tab bar and navigation view both appear correctly. Physical device: The tab bar remains at the bottom, even in landscape orientation, instead of using the expected Duo layout. The main content also starts from the bottom of the navigation view, resulting in an incorrect layout. The most confusing part is that the layout works correctly in the simulator but not on the physical device. Has anyone encountered this behavior on a physical iPhone Duo? Could this be related to the iOS version, SDK version, SwiftUI's automatic tab bar adaptation, or a device-specific bug? I'd appreciate any insights, especially from developers who have tested their SwiftUI apps on actual iPhone Duo hardware. Environment: Xcode version: 27.1 iOS SDK: 27.1 Physical device iOS version: 27.2 Thanks!
Replies
1
Boosts
0
Views
128
Activity
1w