Scenario: Typing Chinese Zhuyin “ㄨㄤ” and then selecting the candidate word “王”.
On iOS 18, the delegate (textField:shouldChangeCharactersInRange:replacementString:) is called with:
range: {0, 2}
replacementString: "王"
On iOS 26, the delegate (textField:shouldChangeCharactersInRanges:replacementString:) instead provides:
ranges: [{2, 0}]
replacementString: "王"
This results in inconsistent text input handling compared to earlier system versions.
Implement: Limit user input to a maximum of 100 Chinese characters.
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
if ([textField markedTextRange]) {
return YES;
}
NSString *changedString = [textField.text stringByReplacingCharactersInRange:range withString:string];
if (changedString.length > 100) {
return NO;
}
return YES;
}
Questions:
Is this an intentional change in iOS 26?
If intentional, what is the recommended way to handle such cases in order to support both iOS 18 and iOS 26 consistently?
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.
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
I have an NSSplitViewController with three columns:
sidebar
full-height content view with NSScrollView/NSTableView
detail view.
There's no (visible) titlebar and no toolbar.
This layout has worked fine for years, but in Tahoe an unwanted overlay (~30-50px high) appears at the top of any column containing a scroll view with table content. Xcode suggests it's an NSScrollPocket.
My research suggests it...
Only affects columns with NSScrollView
Plain NSView columns are unaffected
Overlay height varies (~50px or ~30px depending on how I mess with title / toolbar settings)
Disabling titlebar/toolbar settings reduces but doesn't eliminate the overlay
The overlay obscures content and there doesn't appear to be any API
to control its visibility. Is this intended behavior, and if so, is
there a way to disable it for applications that don't need this UI
element?
If it helps visualise the desired result, the app is https://indigostack.app
Any guidance would be appreciated!
Topic:
UI Frameworks
SubTopic:
AppKit
This is because when opening the keyboard in an app that supports Liquid Glass, iOS will automatically wrap the keyboard with a bottom view that uses the Liquid Glass effect. In this case, we need to remove the background color. However, in apps that do not support Liquid Glass, having a background color still displays normally. So right now, I’m trying to find a way for the keyboard to know whether the host app supports Liquid Glass when the keyboard is opened, but I haven’t found a solution yet.
Topic:
UI Frameworks
SubTopic:
UIKit
Problem description:
When using the Custom keyboard in various system application scenarios, a gray area is always displayed at the top of the Custom keyboard. Although the system has been restarted and the Custom keyboard has been restarted, and the pull-down operation has been repeated in multiple system application environments, the gray bar still appears. This problem also has the same problem on other input method software.
Reproduction steps:
Set the current input method to "CustomKeybaord"
In the memo app or any other system app, pull up the Custom keyboard, or switch to the Custom keyboard.
Observe whether a gray area is always displayed above the Custom keyboard.
Request:
I would like to understand whether the current behavior is a bug or if it requires Custom keyboards to adapt their style accordingly. However, I not found that
currently unable to modify the style or color of the gray bar in question, and I do not have a suitable adaptation solution at this time. I would appreciate further assistance
Topic:
UI Frameworks
SubTopic:
UIKit
The below code will render a list of items and a button to shuffle them and change their height withAnimation.
If you scroll down and shuffle it you will eventually see glitches in the animation, mostly consisting of ghost items animating on top of other items and disappearing.
Does anyone know why this is happening, and how to stop it happening? The issue goes away entirely if I use a VStack, but using a VStack brings its own problems.
import SwiftUI
struct Item: Identifiable {
let id = UUID()
var height: CGFloat
var label: String
}
struct ContentView: View {
@State private var items: [Item] =
(0..<30).map { i in Item(height: .random(in: 80...220), label: "Row \(i)") }
var body: some View {
NavigationStack {
ScrollView {
LazyVStack(spacing: 8) {
ForEach(items) { item in
Text(item.label)
.frame(maxWidth: .infinity)
.frame(height: item.height)
.background(.gray.opacity(0.15))
.clipShape(RoundedRectangle(cornerRadius: 12))
.padding(.horizontal)
}
}
.padding(.vertical)
}
.navigationTitle("LazyVStack Demo")
.toolbar {
ToolbarItem(placement: .topBarTrailing) {
Button("Shuffle") {
withAnimation() {
items.shuffle()
for i in items.indices {
items[i].height = .random(in: 80...220)
}
}
}
}
}
}
}
}
#Preview { ContentView() }
This new modifier is supposedly backported to iOS 17, but on attempting to use it on the latest iOS 18.5, this happens:
Symbol not found: _$s7SwiftUI17EnvironmentValuesV33_navigationIndicatorVisibilityABIAA0G0OvpMV
This happens with any usage of the modifier. An availability check won't save you either.
The cruelest part of this is that I only need the modifier on iOS 26, lmao.
Am I just missing something?
Topic:
UI Frameworks
SubTopic:
SwiftUI
Hello,
I’m seeing a layout issue where the system window controls overlap the navigation bar’s right-side buttons when the app window is resized on iPadOS 26.
Environment
Xcode: 16.4
Simulator: iPadOS 26.0, device profile iPad Pro 13-inch
Physical device: iPad updated to iPadOS 26 (same behavior)
UI stack: UIKit + Storyboards (no SwiftUI)
App structure: Root UINavigationController
Summary
Since iPadOS 26 introduced freely resizable app windows, the system’s window management controls (close/minimize/resize at the top-right) begin to overlap the navigation bar buttons as the window size becomes smaller. At maximum window size there’s no issue. Additionally, the navigation bar buttons themselves appear to scale down visually when the window gets smaller.
Steps to Reproduce
Build with Xcode 16.4 and run on iPadOS 26.0 (simulator or device).
Open a screen embedded in a UINavigationController with right-side bar button items.
Resize the app window to a smaller size.
Observe the top-right system window controls overlapping the navigation bar buttons.
Expected Result
System window controls should not overlap app content; the navigation bar should remain usable and properly spaced at all supported window sizes.
Actual Result
When the window is small, the system window controls overlap the right-side navigation bar buttons. The bar button items also appear to shrink as the window size decreases.
Notes
Reproducible on both simulator and a real device updated to iPadOS 26.
Project uses UIKit + Storyboards only (no SwiftUI).
Safe areas and basic constraints look fine, so the root cause is unclear.
Questions
Is this a known issue with iPadOS 26 resizable windows?
Any recommended workaround (e.g., API to reserve space near the window controls, UINavigationBar configuration, or trait/size-class handling)?
I can provide a minimal sample project and screenshots if helpful.
Thank you!
When combining a zoom navigationTransition with a List in a NavigationStack we end up getting the navigationTitle not properly re-positioning itself on dismiss/back. It looks like a visual bug/glitch (unless I missed something).
This seems to not happen with a ScrollView
import SwiftUI
struct Item: Identifiable {
let id: UUID = UUID()
}
struct ContentView: View {
@State private var selected: Item?
@Namespace private var animation
var body: some View {
NavigationStack {
List {
ForEach((0..<50).map { _ in Item() }, id: \.id) { item in
Button {
selected = item
} label: {
Text(item.id.uuidString)
.frame(maxWidth: .infinity, alignment: .leading)
}
.matchedTransitionSource(id: item.id, in: animation)
}
}
.navigationTitle("Title")
.navigationSubtitle("Subtitle")
}
.fullScreenCover(item: $selected) { item in
Text(item.id.uuidString)
.frame(maxWidth: .infinity)
.navigationTransition(.zoom(sourceID: item.id, in: animation))
}
}
}
#Preview {
ContentView()
}
Topic:
UI Frameworks
SubTopic:
SwiftUI
Steps to Reproduce:
Connect a MacBook Pro (lid closed) to a large external monitor.
Run the SDL3 testwm test application.
git clone https://github.com/libsdl-org/SDL.git
cmake -S . -B build -DBUILD_SHARED_LIBS=OFF -DSDL_TESTS=ON
cmake --build build
The testwm binary will be located in the build/test directory.
Move the application window around the left edge of the external display.
Observed Result:
WindowServer crashes.
System Configuration:
MacBook Pro M3 Max, macOS Sequoia 15.6.1
LG GX9, 5120x2160 resolution, running at 165 Hz refresh rate
Lid closed, single external display
Panic Log:
panic(cpu 7 caller 0xfffffe0027f61d5c): "mismatched swapID's 6386399 vs 6386400\n" @UnifiedPipeline.cpp:14570
Debugger message: panic
Memory ID: 0xff
OS release type: User
OS version: 24G90
Kernel version: Darwin Kernel Version 24.6.0: Mon Jul 14 11:30:55 PDT 2025; root:xnu-11417.140.69~1/RELEASE_ARM64_T6031
Fileset Kernelcache UUID: 8AA69CD2038CD2BAE2ED364428F4DBEA
Kernel UUID: 75A21406-D046-3232-AA3F-085335D5C848
Boot session UUID: B949E839-683B-4DAF-BE42-4562758F976E
iBoot version: iBoot-11881.140.96
iBoot Stage 2 version: iBoot-11881.140.96
secure boot?: YES
roots installed: 0
Paniclog version: 14
KernelCache slide: 0x000000001e0ec000
KernelCache base: 0xfffffe00250f0000
Kernel slide: 0x000000001e0f4000
Kernel text base: 0xfffffe00250f8000
Kernel text exec slide: 0x000000001f870000
Kernel text exec base: 0xfffffe0026874000
mach_absolute_time: 0x64e7db3e6a9
Epoch Time: sec usec
Boot : 0x68b207f0 0x00082ee7
Sleep : 0x68c1a51c 0x00048c6c
Wake : 0x68c1a760 0x00039aa4
Calendar: 0x68c1b78d 0x0001776a
Zone info:
Zone map: 0xfffffe1018000000 - 0xfffffe3618000000
. VM : 0xfffffe1018000000 - 0xfffffe15e4000000
. RO : 0xfffffe15e4000000 - 0xfffffe187e000000
. GEN0 : 0xfffffe187e000000 - 0xfffffe1e4a000000
. GEN1 : 0xfffffe1e4a000000 - 0xfffffe2416000000
. GEN2 : 0xfffffe2416000000 - 0xfffffe29e2000000
. GEN3 : 0xfffffe29e2000000 - 0xfffffe2fae000000
. DATA : 0xfffffe2fae000000 - 0xfffffe3618000000
Metadata: 0xfffffe393c010000 - 0xfffffe3945810000
Bitmaps : 0xfffffe3945810000 - 0xfffffe394c104000
Extra : 0 - 0
CORE 0 recently retired instr at 0xfffffe0026a407a0
CORE 1 recently retired instr at 0xfffffe0026a40798
CORE 2 recently retired instr at 0xfffffe0026a407a0
CORE 3 recently retired instr at 0xfffffe0026a407a0
CORE 4 recently retired instr at 0xfffffe0026a407a0
CORE 5 recently retired instr at 0xfffffe0026a407a0
CORE 6 recently retired instr at 0xfffffe0026a407a0
CORE 7 recently retired instr at 0xfffffe0026a3eefc
CORE 8 recently retired instr at 0xfffffe0026a407a0
CORE 9 recently retired instr at 0xfffffe0026a407a0
CORE 10 recently retired instr at 0xfffffe0026a407a0
CORE 11 recently retired instr at 0xfffffe0026a407a0
CORE 12 recently retired instr at 0xfffffe0026a407a0
CORE 13 recently retired instr at 0xfffffe0026a407a0
TPIDRx_ELy = {1: 0xfffffe29e4ef5ee0 0: 0x0000000000001007 0ro: 0x000000016c59b0e0 }
CORE 0 PVH locks held: None
CORE 1 PVH locks held: None
CORE 2 PVH locks held: None
CORE 3 PVH locks held: None
CORE 4 PVH locks held: None
CORE 5 PVH locks held: None
CORE 6 PVH locks held: None
CORE 7 PVH locks held: None
CORE 8 PVH locks held: None
CORE 9 PVH locks held: None
CORE 10 PVH locks held: None
CORE 11 PVH locks held: None
CORE 12 PVH locks held: None
CORE 13 PVH locks held: None
CORE 0: PC=0xfffffe0026abfa40, LR=0xfffffe0026ae4fc8, FP=0xfffffe65b8703980
CORE 1: PC=0x0000000193ae2730, LR=0x000000019389d108, FP=0x000000016f43e590
CORE 2: PC=0xfffffe0026911e84, LR=0xfffffe0026911e84, FP=0xfffffe65b850bed0
CORE 3: PC=0xfffffe0026911e84, LR=0xfffffe0026911e84, FP=0xfffffe65b8ee7ed0
CORE 4: PC=0xfffffe0026911e84, LR=0xfffffe0026911e84, FP=0xfffffe65b7eebed0
CORE 5: PC=0xfffffe0026a3ac1c, LR=0xfffffe0026a3ac18, FP=0xfffffe65b8c63e40
CORE 6: PC=0xfffffe0026911e84, LR=0xfffffe0026911e84, FP=0xfffffe65b7033ed0
CORE 7 is the one that panicked. Check the full backtrace for details.
CORE 8: PC=0xfffffe0026a3ac1c, LR=0xfffffe0026a3ac18, FP=0xfffffe65b737be40
CORE 9: PC=0xfffffe0026911e84, LR=0xfffffe0026911e84, FP=0xfffffe65b8f1fed0
CORE 10: PC=0xfffffe0026911e84, LR=0xfffffe0026911e84, FP=0xfffffe65b7fe7ed0
CORE 11: PC=0xfffffe0026a3ac1c, LR=0xfffffe0026a3ac18, FP=0xfffffe65b870fe40
CORE 12: PC=0xfffffe0026911e84, LR=0xfffffe0026911e84, FP=0xfffffe65b80a7ed0
CORE 13: PC=0xfffffe0026a3ac1c, LR=0xfffffe0026a3ac18, FP=0xfffffe65b685fe40
Compressor Info: 6% of compressed pages limit (OK) and 16% of segments limit (OK) with 0 swapfiles and OK swap space
Panicked task 0xfffffe23153cb940: 10375 pages, 28 threads: pid 406: WindowServer
Panicked thread: 0xfffffe29e4ef5ee0, backtrace: 0xfffffe65b6f07210, tid: 5146
lr: 0xfffffe00268d53d4 fp: 0xfffffe65b6f072a0
lr: 0xfffffe0026a36da0 fp: 0xfffffe65b6f07310
lr: 0xfffffe0026a35114 fp: 0xfffffe65b6f073d0
lr: 0xfffffe002687f8b0 fp: 0xfffffe65b6f073e0
lr: 0xfffffe00268d5710 fp: 0xfffffe65b6f077b0
lr: 0xfffffe0027169290 fp: 0xfffffe65b6f077d0
lr: 0xfffffe0027f61d5c fp: 0xfffffe65b6f07850
lr: 0xfffffe0029186878 fp: 0xfffffe65b6f07880
lr: 0xfffffe00270bd2a0 fp: 0xfffffe65b6f078b0
lr: 0xfffffe00270bd5b0 fp: 0xfffffe65b6f07a40
lr: 0xfffffe0026a00194 fp: 0xfffffe65b6f07b60
lr: 0xfffffe00268dcd48 fp: 0xfffffe65b6f07c00
lr: 0xfffffe00268b2ed4 fp: 0xfffffe65b6f07c60
lr: 0xfffffe00268c6868 fp: 0xfffffe65b6f07cb0
lr: 0xfffffe00268c6c80 fp: 0xfffffe65b6f07da0
lr: 0xfffffe0026a29bbc fp: 0xfffffe65b6f07e50
lr: 0xfffffe0026a355a4 fp: 0xfffffe65b6f07f10
lr: 0xfffffe002687f8b0 fp: 0xfffffe65b6f07f20
lr: 0x000000018dc89c34 fp: 0x0000000000000000
Kernel Extensions in backtrace:
com.apple.iokit.IOMobileGraphicsFamily(343.0)[6C8CFA29-99CD-39D4-81BC-2B0F147BE64F]@0xfffffe002917d860->0xfffffe00291a024f
The main problem here is that sometimes the snippet view has black text on a black background and it is unreadable.
To see what might be affecting this:
I tried checking the colorscheme enviroment value via @Environment(.colorScheme) in my view. This usually returns the correct device light/dark mode, however it returns incorrect after device restarts or app is updated. In order to correct this, user must toggle light/dark mode in device settings.
I also tried checking UITraitCollection.current.userInterfaceStyle in the perform() function of my AppIntent. This also usually returns the correct value, but does not after user toggles light/dark mode in device settings. In order to correct this, user must open the app.
The idea with checking these variables was that if one always returned the correct mode, I could set the text to the correct color instead of using .primary. Neither value seems to be 100% accurate and they fail in opposite situations.
Color.primary seems to align with the colorscheme environment variable. When we get the wrong value here (not cooresponding to the set device value), we will see something like black text on black background. Our returned view has no background set, so it matches the containing view. Colorscheme will say that the device is in lightmode when it is in darkmode, so although we have the correct background color, Color.primary is incorrect and the text is unreadable/hard to read.
Is there a solution that will never show unreadable text color besides forcing the view to have a specific colored background and specific colored text?
Topic:
UI Frameworks
SubTopic:
SwiftUI
When disabling the opacity slider of color panels, my app crashes with unsatisfiable layout constraints. Feel free reproduce with a minimal test project: A macOS app based on the Xcode 26.0 template with only one line added to the ViewController's viewDidLoad() function:
NSColorPanel.shared.showsAlpha = false
The issue doesn't occur if this property is set to "true" or not set at all.
I just filed a corresponding bug report (FB20269686), although I don't expect any feedback from Apple ... as numerous issues I reported were never updated or commented at all (after migrating from RADARs).
Topic:
UI Frameworks
SubTopic:
AppKit
For information I stumbled upon a regression with SwiftUI Slider on iOS 26. Its onEditingChanged closure might be called twice when interaction ends, with a final Boolean incorrect value of true provided to the closure.
As a result apps cannot reliably rely on this closure to detect when an interaction with the slider starts or ends.
I filed a feedback under FB20283439 (iOS 26.0 regression: Slider onEditingChanged closure is unreliable).
I have some buttons. I set the bezelStyle to NSBezelStyleGlass.
I'm sometimes experiencing the following issue:
Put the system in dark mode.
Some glass buttons still draw with the light appearance.
One or more of the following actions usually makes the appearance redraw proper:
-Clicking the button
-Deactivating and then reactivating the window.
-Close and then reopen the window.
I tried setNeedsDisplay YES etc. but that didn't work
The delay is quite noticeable. Everything else is in dark mode except one or two glass buttons.
This seems to workaround the issue:
BOOL didToggleGlass = NO;
if (self.bezelStyle == NSBezelStyleGlass)
{
// Turn glass off just for a sec.
self.bezelStyle = NSBezelStyleToolbar;
didToggleGlass = YES;
}
if (didToggleGlass)
{
// Put glass back on.
self.bezelStyle = NSBezelStyleGlass;
}
Apparently toggling glass cause the effective appearance to change so you can't use the above workaround in a -viewDidChangeEffectiveAppearance b/c you'll create an infinite loop unless you guard against it.
(Sorry if this is not the right place to post...)
I upgraded my iPad / macOS to 26 yesterday. Soon, I noticed that the two buttons in the toolbar would sometimes not appear:
Note that they should be visible at all times.
I played a little more to see if there was any pattern, but I could not find any. Has anyone experienced something similar...? Is this an iPadOS26 bug? (I haven't checked with an iPhone yet.)
Thanks.
In SwiftUI on macOS, A menu-style Picker is drawn as a pop-up button.
It generally looks and behaves the same as an NSPopUpButton in AppKit.
SwiftUI introduced iOS-like looking UI for settings in macOS, and consequently, the Picker also has its own style when placed inside a Form.
A Form-style Picker displays only up/down chevrons and draws the background only when the mouse hovers over it. It also changes its width dynamically based on the selected item.
Form {
Picker("Animal:", selection: $selection) {
ForEach(["Dog", "Cow"], id: \.self) {
Text($0)
}
.pickerStyle(.menu)
}
You can find it, for instance, in the Print dialog.
My question is: I couldn't find a way to draw an NSPopUpButton in AppKit with this style. Does anyone know how to achieve this in AppKit?
Some might say I should just use SwiftUI straightforwardly, but I would like to use it in a print panel accessory that currently still avoids using SwiftUI but its dialog has SwiftUI.Form-looking.
Hi everyone,
I’m running into a strange animation glitch when using a Menu inside a glassEffect container.
Here’s a minimal example:
import SwiftUI
struct ContentView: View {
@Namespace private var namespace
var body: some View {
ZStack {
Image(.background)
.resizable()
.frame(maxWidth: .infinity, maxHeight: .infinity)
.ignoresSafeArea()
GlassEffectContainer {
HStack {
Button("b1") {}
Button("b2") {}
Button("b3") {}
Button("b4") {}
Button("b5") {}
Menu {
Button("t1") { }
Button("t2") { }
Button("t3") { }
Button("t4") { }
Button("t5") { }
} label: {
Text("Menu")
}
}
}
.padding(.horizontal)
.frame(height: 50)
.glassEffect()
}
}
}
What happens:
The bar looks fine initially:
When you open the Menu, the entire bar morphs into the menu:
When dismissing, the bar briefly animates into a solid rectangle before reapplying the glass effect:
Questions:
Is there a way to prevent that brief rectangle animation when dismissing the menu?
If not, is it possible to avoid the morphing altogether and have the menu simply overlay on top of the bar instead of replacing it?
Any ideas or workarounds would be greatly appreciated!
Hello,
I’ve noticed an issue with custom keyboard extensions in iOS 26 that seems specific to native apps. When a custom keyboard is opened in apps like Messages, Notes, or Safari, there’s an extra strip of native grey space around the left, right, and top edges of the keyboard.
This extra margin cannot be rendered over by the keyboard’s own views.
Interestingly, this behaviour does not occur in third-party apps like Instagram.
It also wasn’t present in earlier iOS versions.
The result is that keyboards with custom or non-grey backgrounds look visually inconsistent (they appear framed by unwanted grey).
Has anyone else run into this? Is this a known change in iOS 26, or could it be a bug? Any guidance or official clarification would be appreciated.
Thanks!
Platform: iOS 26 RC / Xcode 26 RC
Component: UIKit - UITextField
Description:
When typing a Japanese character (or other IME input) as the first character in a UITextField and then losing focus (by pressing Enter or tapping elsewhere), the character is incorrectly duplicated. This issue only happens in iOS26 beta.
Steps to Reproduce:
Create a UITextField with shouldChangeCharactersIn delegate
Switch to Japanese keyboard
Type "あ" (or any hiragana character)
Press Enter or tap outside the text field
Observe the character count becomes 2 instead of 1
Expected Result:
Character count should remain 1
Actual Result:
Character is duplicated, count becomes 2
Sample Code:
func shouldChangeText(
in range: NSRange,
replacementText string: String,
maximumNumberOfCharacters: Int,
regexValidation: String? = nil) -> (String, Bool) {
guard let stringRange = Range(range, in: currentText) else {
return (currentText, false)
}
if let regex = regexValidation,
string != "", // delete key
!string.room.checkPattern(regex) {
return (currentText, false)
}
let changedText = currentText.replacingCharacters(in: stringRange, with: string)
let allowChange = changedText.utf16.count <= maximumNumberOfCharacters
print("=== stringRange: \(stringRange), currentText: \(currentText), replacementText: \(string) changedText: \(changedText), allowChange: \(allowChange) ===")
guard !allowChange else {
return (changedText, allowChange)
}
// Accept text deletion even if changedText count is more than maximumNumberCharacters
guard !string.isEmpty else {
return (changedText, true)
}
insert(text: string, maximumNumberOfCharacters: maximumNumberOfCharacters)
return (currentText, allowChange)
}
I'm noticing some weird glitches with my collection view headers on macOS Tahoe.
The sections headers are pinned to the visible region. I headers fade out when scrolling and are supposed to fade back in but sometimes they don't fade back in and the header remains but the header text doesn't come back (until I scroll again).
How can I turn off this scroll animation thingy?
The following code works properly, ensuring the list is scrolled at the correct ID when first rendered:
import SwiftUI
struct DataItem: Identifiable {
let id: Int
let height: CGFloat
init(id: Int) {
self.id = id
self.height = CGFloat.random(in: 100...300)
}
}
struct ContentView: View {
@State private var items = (0..<1000).map { DataItem(id: $0) }
@State private var scrollPosition: ScrollPosition
init() {
let mid = 500
_scrollPosition = State(initialValue: .init(id: mid, anchor: .center))
}
var body: some View {
ScrollView {
LazyVStack(spacing: 8) {
ForEach(items) { item in
Text("Item \(item.id)")
.frame(height: item.height)
.frame(maxWidth: .infinity)
.background(.gray)
}
}
.scrollTargetLayout()
}
.scrollPosition($scrollPosition, anchor: .center)
}
}
However, if I change this to use VStack this ceases to work - the list begins rendered at the top of the list. The only way I can render it starting at the correct position is using side effects like onAppear or task, where I would update the scroll position.
I have observed the following behavior on my iPhone 15 Pro/iOS 26. Is this a bug?
Topic:
UI Frameworks
SubTopic:
SwiftUI