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

A Summary of the iPhone Duo Group Lab
Group Labs are a unique opportunity for the community to submit questions directly to a panel of Apple engineers and designers. Here are the highlights from the iPhone Duo Group Labs: How should apps preserve navigation and UI state when switching between the inner and outer displays? Treat display transitions as size-class and trait changes, not a scene disconnect or app termination; your process stays alive. For more information, see Prepare your app for iPhone Duo. For state that must survive a scene disconnect/reconnect, implement stateRestorationActivity(for:) to save an NSUserActivity Restoring your app's state. Do multiple instances of the same app on iPhone Duo share UserDefaults/@AppStorage state? Multiple instances of your app's UI on iPhone Duo behave similarly to multi-window support on iPadOS. To learn more, see Leverage multiple displays and scenes on iPhone Duo. Both UserDefaults and AppStorage are app-wide, not per-window, stores. If a full-screen app on the inner display is closed, does it move to the outer display or get backgrounded? iPhone Duo honors UIRequiresFullScreen and apps adapt in place as the device opens and closes rather than backgrounding. To learn more, watch Prepare your app for iPhone Duo. How should apps preserve state — text input, scroll position, video playback, camera sessions — during hinge angle transitions? For example, when a LazyVGrid's column count changes because the device folds, does SwiftUI preserve scroll position automatically, or should you use scrollPosition(id:)? The system generally preserves text input and scroll position automatically since hinge angle changes are represented as size-class and trait updates, not a scene disconnect or app termination. This applies even to cases like a LazyVGrid column-count change triggered by opening or closing the device — apps typically don't need to manually manage scroll position with scrollPosition(id:anchor:) for this transition. For more info, see Prepare your app for iPhone Duo. How can apps preserve what someone is doing when switching displays or folding/unfolding? Treat this as a resize/trait-change event, not app teardown — your process keeps running as size classes change. See Prepare your app for iPhone Duo to learn more. For scenes that actually disconnect and reconnect, implement stateRestorationActivity(for:) to save an NSUserActivity Restoring your app's state. How does actively playing video behave through the hinge angle animation? The system generally preserves video playback and player position automatically since hinge angle changes are represented as size-class and trait updates, not a scene disconnect or app termination. AVKit will scale and resize the video automatically. If a user folds or unfolds the device mid-checkout, what does the system preserve automatically, and what should the app manage itself to avoid lost input or duplicate requests? When someone opens or closes an iPhone Duo, the system represents this as a size-class and trait collection change, not a scene disconnect or app teardown, so in-memory state like input fields typically persists automatically since the app’s process keeps running. For more info, see Prepare your app for iPhone Duo. How should apps handle the keyboard and text input when the device folds or unfolds while typing? As iPhone Duo folds or unfolds, the available screen geometry and framing change. Ensure your app adopts standard layout controls, containers, and size classes to handle resizability gracefully across all poses. When a text field becomes first responder, the system automatically shows the keyboard and binds its input to the text field. Because the appearance of the keyboard has the potential to obscure portions of your user interface, you should update your interface as needed to ensure that the text field being edited remains visible. Use keyboard notifications such as keyboardWillShowNotification, keyboardWillHideNotification, and keyboardWillChangeFrameNotification to detect the appearance and disappearance of the keyboard and to make necessary changes to your interface layout. To learn more, see UITextField. If someone is typing and closes iPhone Duo, does the keyboard/editing session survive the hinge transition, or does it get a new scene? When a user types and closes iPhone Duo, the active editing session and keyboard do not get a completely new scene. Instead, the app undergoes a dynamic resizing and transitions from the inner display to the compact outer display, maintaining the existing scene and application state. For more info, watch Prepare your app for iPhone Duo.
16
0
7.1k
Sep ’26
macOS 27.2: NSStatusItem tooltip stays on screen, then jumps to the pointer when toolTip changes
Environment: macOS Golden Gate 27.3 (26C5035r) arm64, Apple silicon, one display at 2240×1260 (scaled). Symptom. A tooltip window stays on screen at full opacity after the pointer has left. Sometimes it sits in the middle of the screen, far from the menu bar item it belongs to. Hovering or clicking that menu bar item clears it. I've seen it with seven apps: Syncthing, DriveDx and Private Internet Access (menu bar items), and Google Chrome, Chrome Beta, Opera and iTerm2 (tooltips inside their windows). What I measured (polling CGWindowListCopyWindowInfo, plus sample): The stuck window belongs to the app's own process, at window layer 103, alpha 1.0. The app is idle while it's stuck: its main thread is in mach_msg2_trap in 85–100% of samples. In the Chrome and Opera samples the tooltip is handled by NSToolTipManager (displayToolTip:, mouseEnteredToolTip:inWindow:pointInWindow:, fadeToolTip:). Every tooltip is drawn 19–20 pt below where the pointer was when it was shown, so a mid-screen tooltip was shown while the pointer was there. Syncthing (open source) only sets statusItem.button.toolTip, on the main thread, when its status changes. It has no tracking areas or mouse handling of its own. Reproducible part (Syncthing's menu bar item): Have its tooltip stuck. This happens on its own from time to time. I can't trigger it on demand. Leave the pointer anywhere away from the menu bar and change a file in a synced folder, so that Syncthing updates its status and sets a new toolTip. Result: the stuck tooltip window (same window number) moves to 19–20 pt below the current pointer position and stays there. It happened twice in a row, 25 seconds apart, at two different pointer positions. Control: with nothing stuck, 9 such changes (some local, some synced in from another machine) showed no tooltip anywhere. Expected: a tooltip is only shown while the pointer is over its view, and a toolTip change while the pointer is elsewhere shows nothing. So setting toolTip doesn't show a tooltip on its own, it only moves one that is already stuck. I don't know what leaves it stuck in the first place. Possibly related: FB23329983 (status item buttons not getting hover events on macOS 27 betas, reported fixed in beta 5), from this thread. Screenshots of sample tooltips attached.
Topic: UI Frameworks SubTopic: AppKit Tags:
3
0
309
3h
Battery usage timeline graph shows incorrect time labels in macOS 27
Description: The time scale values on the battery usage curve in macOS 27 are displayed incorrectly. The screenshot timestamp is 14:39:11, October 20. Under the "Last 24 Hours" tab for Battery Level and Screen On Time charts, the timeline shows usage extending past 21:00 on October 20. This timestamp does not match the actual current time. It appears the timeline axis failed to shift correctly as time progresses. For comparison: a reference screenshot captured on macOS 26 at 09:30, August 8. Its battery usage timeline rendered correctly. The bottom time span covered August 7 to August 8, which is the expected and proper display behavior. This bug only exists in macOS 27’s battery usage chart. The older macOS 26 implementation works correctly. Device: MacBook Air M5 macOS version: macOS 27.2 RC
Topic: UI Frameworks SubTopic: SwiftUI
1
0
168
14h
Launch screen not refreshed after app update: is clearing Library/SplashBoard supported?
We're adding an option to our Unity SDK that gives a game a native launch screen: a launch storyboard (set through UILaunchStoryboardName) showing a full-screen image from an asset catalog. What we see On a clean install, the new launch screen shows as expected. When the same device installs an update over the existing app (tested through TestFlight), the previous launch screen keeps showing. Launching the app several times does not change it. Deleting the app, restarting the device and reinstalling shows the new launch screen straight away. We checked the build itself: the compiled storyboard, the image in Assets.car and the Info.plist keys are all correct, so this looks like the system's launch screen snapshot cache. We assume App Store updates behave the same way. What we're considering On the first launch after an update, the app would delete the cached launch screen snapshots in its own container (Library/SplashBoard), so the system regenerates them and the new launch screen shows on the next launch. This only uses public file APIs inside the app's own sandbox. But Library/SplashBoard is not documented anywhere, so we'd rather ask before shipping it. Questions Is deleting Library/SplashBoard from the app's own container a supported or acceptable practice, or could it cause problems (with the system, or in a future iOS version)? Is there a supported way to make iOS refresh a cached launch screen after an app update? If not, is the expected behaviour simply that the system refreshes the snapshot at some point? Is it documented when that happens (for example after a reboot, or after a certain time)? If clearing the folder isn't recommended, we won't ship it. Updating players would just keep the old launch screen until iOS refreshes it. Thanks!
1
0
167
15h
macOS 27.2: external monitor on a USB-C to HDMI adapter flickers, shows as "12 inch Display" at 1280x720, all resolutions refused (empty EDID)
Since I updated from macOS 27.0.1 to 27.2 (26B123), my second monitor stopped working on a Mac mini M4 Pro. It is a Dell SE2726HG on a USB-C to HDMI adapter. My LG on the built-in HDMI port still works. Symptoms: The Dell flickers. It disconnects and reconnects about once per second. System Settings shows it as "Display", 12 inch, 1280x720 at 50 Hz. Every resolution change is refused, also for the other monitor. A restart, a replug, or a lower refresh rate on the other monitor does not help. What the logs show: macOS cannot read the monitor's EDID through the adapter. IOAVServiceCopyEDID returns 0xe00002c9 (internal error), and the framebuffer has an all-zero EDID. Without an EDID, the kernel gives the display no display pipe: "AED: validate_or_set_ex: fb 2 rejecting request, exceeds full dual-pipe allocation (w 1280 vs 0 ...)" and "skipping display with null info". In 47 minutes, the log had 379 hotplug "out" events. Workaround (no extra hardware, no paid app): I injected a normal 1920x1080 EDID at runtime with the private IOKit call IOAVServiceSetVirtualEDIDMode(service, 1, edid), then IODPDeviceSetUpdated(device, 1). The monitor then comes up with its correct name at 1920x1080, with zero disconnects. The override is lost on reboot, sleep, or replug, so a LaunchAgent re-applies it every 5 seconds when the EDID read fails. This is the same approach as these projects: https://gist.github.com/danii1/99fa5f849a4d42807418259abfbf03d5 https://github.com/owomocha/macos-360hz-unlock BetterDisplay Pro can also apply a custom EDID.
Topic: UI Frameworks SubTopic: General
2
1
354
18h
What is the recommended way to render a divider line in a NSTextView?
I would like to render a divider line in a NSTextView (like the <div> HTML item) on macOS 10.13 or later. I use Objective-C. I've searched for solutions and it looks like the recommended solution is to use a NSTextAttachmentCell. There was supposedly an example provided on the cocoa-dev mailing list but the archives for this useful mailing list are gone. The issue I'm observing with the NSTextAttachmentCell solution is that it is working almost well with a simple NSTextView example but when used in a more complex application, the rendering of the divider is still fine but there's a huge vertical gap between the divider and the text below the divider. The online documentation for the NSTextAttachmentCell class is not really helpful (and contains typos: "With the exceptions of cellBaselineOffset, attachment, and attachment, all of these methods are implemented by the NSCell class.For general information on text attachments, " -> "attachment" twice, no space between "class." and "For general"). Here's the simple code I'm currently testing for the attachment cell: @implementationMyDividerTextAttachmentCell - (NSRect)cellFrameForTextContainer:(NSTextContainer *)textContainer proposedLineFragment:(NSRect)lineFrag glyphPosition:(NSPoint)position characterIndex:(NSUInteger)charIndex { return NSMakeRect(lineFrag.origin.x, lineFrag.origin.y, textContainer.size.width, 10); } - (void)drawWithFrame:(NSRect)cellFrame inView:(nullable NSView *)controlView { [[NSColor darkGrayColor] setStroke]; [NSBezierPath strokeLineFromPoint:NSMakePoint(0, NSMidY(cellFrame)) toPoint:NSMakePoint(NSMaxX(cellFrame), NSMidY(cellFrame))]; }[Q] Is there an obvious reason why there would be a huge gap (think 200 pixels/points) below the divider? What is the recommended way to render a divider line in a NSTextView if it's not NSTextAttachmentCell.
4
0
338
1d
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
336
1d
iOS 27b3 SDK: iOS App on Mac crashes on UISearchBar focus
Our app crashes when compiled with the iOS 27 beta 3 SDK and run as an iOS app on Mac, on both macOS 26 and macOS 27, as soon as a UISearchBar receives focus. The crash is due to this exception: *** Assertion failure in BOOL _screenBasedFocusUnsupported(void)(), UIScreen.m:3.725 Accessing the focus system through UIScreen is no longer supported. ( 0 CoreFoundation 0x000000018bea31c0 __exceptionPreprocess + 176 1 libobjc.A.dylib 0x000000018b91e91c objc_exception_throw + 88 2 Foundation 0x000000018e092644 -[NSMutableDictionary(NSMutableDictionary) initWithContentsOfFile:] + 0 3 UIKitCore 0x00000001c5dae8ec _screenBasedFocusUnsupported + 272 4 UIKitCore 0x00000001c5dae960 -[UIScreen _preferredFocusedWindow] + 24 5 UIKitCore 0x00000001c4ea3a60 -[UIScreen _mainSceneReferenceBounds] + 200 6 UIKitCore 0x00000001c4ea3914 -[UIScreen _mainSceneBoundsForInterfaceOrientation:] + 40 7 UIKitCore 0x00000001c5708134 +[UINavigationBar defaultSizeForOrientation:] + 76 8 UIKitCore 0x00000001c6222c88 -[_UISearchPresentationController _layoutPresentationWithSize:transitionCoordinator:] + 704 9 UIKitCore 0x00000001c622296c -[_UISearchPresentationController containerViewWillLayoutSubviews] + 84 10 UIKitCore 0x00000001c549304c block_destroy_helper.13 + 25112 11 UIKitCore 0x00000001c549344c block_destroy_helper.13 + 26136 12 UIKitCore 0x00000001c4ea26a8 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 1648 13 QuartzCore 0x0000000196103dbc _ZN2CA5Layer15perform_update_EPS0_P7CALayerjNS_17LayerUpdateReasonEPNS_11TransactionE + 460 14 QuartzCore 0x000000019610390c _ZN2CA5Layer17update_if_needed_EPNS_11TransactionENS_17LayerUpdateReasonE + 692 15 QuartzCore 0x0000000196035d2c _ZN2CA7Context18commit_transactionEPNS_11TransactionEdPd + 608 16 QuartzCore 0x0000000195e69520 _ZN2CA11Transaction6commitEv + 652 17 AppKit 0x0000000190fe116c __37+[NSDisplayCycle currentDisplayCycle]_block_invoke.7 + 44 18 CoreFoundation 0x000000018be34ad0 __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__ + 28 19 CoreFoundation 0x000000018be34a10 __CFRunLoopDoBlocks + 396 20 CoreFoundation 0x000000018be33e54 __CFRunLoopRun + 2356 21 CoreFoundation 0x000000018bf06234 _CFRunLoopRunSpecificWithOptions + 532 22 HIToolbox 0x0000000198c1f560 RunCurrentEventLoopInMode + 320 23 HIToolbox 0x0000000198c228bc ReceiveNextEventCommon + 488 24 HIToolbox 0x0000000198dac14c _BlockUntilNextEventMatchingListInMode + 48 25 AppKit 0x00000001909163d0 _DPSBlockUntilNextEventMatchingListInMode + 228 26 AppKit 0x000000019026a084 _DPSNextEvent + 576 27 AppKit 0x0000000190dff96c -[NSApplication(NSEventRouting) _nextEventMatchingEventMask:untilDate:inMode:dequeue:] + 688 28 AppKit 0x0000000190dff678 -[NSApplication(NSEventRouting) nextEventMatchingMask:untilDate:inMode:dequeue:] + 72 29 AppKit 0x000000019025d13c -[NSApplication run] + 368 30 AppKit 0x00000001902357b0 NSApplicationMain + 880 31 AppKit 0x000000019047c958 +[NSWindow _savedFrameFromString:] + 0 32 UIKitMacHelper 0x00000001aa2651bc UINSApplicationMain + 972 33 UIKitCore 0x00000001c4e1aed4 UIApplicationMain + 144 34 UIKitCore 0x00000001c548bda0 block_destroy_helper.31 + 8880 35 DigitalConcertHall.debug.dylib 0x0000000106e41bd8 $sSo21UIApplicationDelegateP5UIKitE4mainyyFZ + 128 36 DigitalConcertHall.debug.dylib 0x0000000106e41b4c $s18DigitalConcertHall11AppDelegateC5$mainyyFZ + 32 37 DigitalConcertHall.debug.dylib 0x0000000106e4afc0 __debug_main_executable_dylib_entry_point + 28 38 dyld 0x000000018b9ac4e4 start + 6992 ) I could not test with the iOS 27 beta 4 SDK due to this blocking issue: https://developer.apple.com/forums/thread/839012 However, when I tried to set up a simple sample project, I could not reproduce the issue. Does anybody know what might be causing this? I filed feedback FB24201508
7
2
1.8k
1d
Various menu bar NSStatusItem issues with macOS 27
It seems like macOS 27 beta 2 has some issues with NSStatusItem buttons added to the menu bar - this creates difficulties for some menu bar extra apps. NSStatusItem buttons does not receive mouse hover/movement events - FB23329983 On macOS 27, views inside an NSStatusItem button no longer receive hover or mouse-movement events. The same code works correctly on macOS 26. What I tried: An NSTrackingArea attached to a subview of NSStatusBarButton An NSTrackingArea attached directly to the status-bar button Replacing NSStatusItem.view with a custom view Embedding an NSHostingView and using SwiftUI onHover/onContinuousHover NSStatusItem button highlight cannot be set programmatically. - FB23330269 The following code no longer has any effect (does not provide the highlight capsule): NSStatusItem.button?.highlight(true) NSStatusItem window occlusionState no longer reflects hidden menu bar visibility - FB23349447 The following no longer works: statusItem.button?.window?.occlusionState.contains(.visible) These changes may be related to some of the touch related changes or maybe it's about how menu items are now seemingly more "managed" in a way that their position, visibility may change in a way that is transparent/undetectable to the app.
7
2
1.5k
2d
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
259
2d
HiraginoSans-W4/W5 availability diverges between iOS 16.5.1 and iOS 18.0.1: UIFont(name:) returns nil, XIB labels fall back to Helvetica
Background Our app previously bundled ヒラギノ角ゴシック W4.ttc and W5.ttc via UIAppFonts. App Store review flagged them under ITMS-91198 as Apple-provided fonts. We removed the bundled .ttc files and need to verify the runtime font-resolution behavior before shipping. Case C below shows the original state (with .ttc present) for comparison. Environment Same app, same code, same XIB, physical devices only. Tested OS: iOS 16.5.1 (two builds: with and without bundled .ttc) and iOS 18.0.1 (without bundled .ttc). Xcode 16.x. How to read the logs Each log has three sections: SYSTEM HIRAGINO SANS — UIFont.fontNames(forFamilyName: "Hiragino Sans"), i.e. what the OS itself provides. RAW UIFont(name:) — UIFont(name: "HiraginoSans-W4", size: 16) etc. This is the code path our App.Font wrapper uses. XIB LABEL RESOLVED — four UILabels whose XIB fontDescription specifies HiraginoSans-W3/W4/W5/W6 respectively. resolved= is label.font.fontName at runtime. Case A — iOS 18.0.1, physical device, bundled .ttc removed ===== ENV ===== systemVersion : 18.0.1 target : Physical Device ===== SYSTEM HIRAGINO SANS ===== HiraginoSans-W3 HiraginoSans-W4 HiraginoSans-W5 HiraginoSans-W6 HiraginoSans-W7 HiraginoSans-W8 ===== RAW UIFont(name:) ===== HiraginoSans-W3 OK family=Hiragino Sans HiraginoSans-W4 OK family=Hiragino Sans HiraginoSans-W5 OK family=Hiragino Sans HiraginoSans-W6 OK family=Hiragino Sans ===== XIB LABEL RESOLVED ===== W3Lab xib=HiraginoSans-W3 resolved=HiraginoSans-W3 family=Hiragino Sans W4Lab xib=HiraginoSans-W4 resolved=HiraginoSans-W4 family=Hiragino Sans W5Lab xib=HiraginoSans-W5 resolved=HiraginoSans-W5 family=Hiragino Sans W6Lab xib=HiraginoSans-W6 resolved=HiraginoSans-W6 family=Hiragino Sans ===== END =====Case B — iOS 16.5.1, physical device, bundled .ttc removed ===== ENV ===== systemVersion : 16.5.1 target : Physical Device ===== SYSTEM HIRAGINO SANS ===== HiraginoSans-W3 HiraginoSans-W6 HiraginoSans-W7 ===== RAW UIFont(name:) ===== HiraginoSans-W3 OK family=Hiragino Sans HiraginoSans-W4 nil HiraginoSans-W5 nil HiraginoSans-W6 OK family=Hiragino Sans ===== XIB LABEL RESOLVED ===== W3Lab xib=HiraginoSans-W3 resolved=HiraginoSans-W3 family=Hiragino Sans W4Lab xib=HiraginoSans-W4 resolved=Helvetica family=Helvetica W5Lab xib=HiraginoSans-W5 resolved=Helvetica family=Helvetica W6Lab xib=HiraginoSans-W6 resolved=HiraginoSans-W6 family=Hiragino Sans ===== END =====Case C — iOS 16.5.1, physical device, bundled .ttc present (original state) ===== ENV ===== systemVersion : 16.5.1 target : Physical Device ===== SYSTEM HIRAGINO SANS ===== HiraginoSans-W3 HiraginoSans-W4 HiraginoSans-W5 HiraginoSans-W6 HiraginoSans-W7 ===== RAW UIFont(name:) ===== HiraginoSans-W3 OK family=Hiragino Sans HiraginoSans-W4 OK family=Hiragino Sans HiraginoSans-W5 OK family=Hiragino Sans HiraginoSans-W6 OK family=Hiragino Sans ===== XIB LABEL RESOLVED ===== W3Lab xib=HiraginoSans-W3 resolved=HiraginoSans-W3 family=Hiragino Sans W4Lab xib=HiraginoSans-W4 resolved=HiraginoSans-W4 family=Hiragino Sans W5Lab xib=HiraginoSans-W5 resolved=HiraginoSans-W5 family=Hiragino Sans W6Lab xib=HiraginoSans-W6 resolved=HiraginoSans-W6 family=Hiragino Sans ===== END =====Observations Comparing B and C (same OS, only .ttc presence differs): removing the bundled .ttc removes HiraginoSans-W4/W5 from the system font list, makes UIFont(name:) return nil for them, and makes XIB labels naming them fall back to Helvetica — not SF, not the nearest weight in the same family. Comparing B and A (same .ttc state, only OS differs): iOS 18.0.1 ships HiraginoSans-W3–W8 in the system, so removing the bundled .ttc has no effect there. Question 1 — System font inventory by OS version Is there an official, versioned list of system-provided fonts (PostScript names) per iOS release? We need to determine which Hiragino Sans weights are available on a given OS at runtime, without hard-coding assumptions. Our observations show that iOS 16.5.1 does not provide HiraginoSans-W4/W5 in the system font set, while iOS 18.0.1 provides W3–W8. If no per-version official list exists, is UIFont.familyNames / UIFont.fontNames(forFamilyName:) the recommended runtime enumeration method? Or is there a documented recommendation to avoid relying on specific PostScript names across OS versions? Question 2 — XIB fontDescription fallback rule When a UILabel's XIB fontDescription specifies a font PostScript name that is not available at runtime (e.g. HiraginoSans-W4 on iOS 16.5.1 after removing the bundled .ttc), we observe UIKit falls back to Helvetica — not SF, not the nearest available weight in the same family. Is this fallback rule documented? Is it stable across iOS versions, or should we treat the fallback target as unspecified? If the fallback target cannot be relied upon, what is the recommended approach for XIB-based layouts that must not render with an unexpected font? Must every such label be re-assigned in code after awakeFromNib / viewDidLoad? Or is there a supported way to declare a fallback chain in Interface Builder?
0
0
45
2d
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
378
2d
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
373
2d
Is a scene always connected when a UIScene app is launched in the background (silent push, BGTask, background URLSession)?
Hello, We are migrating a large UIKit app from the app-delegate lifecycle to the UIScene lifecycle. (Building with Xcode 27 / iOS 27 SDK, our non-scene app crashes at launch with EXC_BREAKPOINT in _UIApplicationEvaluateRuntimeIssueForNoSceneLifecycleAdoption.) Our startup work runs from application(_:didFinishLaunchingWithOptions:), and we need to know what is guaranteed for background launches. Observed (iPhone 15 Pro, iOS 27.2, app built with Xcode 26.3; also iOS 17.5 simulator): Non-scene build, launched by a content-available push: launchOptions contained UIApplicationLaunchOptionsRemoteNotificationKey. applicationDidEnterBackground was not called during the background run. Non-scene build, launched by a BGProcessingTask: launchOptions empty. applicationDidEnterBackground was not called; the first lifecycle callback was applicationWillEnterForeground when the user opened the app 8 minutes later. Scene build, launched by a BGProcessingTask and by a content-available push: scene(_:willConnectTo:options:) was called 0.15-0.2 s after didFinishLaunching while applicationState == .background (activationState .unattached). connectionOptions had no notificationResponse, URL or shortcut item. In the push launch, scene(_:willConnectTo:options:) was called 37 ms before application(_:didReceiveRemoteNotification:fetchCompletionHandler:). sceneWillEnterForeground / sceneDidEnterBackground were not called before the process was suspended. Scene build, background URLSession relaunch (simulator): the scene also connected right after didFinishLaunching in the background, 6 ms before application(_:handleEventsForBackgroundURLSession:completionHandler:). Question: For a UIScene-based app that the system launches directly into the background (content-available push, BGTaskScheduler task, background URLSession events), is it guaranteed that UIKit connects a scene session (scene(_:willConnectTo:options:)) before the user opens the app, or can a background launch run with no connected scene until the app comes to the foreground? In the same launches, can sceneDidEnterBackground (or applicationDidEnterBackground in a non-scene app) be called for a process that never entered the foreground? Please point us to documentation that describes the guaranteed callbacks and their order for background launches. Thank you.
Topic: UI Frameworks SubTopic: UIKit
0
0
76
2d
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
59
3d
Persistent scroll stutter on iPhone 17 Pro Max, 18 Pro Max and 18 Pro (iOS 27.2), also on Apple Store demo units
Affected devices (all show the same problem): 1x iPhone 17 Pro Max 2x iPhone 18 Pro Max 1x iPhone 18 Pro Many demo iPhones at several Apple Stores Current iOS version: 27.2 Issue: Vertical scrolling inside apps frequently stutters and drops frames. It happens in many, many apps, including Apple's own App Store and Apple Store apps. During a normal flick-and-decelerate scroll, the content repeatedly freezes for one or more frames and then jumps forward. Because this reproduces on four of my own devices and on many Apple Store demo units, I believe it is a widespread, system-level issue, not a defect of a single device or my settings. Impact: I have been living with this for more than six months. I use my iPhone heavily every day, and the constant stutter has made using it genuinely distressing. Everything else about iPhone feels excellent, which makes this problem even harder to accept. Steps to reproduce: Open the App Store app (or almost any app with a scrolling list). Scroll with a normal flick and let it decelerate. Observe repeated hitches during the scroll. Measurements: I filmed the screen with a second iPhone at 4K 120 fps and measured content movement frame by frame: iPhone 18 Pro Max, third-party video feed: about 4 hitches per second of scrolling, about 4% of frames dropped, mostly single-frame drops. iPhone 18 Pro Max, third-party social app list: about 11 hitches per second, about 12% of frames dropped, at a regular rhythm every 6-8 frames. About a third of the stalls last 2-3 frames, and the content does not catch up afterwards. iPhone 17 Pro Max, third-party comment list: about 5 hitches per second, about 8% of frames dropped, including several full freezes of 50-75 ms. Expected: Smooth 120 Hz scrolling, as ProMotion is designed to deliver. Is Apple aware of this issue? I am happy to provide videos, frame-by-frame data, or sysdiagnose logs.
3
1
191
3d
On iPhone Duo in landscape, the tab bar isn't visible.
Hi, I have an app with a specific view hierarchy, and when I tested it on an iPhone Duo in landscape, I noticed an issue with how the tab bar is displayed or, rather, how it isn’t displayed. On iPhone Duo in landscape and on the main screen, the tab bar for a `UITabBarController` pushed onto a `UINavigationController` (itself inside another `UITabBarController`) isn’t visible. I've tested it in both UIKit and SwiftUI, and the issue is present in both. I could only get the tab bar to appear by presenting the view modally instead of pushing it, but that isn’t a viable solution for my app. For example: ``` UIWindow └─ RootTabBarController (UITabBarController) └─ UINavigationController (tab 2) ├─ FirstTabViewController (root) └─ push └─ NestedTabBarController (UITabBarController) ├─ ItemListViewController (UITableView) ├─ ItemListViewController (UITableView) └─ ItemListViewController (UITableView) ``` I've put together a simplified [demo repo](https://github.com/janossuta/iphone-duo-issue-demo/tree/main) that shows the problem. I've attached two images showing that the tabs disappear in landscape mode and are visible in portrait mode. Can we preserve the original functionality?
Topic: UI Frameworks SubTopic: General
0
0
35
3d
Cannot move window by its background (macOS 27)
Hi, My app (SmashTunes) can display a floating window with artwork of a music track that is displaying. It does for over a decade in multiple versions of macOS. I do this by calling window?.isMovableByWindowBackground = true. This stopped working under macOS 27. I've read some reports of others not being able to move windows. It should supposedly have been fixed in macOS 27.2, but it is not. Has anyone on this forum run into the same problem, or know of a different way to move windows around on the screen? When I add add a titlebar, I can drag it by the titlebar, but that is not really an option for my use case.
Topic: UI Frameworks SubTopic: General
1
0
115
4d
A Summary of the iPhone Duo Group Lab
Group Labs are a unique opportunity for the community to submit questions directly to a panel of Apple engineers and designers. Here are the highlights from the iPhone Duo Group Labs: How should apps preserve navigation and UI state when switching between the inner and outer displays? Treat display transitions as size-class and trait changes, not a scene disconnect or app termination; your process stays alive. For more information, see Prepare your app for iPhone Duo. For state that must survive a scene disconnect/reconnect, implement stateRestorationActivity(for:) to save an NSUserActivity Restoring your app's state. Do multiple instances of the same app on iPhone Duo share UserDefaults/@AppStorage state? Multiple instances of your app's UI on iPhone Duo behave similarly to multi-window support on iPadOS. To learn more, see Leverage multiple displays and scenes on iPhone Duo. Both UserDefaults and AppStorage are app-wide, not per-window, stores. If a full-screen app on the inner display is closed, does it move to the outer display or get backgrounded? iPhone Duo honors UIRequiresFullScreen and apps adapt in place as the device opens and closes rather than backgrounding. To learn more, watch Prepare your app for iPhone Duo. How should apps preserve state — text input, scroll position, video playback, camera sessions — during hinge angle transitions? For example, when a LazyVGrid's column count changes because the device folds, does SwiftUI preserve scroll position automatically, or should you use scrollPosition(id:)? The system generally preserves text input and scroll position automatically since hinge angle changes are represented as size-class and trait updates, not a scene disconnect or app termination. This applies even to cases like a LazyVGrid column-count change triggered by opening or closing the device — apps typically don't need to manually manage scroll position with scrollPosition(id:anchor:) for this transition. For more info, see Prepare your app for iPhone Duo. How can apps preserve what someone is doing when switching displays or folding/unfolding? Treat this as a resize/trait-change event, not app teardown — your process keeps running as size classes change. See Prepare your app for iPhone Duo to learn more. For scenes that actually disconnect and reconnect, implement stateRestorationActivity(for:) to save an NSUserActivity Restoring your app's state. How does actively playing video behave through the hinge angle animation? The system generally preserves video playback and player position automatically since hinge angle changes are represented as size-class and trait updates, not a scene disconnect or app termination. AVKit will scale and resize the video automatically. If a user folds or unfolds the device mid-checkout, what does the system preserve automatically, and what should the app manage itself to avoid lost input or duplicate requests? When someone opens or closes an iPhone Duo, the system represents this as a size-class and trait collection change, not a scene disconnect or app teardown, so in-memory state like input fields typically persists automatically since the app’s process keeps running. For more info, see Prepare your app for iPhone Duo. How should apps handle the keyboard and text input when the device folds or unfolds while typing? As iPhone Duo folds or unfolds, the available screen geometry and framing change. Ensure your app adopts standard layout controls, containers, and size classes to handle resizability gracefully across all poses. When a text field becomes first responder, the system automatically shows the keyboard and binds its input to the text field. Because the appearance of the keyboard has the potential to obscure portions of your user interface, you should update your interface as needed to ensure that the text field being edited remains visible. Use keyboard notifications such as keyboardWillShowNotification, keyboardWillHideNotification, and keyboardWillChangeFrameNotification to detect the appearance and disappearance of the keyboard and to make necessary changes to your interface layout. To learn more, see UITextField. If someone is typing and closes iPhone Duo, does the keyboard/editing session survive the hinge transition, or does it get a new scene? When a user types and closes iPhone Duo, the active editing session and keyboard do not get a completely new scene. Instead, the app undergoes a dynamic resizing and transitions from the inner display to the compact outer display, maintaining the existing scene and application state. For more info, watch Prepare your app for iPhone Duo.
Replies
16
Boosts
0
Views
7.1k
Activity
Sep ’26
macOS 27.2: NSStatusItem tooltip stays on screen, then jumps to the pointer when toolTip changes
Environment: macOS Golden Gate 27.3 (26C5035r) arm64, Apple silicon, one display at 2240×1260 (scaled). Symptom. A tooltip window stays on screen at full opacity after the pointer has left. Sometimes it sits in the middle of the screen, far from the menu bar item it belongs to. Hovering or clicking that menu bar item clears it. I've seen it with seven apps: Syncthing, DriveDx and Private Internet Access (menu bar items), and Google Chrome, Chrome Beta, Opera and iTerm2 (tooltips inside their windows). What I measured (polling CGWindowListCopyWindowInfo, plus sample): The stuck window belongs to the app's own process, at window layer 103, alpha 1.0. The app is idle while it's stuck: its main thread is in mach_msg2_trap in 85–100% of samples. In the Chrome and Opera samples the tooltip is handled by NSToolTipManager (displayToolTip:, mouseEnteredToolTip:inWindow:pointInWindow:, fadeToolTip:). Every tooltip is drawn 19–20 pt below where the pointer was when it was shown, so a mid-screen tooltip was shown while the pointer was there. Syncthing (open source) only sets statusItem.button.toolTip, on the main thread, when its status changes. It has no tracking areas or mouse handling of its own. Reproducible part (Syncthing's menu bar item): Have its tooltip stuck. This happens on its own from time to time. I can't trigger it on demand. Leave the pointer anywhere away from the menu bar and change a file in a synced folder, so that Syncthing updates its status and sets a new toolTip. Result: the stuck tooltip window (same window number) moves to 19–20 pt below the current pointer position and stays there. It happened twice in a row, 25 seconds apart, at two different pointer positions. Control: with nothing stuck, 9 such changes (some local, some synced in from another machine) showed no tooltip anywhere. Expected: a tooltip is only shown while the pointer is over its view, and a toolTip change while the pointer is elsewhere shows nothing. So setting toolTip doesn't show a tooltip on its own, it only moves one that is already stuck. I don't know what leaves it stuck in the first place. Possibly related: FB23329983 (status item buttons not getting hover events on macOS 27 betas, reported fixed in beta 5), from this thread. Screenshots of sample tooltips attached.
Topic: UI Frameworks SubTopic: AppKit Tags:
Replies
3
Boosts
0
Views
309
Activity
3h
is NSTextInputClient safe?
is NSTextInputClient safe? I have several apps that has autofill (app name) activity due to NSTextInputClient. I am wondering if my app has this activity will it be submittable to the app store?
Replies
1
Boosts
0
Views
186
Activity
13h
Battery usage timeline graph shows incorrect time labels in macOS 27
Description: The time scale values on the battery usage curve in macOS 27 are displayed incorrectly. The screenshot timestamp is 14:39:11, October 20. Under the "Last 24 Hours" tab for Battery Level and Screen On Time charts, the timeline shows usage extending past 21:00 on October 20. This timestamp does not match the actual current time. It appears the timeline axis failed to shift correctly as time progresses. For comparison: a reference screenshot captured on macOS 26 at 09:30, August 8. Its battery usage timeline rendered correctly. The bottom time span covered August 7 to August 8, which is the expected and proper display behavior. This bug only exists in macOS 27’s battery usage chart. The older macOS 26 implementation works correctly. Device: MacBook Air M5 macOS version: macOS 27.2 RC
Topic: UI Frameworks SubTopic: SwiftUI
Replies
1
Boosts
0
Views
168
Activity
14h
Launch screen not refreshed after app update: is clearing Library/SplashBoard supported?
We're adding an option to our Unity SDK that gives a game a native launch screen: a launch storyboard (set through UILaunchStoryboardName) showing a full-screen image from an asset catalog. What we see On a clean install, the new launch screen shows as expected. When the same device installs an update over the existing app (tested through TestFlight), the previous launch screen keeps showing. Launching the app several times does not change it. Deleting the app, restarting the device and reinstalling shows the new launch screen straight away. We checked the build itself: the compiled storyboard, the image in Assets.car and the Info.plist keys are all correct, so this looks like the system's launch screen snapshot cache. We assume App Store updates behave the same way. What we're considering On the first launch after an update, the app would delete the cached launch screen snapshots in its own container (Library/SplashBoard), so the system regenerates them and the new launch screen shows on the next launch. This only uses public file APIs inside the app's own sandbox. But Library/SplashBoard is not documented anywhere, so we'd rather ask before shipping it. Questions Is deleting Library/SplashBoard from the app's own container a supported or acceptable practice, or could it cause problems (with the system, or in a future iOS version)? Is there a supported way to make iOS refresh a cached launch screen after an app update? If not, is the expected behaviour simply that the system refreshes the snapshot at some point? Is it documented when that happens (for example after a reboot, or after a certain time)? If clearing the folder isn't recommended, we won't ship it. Updating players would just keep the old launch screen until iOS refreshes it. Thanks!
Replies
1
Boosts
0
Views
167
Activity
15h
macOS 27.2: external monitor on a USB-C to HDMI adapter flickers, shows as "12 inch Display" at 1280x720, all resolutions refused (empty EDID)
Since I updated from macOS 27.0.1 to 27.2 (26B123), my second monitor stopped working on a Mac mini M4 Pro. It is a Dell SE2726HG on a USB-C to HDMI adapter. My LG on the built-in HDMI port still works. Symptoms: The Dell flickers. It disconnects and reconnects about once per second. System Settings shows it as "Display", 12 inch, 1280x720 at 50 Hz. Every resolution change is refused, also for the other monitor. A restart, a replug, or a lower refresh rate on the other monitor does not help. What the logs show: macOS cannot read the monitor's EDID through the adapter. IOAVServiceCopyEDID returns 0xe00002c9 (internal error), and the framebuffer has an all-zero EDID. Without an EDID, the kernel gives the display no display pipe: "AED: validate_or_set_ex: fb 2 rejecting request, exceeds full dual-pipe allocation (w 1280 vs 0 ...)" and "skipping display with null info". In 47 minutes, the log had 379 hotplug "out" events. Workaround (no extra hardware, no paid app): I injected a normal 1920x1080 EDID at runtime with the private IOKit call IOAVServiceSetVirtualEDIDMode(service, 1, edid), then IODPDeviceSetUpdated(device, 1). The monitor then comes up with its correct name at 1920x1080, with zero disconnects. The override is lost on reboot, sleep, or replug, so a LaunchAgent re-applies it every 5 seconds when the EDID read fails. This is the same approach as these projects: https://gist.github.com/danii1/99fa5f849a4d42807418259abfbf03d5 https://github.com/owomocha/macos-360hz-unlock BetterDisplay Pro can also apply a custom EDID.
Topic: UI Frameworks SubTopic: General
Replies
2
Boosts
1
Views
354
Activity
18h
What is the recommended way to render a divider line in a NSTextView?
I would like to render a divider line in a NSTextView (like the <div> HTML item) on macOS 10.13 or later. I use Objective-C. I've searched for solutions and it looks like the recommended solution is to use a NSTextAttachmentCell. There was supposedly an example provided on the cocoa-dev mailing list but the archives for this useful mailing list are gone. The issue I'm observing with the NSTextAttachmentCell solution is that it is working almost well with a simple NSTextView example but when used in a more complex application, the rendering of the divider is still fine but there's a huge vertical gap between the divider and the text below the divider. The online documentation for the NSTextAttachmentCell class is not really helpful (and contains typos: "With the exceptions of cellBaselineOffset, attachment, and attachment, all of these methods are implemented by the NSCell class.For general information on text attachments, " -> "attachment" twice, no space between "class." and "For general"). Here's the simple code I'm currently testing for the attachment cell: @implementationMyDividerTextAttachmentCell - (NSRect)cellFrameForTextContainer:(NSTextContainer *)textContainer proposedLineFragment:(NSRect)lineFrag glyphPosition:(NSPoint)position characterIndex:(NSUInteger)charIndex { return NSMakeRect(lineFrag.origin.x, lineFrag.origin.y, textContainer.size.width, 10); } - (void)drawWithFrame:(NSRect)cellFrame inView:(nullable NSView *)controlView { [[NSColor darkGrayColor] setStroke]; [NSBezierPath strokeLineFromPoint:NSMakePoint(0, NSMidY(cellFrame)) toPoint:NSMakePoint(NSMaxX(cellFrame), NSMidY(cellFrame))]; }[Q] Is there an obvious reason why there would be a huge gap (think 200 pixels/points) below the divider? What is the recommended way to render a divider line in a NSTextView if it's not NSTextAttachmentCell.
Replies
4
Boosts
0
Views
338
Activity
1d
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
336
Activity
1d
iOS 27b3 SDK: iOS App on Mac crashes on UISearchBar focus
Our app crashes when compiled with the iOS 27 beta 3 SDK and run as an iOS app on Mac, on both macOS 26 and macOS 27, as soon as a UISearchBar receives focus. The crash is due to this exception: *** Assertion failure in BOOL _screenBasedFocusUnsupported(void)(), UIScreen.m:3.725 Accessing the focus system through UIScreen is no longer supported. ( 0 CoreFoundation 0x000000018bea31c0 __exceptionPreprocess + 176 1 libobjc.A.dylib 0x000000018b91e91c objc_exception_throw + 88 2 Foundation 0x000000018e092644 -[NSMutableDictionary(NSMutableDictionary) initWithContentsOfFile:] + 0 3 UIKitCore 0x00000001c5dae8ec _screenBasedFocusUnsupported + 272 4 UIKitCore 0x00000001c5dae960 -[UIScreen _preferredFocusedWindow] + 24 5 UIKitCore 0x00000001c4ea3a60 -[UIScreen _mainSceneReferenceBounds] + 200 6 UIKitCore 0x00000001c4ea3914 -[UIScreen _mainSceneBoundsForInterfaceOrientation:] + 40 7 UIKitCore 0x00000001c5708134 +[UINavigationBar defaultSizeForOrientation:] + 76 8 UIKitCore 0x00000001c6222c88 -[_UISearchPresentationController _layoutPresentationWithSize:transitionCoordinator:] + 704 9 UIKitCore 0x00000001c622296c -[_UISearchPresentationController containerViewWillLayoutSubviews] + 84 10 UIKitCore 0x00000001c549304c block_destroy_helper.13 + 25112 11 UIKitCore 0x00000001c549344c block_destroy_helper.13 + 26136 12 UIKitCore 0x00000001c4ea26a8 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 1648 13 QuartzCore 0x0000000196103dbc _ZN2CA5Layer15perform_update_EPS0_P7CALayerjNS_17LayerUpdateReasonEPNS_11TransactionE + 460 14 QuartzCore 0x000000019610390c _ZN2CA5Layer17update_if_needed_EPNS_11TransactionENS_17LayerUpdateReasonE + 692 15 QuartzCore 0x0000000196035d2c _ZN2CA7Context18commit_transactionEPNS_11TransactionEdPd + 608 16 QuartzCore 0x0000000195e69520 _ZN2CA11Transaction6commitEv + 652 17 AppKit 0x0000000190fe116c __37+[NSDisplayCycle currentDisplayCycle]_block_invoke.7 + 44 18 CoreFoundation 0x000000018be34ad0 __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__ + 28 19 CoreFoundation 0x000000018be34a10 __CFRunLoopDoBlocks + 396 20 CoreFoundation 0x000000018be33e54 __CFRunLoopRun + 2356 21 CoreFoundation 0x000000018bf06234 _CFRunLoopRunSpecificWithOptions + 532 22 HIToolbox 0x0000000198c1f560 RunCurrentEventLoopInMode + 320 23 HIToolbox 0x0000000198c228bc ReceiveNextEventCommon + 488 24 HIToolbox 0x0000000198dac14c _BlockUntilNextEventMatchingListInMode + 48 25 AppKit 0x00000001909163d0 _DPSBlockUntilNextEventMatchingListInMode + 228 26 AppKit 0x000000019026a084 _DPSNextEvent + 576 27 AppKit 0x0000000190dff96c -[NSApplication(NSEventRouting) _nextEventMatchingEventMask:untilDate:inMode:dequeue:] + 688 28 AppKit 0x0000000190dff678 -[NSApplication(NSEventRouting) nextEventMatchingMask:untilDate:inMode:dequeue:] + 72 29 AppKit 0x000000019025d13c -[NSApplication run] + 368 30 AppKit 0x00000001902357b0 NSApplicationMain + 880 31 AppKit 0x000000019047c958 +[NSWindow _savedFrameFromString:] + 0 32 UIKitMacHelper 0x00000001aa2651bc UINSApplicationMain + 972 33 UIKitCore 0x00000001c4e1aed4 UIApplicationMain + 144 34 UIKitCore 0x00000001c548bda0 block_destroy_helper.31 + 8880 35 DigitalConcertHall.debug.dylib 0x0000000106e41bd8 $sSo21UIApplicationDelegateP5UIKitE4mainyyFZ + 128 36 DigitalConcertHall.debug.dylib 0x0000000106e41b4c $s18DigitalConcertHall11AppDelegateC5$mainyyFZ + 32 37 DigitalConcertHall.debug.dylib 0x0000000106e4afc0 __debug_main_executable_dylib_entry_point + 28 38 dyld 0x000000018b9ac4e4 start + 6992 ) I could not test with the iOS 27 beta 4 SDK due to this blocking issue: https://developer.apple.com/forums/thread/839012 However, when I tried to set up a simple sample project, I could not reproduce the issue. Does anybody know what might be causing this? I filed feedback FB24201508
Replies
7
Boosts
2
Views
1.8k
Activity
1d
Various menu bar NSStatusItem issues with macOS 27
It seems like macOS 27 beta 2 has some issues with NSStatusItem buttons added to the menu bar - this creates difficulties for some menu bar extra apps. NSStatusItem buttons does not receive mouse hover/movement events - FB23329983 On macOS 27, views inside an NSStatusItem button no longer receive hover or mouse-movement events. The same code works correctly on macOS 26. What I tried: An NSTrackingArea attached to a subview of NSStatusBarButton An NSTrackingArea attached directly to the status-bar button Replacing NSStatusItem.view with a custom view Embedding an NSHostingView and using SwiftUI onHover/onContinuousHover NSStatusItem button highlight cannot be set programmatically. - FB23330269 The following code no longer has any effect (does not provide the highlight capsule): NSStatusItem.button?.highlight(true) NSStatusItem window occlusionState no longer reflects hidden menu bar visibility - FB23349447 The following no longer works: statusItem.button?.window?.occlusionState.contains(.visible) These changes may be related to some of the touch related changes or maybe it's about how menu items are now seemingly more "managed" in a way that their position, visibility may change in a way that is transparent/undetectable to the app.
Replies
7
Boosts
2
Views
1.5k
Activity
2d
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
259
Activity
2d
HiraginoSans-W4/W5 availability diverges between iOS 16.5.1 and iOS 18.0.1: UIFont(name:) returns nil, XIB labels fall back to Helvetica
Background Our app previously bundled ヒラギノ角ゴシック W4.ttc and W5.ttc via UIAppFonts. App Store review flagged them under ITMS-91198 as Apple-provided fonts. We removed the bundled .ttc files and need to verify the runtime font-resolution behavior before shipping. Case C below shows the original state (with .ttc present) for comparison. Environment Same app, same code, same XIB, physical devices only. Tested OS: iOS 16.5.1 (two builds: with and without bundled .ttc) and iOS 18.0.1 (without bundled .ttc). Xcode 16.x. How to read the logs Each log has three sections: SYSTEM HIRAGINO SANS — UIFont.fontNames(forFamilyName: "Hiragino Sans"), i.e. what the OS itself provides. RAW UIFont(name:) — UIFont(name: "HiraginoSans-W4", size: 16) etc. This is the code path our App.Font wrapper uses. XIB LABEL RESOLVED — four UILabels whose XIB fontDescription specifies HiraginoSans-W3/W4/W5/W6 respectively. resolved= is label.font.fontName at runtime. Case A — iOS 18.0.1, physical device, bundled .ttc removed ===== ENV ===== systemVersion : 18.0.1 target : Physical Device ===== SYSTEM HIRAGINO SANS ===== HiraginoSans-W3 HiraginoSans-W4 HiraginoSans-W5 HiraginoSans-W6 HiraginoSans-W7 HiraginoSans-W8 ===== RAW UIFont(name:) ===== HiraginoSans-W3 OK family=Hiragino Sans HiraginoSans-W4 OK family=Hiragino Sans HiraginoSans-W5 OK family=Hiragino Sans HiraginoSans-W6 OK family=Hiragino Sans ===== XIB LABEL RESOLVED ===== W3Lab xib=HiraginoSans-W3 resolved=HiraginoSans-W3 family=Hiragino Sans W4Lab xib=HiraginoSans-W4 resolved=HiraginoSans-W4 family=Hiragino Sans W5Lab xib=HiraginoSans-W5 resolved=HiraginoSans-W5 family=Hiragino Sans W6Lab xib=HiraginoSans-W6 resolved=HiraginoSans-W6 family=Hiragino Sans ===== END =====Case B — iOS 16.5.1, physical device, bundled .ttc removed ===== ENV ===== systemVersion : 16.5.1 target : Physical Device ===== SYSTEM HIRAGINO SANS ===== HiraginoSans-W3 HiraginoSans-W6 HiraginoSans-W7 ===== RAW UIFont(name:) ===== HiraginoSans-W3 OK family=Hiragino Sans HiraginoSans-W4 nil HiraginoSans-W5 nil HiraginoSans-W6 OK family=Hiragino Sans ===== XIB LABEL RESOLVED ===== W3Lab xib=HiraginoSans-W3 resolved=HiraginoSans-W3 family=Hiragino Sans W4Lab xib=HiraginoSans-W4 resolved=Helvetica family=Helvetica W5Lab xib=HiraginoSans-W5 resolved=Helvetica family=Helvetica W6Lab xib=HiraginoSans-W6 resolved=HiraginoSans-W6 family=Hiragino Sans ===== END =====Case C — iOS 16.5.1, physical device, bundled .ttc present (original state) ===== ENV ===== systemVersion : 16.5.1 target : Physical Device ===== SYSTEM HIRAGINO SANS ===== HiraginoSans-W3 HiraginoSans-W4 HiraginoSans-W5 HiraginoSans-W6 HiraginoSans-W7 ===== RAW UIFont(name:) ===== HiraginoSans-W3 OK family=Hiragino Sans HiraginoSans-W4 OK family=Hiragino Sans HiraginoSans-W5 OK family=Hiragino Sans HiraginoSans-W6 OK family=Hiragino Sans ===== XIB LABEL RESOLVED ===== W3Lab xib=HiraginoSans-W3 resolved=HiraginoSans-W3 family=Hiragino Sans W4Lab xib=HiraginoSans-W4 resolved=HiraginoSans-W4 family=Hiragino Sans W5Lab xib=HiraginoSans-W5 resolved=HiraginoSans-W5 family=Hiragino Sans W6Lab xib=HiraginoSans-W6 resolved=HiraginoSans-W6 family=Hiragino Sans ===== END =====Observations Comparing B and C (same OS, only .ttc presence differs): removing the bundled .ttc removes HiraginoSans-W4/W5 from the system font list, makes UIFont(name:) return nil for them, and makes XIB labels naming them fall back to Helvetica — not SF, not the nearest weight in the same family. Comparing B and A (same .ttc state, only OS differs): iOS 18.0.1 ships HiraginoSans-W3–W8 in the system, so removing the bundled .ttc has no effect there. Question 1 — System font inventory by OS version Is there an official, versioned list of system-provided fonts (PostScript names) per iOS release? We need to determine which Hiragino Sans weights are available on a given OS at runtime, without hard-coding assumptions. Our observations show that iOS 16.5.1 does not provide HiraginoSans-W4/W5 in the system font set, while iOS 18.0.1 provides W3–W8. If no per-version official list exists, is UIFont.familyNames / UIFont.fontNames(forFamilyName:) the recommended runtime enumeration method? Or is there a documented recommendation to avoid relying on specific PostScript names across OS versions? Question 2 — XIB fontDescription fallback rule When a UILabel's XIB fontDescription specifies a font PostScript name that is not available at runtime (e.g. HiraginoSans-W4 on iOS 16.5.1 after removing the bundled .ttc), we observe UIKit falls back to Helvetica — not SF, not the nearest available weight in the same family. Is this fallback rule documented? Is it stable across iOS versions, or should we treat the fallback target as unspecified? If the fallback target cannot be relied upon, what is the recommended approach for XIB-based layouts that must not render with an unexpected font? Must every such label be re-assigned in code after awakeFromNib / viewDidLoad? Or is there a supported way to declare a fallback chain in Interface Builder?
Replies
0
Boosts
0
Views
45
Activity
2d
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
378
Activity
2d
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
373
Activity
2d
Is a scene always connected when a UIScene app is launched in the background (silent push, BGTask, background URLSession)?
Hello, We are migrating a large UIKit app from the app-delegate lifecycle to the UIScene lifecycle. (Building with Xcode 27 / iOS 27 SDK, our non-scene app crashes at launch with EXC_BREAKPOINT in _UIApplicationEvaluateRuntimeIssueForNoSceneLifecycleAdoption.) Our startup work runs from application(_:didFinishLaunchingWithOptions:), and we need to know what is guaranteed for background launches. Observed (iPhone 15 Pro, iOS 27.2, app built with Xcode 26.3; also iOS 17.5 simulator): Non-scene build, launched by a content-available push: launchOptions contained UIApplicationLaunchOptionsRemoteNotificationKey. applicationDidEnterBackground was not called during the background run. Non-scene build, launched by a BGProcessingTask: launchOptions empty. applicationDidEnterBackground was not called; the first lifecycle callback was applicationWillEnterForeground when the user opened the app 8 minutes later. Scene build, launched by a BGProcessingTask and by a content-available push: scene(_:willConnectTo:options:) was called 0.15-0.2 s after didFinishLaunching while applicationState == .background (activationState .unattached). connectionOptions had no notificationResponse, URL or shortcut item. In the push launch, scene(_:willConnectTo:options:) was called 37 ms before application(_:didReceiveRemoteNotification:fetchCompletionHandler:). sceneWillEnterForeground / sceneDidEnterBackground were not called before the process was suspended. Scene build, background URLSession relaunch (simulator): the scene also connected right after didFinishLaunching in the background, 6 ms before application(_:handleEventsForBackgroundURLSession:completionHandler:). Question: For a UIScene-based app that the system launches directly into the background (content-available push, BGTaskScheduler task, background URLSession events), is it guaranteed that UIKit connects a scene session (scene(_:willConnectTo:options:)) before the user opens the app, or can a background launch run with no connected scene until the app comes to the foreground? In the same launches, can sceneDidEnterBackground (or applicationDidEnterBackground in a non-scene app) be called for a process that never entered the foreground? Please point us to documentation that describes the guaranteed callbacks and their order for background launches. Thank you.
Topic: UI Frameworks SubTopic: UIKit
Replies
0
Boosts
0
Views
76
Activity
2d
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
59
Activity
3d
Persistent scroll stutter on iPhone 17 Pro Max, 18 Pro Max and 18 Pro (iOS 27.2), also on Apple Store demo units
Affected devices (all show the same problem): 1x iPhone 17 Pro Max 2x iPhone 18 Pro Max 1x iPhone 18 Pro Many demo iPhones at several Apple Stores Current iOS version: 27.2 Issue: Vertical scrolling inside apps frequently stutters and drops frames. It happens in many, many apps, including Apple's own App Store and Apple Store apps. During a normal flick-and-decelerate scroll, the content repeatedly freezes for one or more frames and then jumps forward. Because this reproduces on four of my own devices and on many Apple Store demo units, I believe it is a widespread, system-level issue, not a defect of a single device or my settings. Impact: I have been living with this for more than six months. I use my iPhone heavily every day, and the constant stutter has made using it genuinely distressing. Everything else about iPhone feels excellent, which makes this problem even harder to accept. Steps to reproduce: Open the App Store app (or almost any app with a scrolling list). Scroll with a normal flick and let it decelerate. Observe repeated hitches during the scroll. Measurements: I filmed the screen with a second iPhone at 4K 120 fps and measured content movement frame by frame: iPhone 18 Pro Max, third-party video feed: about 4 hitches per second of scrolling, about 4% of frames dropped, mostly single-frame drops. iPhone 18 Pro Max, third-party social app list: about 11 hitches per second, about 12% of frames dropped, at a regular rhythm every 6-8 frames. About a third of the stalls last 2-3 frames, and the content does not catch up afterwards. iPhone 17 Pro Max, third-party comment list: about 5 hitches per second, about 8% of frames dropped, including several full freezes of 50-75 ms. Expected: Smooth 120 Hz scrolling, as ProMotion is designed to deliver. Is Apple aware of this issue? I am happy to provide videos, frame-by-frame data, or sysdiagnose logs.
Replies
3
Boosts
1
Views
191
Activity
3d
On iPhone Duo in landscape, the tab bar isn't visible.
Hi, I have an app with a specific view hierarchy, and when I tested it on an iPhone Duo in landscape, I noticed an issue with how the tab bar is displayed or, rather, how it isn’t displayed. On iPhone Duo in landscape and on the main screen, the tab bar for a `UITabBarController` pushed onto a `UINavigationController` (itself inside another `UITabBarController`) isn’t visible. I've tested it in both UIKit and SwiftUI, and the issue is present in both. I could only get the tab bar to appear by presenting the view modally instead of pushing it, but that isn’t a viable solution for my app. For example: ``` UIWindow └─ RootTabBarController (UITabBarController) └─ UINavigationController (tab 2) ├─ FirstTabViewController (root) └─ push └─ NestedTabBarController (UITabBarController) ├─ ItemListViewController (UITableView) ├─ ItemListViewController (UITableView) └─ ItemListViewController (UITableView) ``` I've put together a simplified [demo repo](https://github.com/janossuta/iphone-duo-issue-demo/tree/main) that shows the problem. I've attached two images showing that the tabs disappear in landscape mode and are visible in portrait mode. Can we preserve the original functionality?
Topic: UI Frameworks SubTopic: General
Replies
0
Boosts
0
Views
35
Activity
3d
Cannot move window by its background (macOS 27)
Hi, My app (SmashTunes) can display a floating window with artwork of a music track that is displaying. It does for over a decade in multiple versions of macOS. I do this by calling window?.isMovableByWindowBackground = true. This stopped working under macOS 27. I've read some reports of others not being able to move windows. It should supposedly have been fixed in macOS 27.2, but it is not. Has anyone on this forum run into the same problem, or know of a different way to move windows around on the screen? When I add add a titlebar, I can drag it by the titlebar, but that is not really an option for my use case.
Topic: UI Frameworks SubTopic: General
Replies
1
Boosts
0
Views
115
Activity
4d