Why there is a working animation with ScrollView + ForEach of items removal, but there is none with List?
ScrollView + ForEach:
struct ContentView: View {
@State var items: [String] = Array(1...5).map(\.description)
var body: some View {
ScrollView(.vertical) {
ForEach(items, id: \.self) { item in
Text(String(item))
.frame(maxWidth: .infinity, minHeight: 50)
.background(.gray)
.onTapGesture {
withAnimation(.linear(duration: 0.1)) {
items = items.filter { $0 != item }
}
}
}
}
}
}
List:
struct ContentView: View {
@State var items: [String] = Array(1...5).map(\.description)
var body: some View {
List(items, id: \.self) { item in
Text(String(item))
.frame(maxWidth: .infinity, minHeight: 50)
.background(.gray)
.onTapGesture {
withAnimation(.linear(duration: 0.1)) {
items = items.filter { $0 != item }
}
}
}
}
}```
SwiftUI
RSS for tagProvide views, controls, and layout structures for declaring your app's user interface using SwiftUI.
Posts under SwiftUI tag
200 Posts
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
I had take screenshots by following code
let scenes = UIApplication.shared.connectedScenes
let windowScene = scenes.first as? UIWindowScene
let window = windowScene?.windows.first
self.uiImage = window?.rootViewController?.view!.getImage(rect: rect)
View has two views. One is ImageView contains some image and overlay of image detection results with .overlay. another view is InfoView contains several info and button which above code fired. on iOS 17, I can take screenshots as I saw, but on iOS26, missing on image of ImageView. Overlay(detected rectangle) in Imageview and InfView can be taken.
How can I take screenshots as I saw on iOS26?(iPad)
I’ve notice that in Maps, some pins contain images and do not have the little triangle at the bottom of it, yet they still animate the same when clicked. How could this be achieved? I believe the name of this annotation is MKMapFeatureAnnotation.
I've tried this and it did not give the same result. I'm able to create a custom MKMarkerAnnotationView but it does not animate the same (balloon animation like the MKMapFeatureAnnotation). I was looking forward to create a custom MKMapFeatureAnnotation similar in design which would animate the same. Unfortunately, I cannot create a custom MKMapFeatureAnnotation because everything is privated
Environment
iOS 26 (23A343)
Xcode 26
Reproduces on device and Simulator
Description
When presenting a SwiftUI WebView (native iOS 26 component) or a WKWebView/UIWebView via UIViewRepresentable, focusing a text field inside the web view and then dismissing it breaks the keyboard layout behavior.
After returning to the main app, tapping any TextField causes the keyboard to cover bottom controls (e.g. buttons). Expected safe area insets are not applied.
The issue is only resolved after closing and reopening the keyboard once.
Steps to Reproduce
Open a SwiftUI screen with WebView (via .sheet or NavigationLink).
Inside the web view, tap a text field to show the keyboard.
Dismiss the web view.
Tap a TextField in the main app.
Expected Result
Layout should adjust correctly.
Bottom controls stay visible above the keyboard.
Actual Result
Keyboard covers bottom controls.
Insets are ignored until the keyboard is dismissed and reopened.
Notes
Reproduces with:
Native SwiftUI WebView (iOS 26)
WKWebView and UIWebView via UIViewRepresentable
Presentation style (.sheet or navigation push) does not matter.
Example video: https://youtu.be/Epgoz1vETKU
FB: FB20386257
Sample Code
import SwiftUI
import WebKit
struct ContentView: View {
@State var url: URL?
@FocusState private var isFocused: Bool
var body: some View {
VStack {
TextField("TextField", text: .constant(""))
.focused($isFocused)
Button("HIDE KEYBOARD") { isFocused = false }
Spacer()
Button("ACTION") {
url = URL(string: "https://google.com")
}
}
.sheet(item: $url) { value in
NavigationStack {
WebView(url: value)
.toolbar {
ToolbarItem(placement: .topBarLeading) {
Button("CLOSE") { url = nil }
}
}
}
}
}
}
extension URL: Identifiable {
public var id: String { absoluteString }
}
I'm trying to replicate edit/select mode of iOS 26 photos app. When user clicks Select button, bottom tab bar is replaced by the toolbar buttons. When I press Done button, a white opaque bar appears at the bottom behind the tabbar. It looks pretty straightforward to implement but I'm banging my head here now. Any help will be appreciated.
Code and animation frames attached bellow
struct ContentView: View {
var body: some View {
TabView(selection: $selectedTab) {
OverviewView()
.tabItem {
Image(systemName: "chart.pie")
Text("Overview")
}
.tag(0)
//rest of the tabs
}
}
}
struct OverviewView: View {
@State private var editActive = false
@State private var selection = Set<String>()
@State private var items = [
"Item 1",
"Item 2",
"Item 3",
]
var body: some View {
NavigationStack {
List(selection: $selection) {
ForEach(items, id: \.self) { item in
Text(item)
}
}
.toolbar {
if editActive {
ToolbarItem(placement: .bottomBar) {
Button {
} label: {
Label("Delete", systemImage: "trash")
}
}
ToolbarItem(placement: .bottomBar) {
Button {
} label: {
Label("Category", systemImage: "tag")
}
}
}
ToolbarItem(placement: .topBarTrailing) {
Button(editActive ? "Done" : "Select") {
withAnimation {
editActive.toggle()
}
}
}
}
.environment(\.editMode, .constant(editActive ? .active : .inactive))
.toolbar(editActive ? .hidden : .visible, for: .tabBar)
}
}
}
I have attached 5 frames during animation phase.
iOS 26 SwiftUI .glassEffect() renders dark/gray on physical device - TestFlight doesn't fix it
.glassEffect() renders as dark/muddy gray on my physical iPhone instead of the light frosted glass like Apple Music's tab bar.
What I've confirmed:
Same code works perfectly on iOS Simulator
Apple Music and other Apple apps show correct Liquid Glass on same device
Brand new Xcode project with just .glassEffect() also renders dark
TestFlight build (App Store signing) has the SAME problem - still dark/gray
This rules out developer signing vs App Store signing as the cause
What I've tried:
Clean build, delete derived data, reinstall app
Completely reinstalled Xcode
All accessibility settings correct (Reduce Transparency OFF, Liquid Glass set to Clear)
Disabled Metal diagnostics
Debug and Release builds
Added window configuration for Extended sRGB/P3 color space
Added AppDelegate with configureWindowForLiquidGlass()
Tried .preferredColorScheme(nil)
Tried background animation to force "live" rendering
Environment:
iPhone 17 Pro, iOS 26.3
Xcode 26.2
macOS 26.3
The question:
Why does .glassEffect() work for Apple's apps but not third party apps, even with App Store signing via TestFlight? What am I missing?
I have some questions about Liquid Glass and iOS 26 on the iPhone.
Routine scrolling transactions in any view are causing the title to change from Light Mode colors to Dark Mode colors. Is this now standard operation? The column headers are also displaying a black stripe across the top of the screen when scrolling. So why doesn't the display shift when in Dark Mode to Light mode?
Scrolling is causing everything in the header (navigation title, time, battery status, and wi-fi status) to change from black to white.
Is this an accessibility action that I may have turned on by accident?
I'm not very thrilled by this behavior!
I’ve created a document type for my app and set it up in the Info Configuration in Xcode. This all works as expected: Implemented with the Transferrable API and ShareLink, I can share an app’s file via the Files app or Notes and then import the file via a Share extension and the fileImport swiftUI api.
My question is regarding Messages, specifically.
It appears as a ShareLink option and I’m able to send my app’s document type via a message, but I’m unable to open it or share it (internally, with my app), other than being able to forward or delete it. If I copy the file, I can’t access it within my app (it’s still stored in the Messages private bundle) and startAccessingSecurityScopedResource returns false as expected. The message does detect the right icon, so it’s recognizing the custom document type.
If my Share Extension, exported document type, and transferable implementation is configured correctly, should I be able to open a file for my app shared via Messages? Is this an allowed action?
I get various answers from AI, and I can’t test this in the Simulator on pre-26 devices.
Hi there,
I have an SwiftUI app that opens a user selected audio file (wave). For each audio file an additional file exists containing events that were extracted from the audio file. This additional file has the same filename and uses the extension bcCalls. I load the audio file using FileImporter view modifier and within access the audio file with a security scoped bookmark. That works well. After loading the audio I create a CallsSidecar NSFilePresenter with the url of the audio file. I make the presenter known to the NSFileCoordinator and upon this add it to the FileCoordinator. This fails with NSFileSandboxingRequestRelatedItemExtension: Failed to issue extension for; Error Domain=NSPOSIXErrorDomain Code=3 "No such process"
My Info.plist contains an entry for the document with NSIsRelatedItemType set to YES
I am using this kind of FilePresenter code in various live apps developed some years ago. Now when starting from scratch on a fresh macOS26 system with most current Xcode I do not manage to get it running. Any ideas welcome!
Here is the code:
struct ContentView: View {
@State private var sonaImg: CGImage?
@State private var calls: Array<CallMeasurements> = Array()
@State private var soundContainer: BatSoundContainer?
@State private var importPresented: Bool = false
var body: some View {
VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundStyle(.tint)
Text("Hello, world!")
if self.sonaImg != nil {
Image(self.sonaImg!, scale: 1.0, orientation: .left, label: Text("Sonagram"))
}
if !(self.calls.isEmpty) {
List(calls) {aCall in
Text("\(aCall.callNumber)")
}
}
Button("Load sound file") {
importPresented.toggle()
}
}
.fileImporter(isPresented: $importPresented, allowedContentTypes: [.audio, UTType(filenameExtension: "raw")!], onCompletion: { result in
switch result {
case .success(let url):
let gotAccess = url.startAccessingSecurityScopedResource()
if !gotAccess { return }
if let soundContainer = try? BatSoundContainer(with: url) {
self.soundContainer = soundContainer
self.sonaImg = soundContainer.overviewSonagram(expectedWidth: 800)
let callsSidecar = CallsSidecar(withSoundURL: url)
let data = callsSidecar.readData()
print(data)
}
url.stopAccessingSecurityScopedResource()
case .failure(let error):
// handle error
print(error)
}
})
.padding()
}
}
The file presenter according to the WWDC 19 example:
class CallsSidecar: NSObject, NSFilePresenter {
lazy var presentedItemOperationQueue = OperationQueue.main
var primaryPresentedItemURL: URL?
var presentedItemURL: URL?
init(withSoundURL audioURL: URL) {
primaryPresentedItemURL = audioURL
presentedItemURL = audioURL.deletingPathExtension().appendingPathExtension("bcCalls")
}
func readData() -> Data? {
var data: Data?
var error: NSError?
NSFileCoordinator.addFilePresenter(self)
let coordinator = NSFileCoordinator.init(filePresenter: self)
NSFileCoordinator.addFilePresenter(self)
coordinator.coordinate(readingItemAt: presentedItemURL!, options: [], error: &error) {
url in
data = try! Data.init(contentsOf: url)
}
return data
}
}
And from Info.plist
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>bcCalls</string>
</array>
<key>CFBundleTypeName</key>
<string>bcCalls document</string>
<key>CFBundleTypeRole</key>
<string>None</string>
<key>LSHandlerRank</key>
<string>Alternate</string>
<key>LSItemContentTypes</key>
<array>
<string>com.apple.property-list</string>
</array>
<key>LSTypeIsPackage</key>
<false/>
<key>NSIsRelatedItemType</key>
<true/>
</dict>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>wav</string>
<string>wave</string>
</array>
<key>CFBundleTypeName</key>
<string>Windows wave</string>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>LSHandlerRank</key>
<string>Alternate</string>
<key>LSItemContentTypes</key>
<array>
<string>com.microsoft.waveform-audio</string>
</array>
<key>LSTypeIsPackage</key>
<integer>0</integer>
<key>NSDocumentClass</key>
<string></string>
</dict>
</array>
Note that BatSoundContainer is a custom class for loading audio of various undocumented formats as well as wave, Flac etc. and this is working well displaying a sonogram of the audio.
Thx, Volker
Hello, I've a question about performance when trying to render lots of items coming from SwiftData via a @Query on a SwiftUI List. Here's my setup:
// Item.swift:
@Model final class Item: Identifiable {
var timestamp: Date
var isOptionA: Bool
init() {
self.timestamp = Date()
self.isOptionA = Bool.random()
}
}
// Menu.swift
enum Menu: String, CaseIterable, Hashable, Identifiable {
var id: String { rawValue }
case optionA
case optionB
case all
var predicate: Predicate<Item> {
switch self {
case .optionA: return #Predicate { $0.isOptionA }
case .optionB: return #Predicate { !$0.isOptionA }
case .all: return #Predicate { _ in true }
}
}
}
// SlowData.swift
@main
struct SlowDataApp: App {
var sharedModelContainer: ModelContainer = {
let schema = Schema([Item.self])
let modelConfiguration = ModelConfiguration(schema: schema, isStoredInMemoryOnly: false)
return try! ModelContainer(for: schema, configurations: [modelConfiguration])
}()
var body: some Scene {
WindowGroup {
ContentView()
}
.modelContainer(sharedModelContainer)
}
}
// ContentView.swift
struct ContentView: View {
@Environment(\.modelContext) private var modelContext
@State var selection: Menu? = .optionA
var body: some View {
NavigationSplitView {
List(Menu.allCases, selection: $selection) { menu in
Text(menu.rawValue).tag(menu)
}
} detail: {
DemoListView(selectedMenu: $selection)
}.onAppear {
// Do this just once
// (0..<15_000).forEach { index in
// let item = Item()
// modelContext.insert(item)
// }
}
}
}
// DemoListView.swift
struct DemoListView: View {
@Binding var selectedMenu: Menu?
@Query private var items: [Item]
init(selectedMenu: Binding<Menu?>) {
self._selectedMenu = selectedMenu
self._items = Query(filter: selectedMenu.wrappedValue?.predicate,
sort: \.timestamp)
}
var body: some View {
// Option 1: touching `items` = slow!
List(items) { item in
Text(item.timestamp.description)
}
// Option 2: Not touching `items` = fast!
// List {
// Text("Not accessing `items` here")
// }
.navigationTitle(selectedMenu?.rawValue ?? "N/A")
}
}
When I use Option 1 on DemoListView, there's a noticeable delay on the navigation. If I use Option 2, there's none. This happens both on Debug builds and Release builds, just FYI because on Xcode 16 Debug builds seem to be slower than expected: https://indieweb.social/@curtclifton/113273571392595819
I've profiled it and the SwiftData fetches seem blazing fast, the Hang occurs when accessing the items property from the List. Is there anything I'm overlooking or it's just as fast as it can be right now?
When I try to show/hide the content in .safeAreaBar(edge: .bottom), especially the content with a large height, the background animation of the toolbar is very laggy.
iOS 26 RC
Feedback ID - FB19768797
import SwiftUI
struct ContentView: View {
@State private var isShown: Bool = false
var body: some View {
NavigationStack {
Button("Toggle") {
withAnimation {
isShown.toggle()
}
}
ScrollView(.vertical) {
ForEach(0..<100) { index in
Text("\(index)")
.padding()
.border(.blue)
.background(.blue)
.frame(maxWidth: .infinity)
}
}
.scrollEdgeEffectStyle(.soft, for: .bottom)
.safeAreaBar(edge: .bottom) {
if isShown {
Text("Safe area bar")
.padding(64)
.background(.red)
}
}
}
}
}
#Preview {
ContentView()
}
Calling contactAccessPicker results in a blank sheet and a jetsam error, rather than the expected contact picker, using Apple’s sample code, only on device with iOS 26.2.1.
This is happening on a iPhone 17 Pro Max running 26.2.1, and not on a simulator.
I’m running Apple's sample project
Accessing a person’s contact data using Contacts and ContactsUI
Steps:
Run the sample app on device running iOS 26.2.1.
Use the flow to authorize .limited access with 1 contact: Tap request access, Continue, Select Contacts. Select a contact, Continue, Allow Selected Contact. This all works as expected.
Tap the add contact button in the toolbar to add a second contact.
Expected: This should show the Contact Access Picker UI.
Actual: Sheet is shown with no contents. See screenshot of actual results on iOS device running 26.2.1.
Reported as FB21812568
I see a similar (same?) error reported for 26.1. It seems strange that the feature is completely broken for multiple point releases. Is anyone else seeing this or are the two of us running into the same rare edge case?
Expected Outcome, seen on simulator running 26.2
Actual outcome, seen on device running 26.2.1
As GKGameCenterViewController has been deprecated, it seems that GKAccessPoint is now the correct way to present the GameCentre leaderboard.
But the placement options for the GKAccessPoint are very limited and lead to misaligned UI that looks clunky, as the GKAccessPoint does not align with the system navigation toolbar.
Am I missing something here or am I just stuck with a lopsided UI now?
I much preferred how this previously worked, where I could present the GKGameCenterViewController in a sheet from my own button
I have the following code that renders a one-page PDF:
func render() -> URL {
let renderer = ImageRenderer(content: pdfView())
let url = URL.documentsDirectory.appending(path: "filename.pdf")
renderer.render { size, context in
var document = CGRect(x: 0, y: 0, width: 2550, height: 3300)
guard let pdf = CGContext(url as CFURL, mediaBox: &document, nil) else {
return
}
pdf.beginPDFPage(nil)
context(pdf)
pdf.endPDFPage()
pdf.closePDF()
}
return url
}
func pdfView() -> some View {
Text("View")
}
How can this be modified so that it renders a PDF with more than one page?
Hello,
We're having massive issues when we nest LazyVStacks inside a ScrollView. Our app relies heavily on custom views that are sometimes nested two or three levels deep. While the app does work fine overall, we see a massive spike in CPU usage in Instruments when accessibility features like VoiceOver are enabled. Those spikes never recover, so the app basically freezes and stays that way until force quit.
We are in talks with a third-party service that uses accessibility features we want to use. Fortunately they have created a GitHub repository which recreates the issue we're facing.
It would be greatly appreciated if someone could have a look at the code and tell us what the issue is, or if there's some kind of workaround.
Here's the link to the repo: https://github.com/pendo-io/SwiftUI_Hang_Reproduction.
Just to be clear, the issue is not directly related to the third-party SDK, but to the accessibility features used in conjunction with SwiftUI. As you can see in the repo the issue is reproducible without having the SDK included in the project.
Thanks in advance
I am implementing an AI chat application and aiming to achieve ChatGPT-like behavior. Specifically, when a new message is sent, the ScrollView should automatically scroll to the top to display the latest message.
I am currently using the scrollTo method for this purpose, but the behavior is inconsistent—sometimes it works as expected, and other times it does not. I’ve noticed that this issue has been reported in multiple places, which suggests it may be a known SwiftUI limitation.
I’d like to know:
Has this issue been fixed in recent SwiftUI versions, or does it still persist?
If it still exists, is there a reliable solution or workaround that anyone can recommend?
In WKWebView, there is the WKUIDelegate method:
func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? {}
This delegate method provides a callback when a new window (for example, target="_blank") is requested in the web view.
However, in native SwiftUI (iOS 26), WebView / WebPage APIs do not provide an equivalent delegate method to handle new window requests.
As a workaround, I am using the following method:
public func decidePolicy(for action: WebPage.NavigationAction, preferences: inout WebPage.NavigationPreferences) async -> WKNavigationActionPolicy {}
In this method, when action.target == nil, I treat it as a new window request.
My question:
Is relying on action.target == nil in decidePolicy a reliable and future-safe way to detect new window requests in SwiftUI’s WebView, or is there a better or more recommended approach for handling target="_blank" / new window navigation in the SwiftUI WebView APIs?
Code:
public func decidePolicy(for action: WebPage.NavigationAction, preferences: inout WebPage.NavigationPreferences) async -> WKNavigationActionPolicy {
guard let webPage = webPage else { return .cancel }
// Handle case where target frame is nil (e.g., target="_blank" or window.open)
// This indicates a new window request
if action.target == nil {
print("Target frame is nil - new window requested")
// WORKAROUND: Until iOS 26 WebPage UI protocol is available, we handle new windows here
// Try to create a new WebPage through UI plugins
if handleCreateWebPage(for: webPage, navigationAction: action) != nil {
// Note: The new WebPage has been created and published to the view
return .allow
}
}
return .allow
}
[Also submitted as FB20636175]
In iOS 26.1 Seed 2 (23B5059e), ToolbarItem menus with .bottomBar placement cause the toolbar item to disappear and rebuild after the menu is dismissed, instead of smoothly morphing back. The bottom toolbar can take 1–2 seconds to reappear.
This also seems to coincide with this console error:
Adding 'UIKitToolbar' as a subview of UIHostingController.view is not supported and may result in a broken view hierarchy. Add your view above UIHostingController.view in a common superview or insert it into your SwiftUI content in a UIViewRepresentable instead.
This occurs both on device and in a simulator.
Sample Project
This sample ContentView includes two menu buttons—one in the bottom bar and one in the top bar. Dismissing the bottom bar menu causes a short delay before the button reappears, while the top bar menu behaves normally.
struct ContentView: View {
var body: some View {
NavigationStack {
Text("Tap and dismiss both menu buttons and note the difference.")
.navigationTitle("BottomBar Menu Issue")
.navigationSubtitle("Reproduces on iOS 26.1 Seed 2 (23B5059e)")
.toolbar {
// Control: top bar trailing menu animates back smoothly
ToolbarItem(placement: .topBarTrailing) {
Menu {
Button("Dismiss", role: .cancel) { }
Button("Do Nothing") { }
} label: {
Label("More", systemImage: "ellipsis.circle")
.font(.title3)
}
}
// Repro: delay before menu button reappears after menu dismissal
ToolbarItem(placement: .bottomBar) {
Menu {
Button("Dismiss", role: .cancel) { }
Button("Do Nothing") { }
} label: {
Label("Actions", systemImage: "ellipsis.circle")
.font(.title2)
}
}
}
}
}
}
Passwords App
This can also be seen in iOS 26.1 Seed 2 (23B5059e)'s Passwords app ("All" or "Passcodes" views):
Hello,
in my widget the user displays images filling the whole widget with overlayed texts (via ZStack). Via shadows or text background color the text gets better readable.
However, when a user chooses transparent or tinted colors for the home screen, the text is barely or not readable anymore since e.g. white text on white image background. How to resolve this issue?
Topic:
App & System Services
SubTopic:
Widgets & Live Activities
Tags:
SwiftUI
Visual Design
WidgetKit
Overview
In iOS 26, a List embedded in a NavigationStack inside a TabView exhibits a visual glitch when switching tabs.
When the list is scrolled such that some rows are partially obscured by the navigation bar, the system correctly applies a fade/opacity effect to those rows. However, if the user switches to another tab while rows are in this partially obscured (faded) state, those rows briefly flash at full opacity during the tab transition before disappearing.
This flash is visually distracting and appears to be inconsistent with the intended scroll-edge opacity behavior.
The issue occurs only for rows partially obscured by the navigation bar.
Rows partially obscured by the tab bar do not exhibit this flashing behavior.
Steps to Reproduce:
Run the attached minimal reproduction on iOS 26.
Open the first tab.
Scroll the list so that some rows are partially hidden behind the navigation bar (showing the native faded appearance).
While rows are in this partially faded state, switch to the second tab.
Observe that the faded rows briefly render fully opaque during the tab switch.
Expected Behavior:
Rows that are partially obscured by the navigation bar should maintain consistent opacity behavior during tab transitions, without flashing to full opacity.
import SwiftUI
@main
struct NavBarReproApp: App {
/// Minimal repro for iOS 26:
/// - TabView with two tabs
/// - First tab: NavigationStack + List
/// - Scroll so some rows are partially behind the nav bar (faded)
/// - Switch tabs: those partially-faded rows briefly flash fully opaque. Partially faded rows under the tab bar do not flash
private let items = Array(0..<200).map { "Row \($0)" }
var body: some Scene {
WindowGroup {
TabView {
NavigationStack {
List {
ForEach(items, id: \.self) { item in
Text(item)
}
}
.navigationTitle("One")
.navigationBarTitleDisplayMode(.inline)
}
.tabItem { Label("One", systemImage: "1.circle") }
NavigationStack {
Text("Second tab")
.navigationTitle("Two")
.navigationBarTitleDisplayMode(.inline)
}
.tabItem { Label("Two", systemImage: "2.circle") }
}
}
}
}