In visionOS, is there a way to temporarily hide the window close/position handle at the bottom of a window?
The Safari app does this, so it must be possible.
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
Following on from this thread: https://developer.apple.com/forums/thread/805037 my list of items is now correctly maintaining state (no more disappearing rows), but I'm now hitting a really annoying issue: Every time something changes - even just changing the dark mode of the device - the entire list of items is refreshed, and the list jumps back to the top.
A simple representation:
// modelData.filteredItems is either all items or some items, depending on whether the user is searching
List {
ForEach(modelData.filteredItems) { item in
ItemRow(item: item)
}
}
When the user isn't searching, filteredItems has everything in it. When they turn on search, I filter and sort the data in place:
// Called when the user turns on search, or when the searchString or searchType changes
func sortAndFilterItemsInModelData() {
modelData.filteredItems.removeAll() // Remove all items from the filtered array
modelData.filteredItems.append(contentsOf: modelData.allItems) // Add all items back in
let searchString: String = modelData.searchString.lowercased()
switch(modelData.searchType) {
case 1:
// Remove all items from the filtered array that don't match the search string
modelData.filteredItems.removeAll(where: { !$0.name.lowercased().contains(searchString) })
...
}
// Sorting
switch(modelData.sortKey) {
case sortKeyDate:
modelData.sortAscending ? modelData.filteredItems.sort { $0.date < $1.date } : modelData.filteredItems.sort { $0.date > $1.date } // Sorts in place
...
}
}
The method doesn't return anything because all the actions are done in place on the data, and the view should display the contents of modelData.filteredItems.
If you're searching and there are, say 10 items in the list and you're at the bottom of the list, then you change the search so there are now 11 items, it jumps back to the top rather than just adding the extra ItemRow to the bottom. Yes, the data is different, but it hasn't been replaced; it has been altered in place.
The biggest issue here is that you can simply change the device to/from Dark Mode - which can happen automatically at a certain time of day - and you're thrown back to the top of the list. The array of data hasn't changed, but SwiftUI treats it as though it has.
There's also a section in the List that can be expanded and contracted. It shows or hides items of a certain type. When I expand it, I expect the list to stay in the same place and just show the extra rows, but again, it jumps to the top. It's a really poor user experience.
Am I doing something wrong (probably, yes), or is there some other way to retain the scroll position in a List? The internet suggests switching to a LazyVStack, but I lose left/right swipe buttons and the platform-specific styling.
Thanks.
I’m really frustrated with iOS 26. It was supposed to make better use of screen space, but when you combine the navigation bar, tab bar, and search bar, they eat up way too much room.
Apple actually did a great job with the new tab bar — it’s smaller, smooth, and looks great when expanding or collapsing while scrolling. The way the search bar appears above the keyboard is also really nice.
But why did they keep the navigation bar the same height in both portrait and landscape? In landscape it takes up too much space and just looks bad. It was way better in iOS 18.
I have a custom input view in my app which is .focusable(). It behaves similar to a TextField, where it must be focused in order to be used.
This works fine on all platforms including iPad, except when when an external keyboard is connected (magic keyboard), in which case it can't be focused anymore and becomes unusable.
Is there a solution to this, or a workaround? My view is very complex, so simple solutions like replacing it with a native view isn't possible, and I must be able to pragmatically force it to focus.
Here's a very basic example replicating my issue. Non of the functionality works when a keyboard is connected:
struct FocusableTestView: View {
@FocusState private var isRectFocused: Bool
var body: some View {
VStack {
// This text field should focus the custom input when pressing return:
TextField("Enter text", text: .constant(""))
.textFieldStyle(.roundedBorder)
.onSubmit {
isRectFocused = true
}
.onKeyPress(.return) {
isRectFocused = true
return .handled
}
// This custom "input" should focus itself when tapped:
Rectangle()
.fill(isRectFocused ? Color.accentColor : Color.gray.opacity(0.3))
.frame(width: 100, height: 100)
.overlay(
Text(isRectFocused ? "Focused" : "Tap me")
)
.focusable(true, interactions: .edit)
.focused($isRectFocused)
.onTapGesture {
isRectFocused = true
print("Focused rectangle")
}
// The focus should be able to be controlled externally:
Button("Toggle Focus") {
isRectFocused.toggle()
}
.buttonStyle(.bordered)
}
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .center)
}
}
I have a List containing ItemRow views based on an ItemDetails object. The content is provided by a model which pulls it from Core Data.
When I scroll through the list one or two of the rows will disappear and reappear when I scroll back up. I have a feeling it's because the state is being lost?
Here's some relevant info (only necessary parts of the files are provided):
-- ModelData.swift:
@Observable
class ModelData {
var allItems: [ItemDetails] = coreData.getAllItems()
...
}
-- ItemDetails.swift:
struct ItemDetails: Identifiable, Hashable, Equatable {
public let id: UUID = UUID()
public var itemId: String // Also unique, but used for a different reason
...
}
-- MainApp.swift:
let modelData: ModelData = ModelData() // Created as a global
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
// Methods in here (and in lots of other places) use `modelData`, which is why it's a global
}
@main
struct MainApp: App {
var body: some Scene {
WindowGroup {
MainView()
}
}
...
}
-- MainView.swift:
struct MainView: View {
var body: some View {
List {
ForEach(modelData.allItems, id: \.id) { item in
ItemRow(item)
}
}
}
}
struct ItemRow: View, Equatable {
var item: ItemDetails
var body: some View {
...
}
static func == (lhs: Self, rhs: Self) -> Bool {
lhs.item == rhs.item
}
}
There's obviously more code in the app than that, but it's not relevant to the issue.
I've tried:
ItemRow(item).equatable()
Wrapping ItemRow in an EquatableView
Giving the List a unique id
Using class ModelData: ObservableObject and @StateObject for modelData
None made any difference.
I'm using iOS/iPadOS 26.0.1, and I see it on my physical iPhone 17 Pro Max and iPad Pro 11-inch M4, but I don't see it in the equivalent simulators on those versions. The Simulator also doesn't exhibit this for versions 17.5 and 18.5, and I have no physical devices on 17.5/18.5 to check.
Should I be doing as I currently am, where I create modelData as a global let so I can access it everywhere, or should I pass it through the view hierarchy as an Environment variable, like @Environment(ModelData.self) var modelData: ModelData? Bear in mind that some functions are outside of the view hierarchy and cannot access modelData if I do this. Various things like controllers that need access to values in modelData cannot get to it.
Any ideas? Thanks.
Hello,
Whenever I put accessibility focus on an image and if image has some text in it, voiceover reads that text along with image's accessibility label.
Is there a way to programmatically turn off text recognition on images for accessibility?
I couldn't find any relevant accessibility API's that could help here.
Thanks!
Hi! I am learning Swift and UIKit for work. I am trying to automate using a pickerWheel in VisionOS, but since .adjust(toValue: ) was removed in VisionOS's API, I am absolutely struggling to find a way to set a pickerWheel to a specific value.
Currently, my solution is to calculate the amount of times I would need to increment/decrement the wheel to get from the current value to the desired value, then do so one at a time. However, this currently does not work, as .accessibilityIncrement() and .accessibilityDecrement() do not work, and .swipeUp() and .swipeDown() go too far. What can I do?
Note: I am not a frontend engineer, so while solutions may exist that involve changes to the frontend, I would much rather try and get the frontend we do have to work as is.
I’m building a macOS document based app using SwiftUI’s DocumentGroup API. By default, when a document based app launches, macOS automatically shows a file open panel or creates a new untitled document window.
However, I want to suppress this default behavior and instead show a custom welcome window when the app starts — something similar to how Xcode or Final Cut Pro shows a “Welcome” or “Start Project” screen first.
So basically, when the user opens the app normally, it should not open the document selector or create a document automatically. Instead, it should show my custom SwiftUI or AppKit window. Here is my Code :-
//MyApp.swift
import SwiftUI
import AppKit
@main
struct PhiaApp: App {
@NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
var body: some Scene {
DocumentGroup(newDocument: MyDocumentModel()) { file in
EditorView(document: file.document, filePath: file.fileURL)
}
Settings { EmptyView() }
}
}
Current I have this code setup for my MainApp.swift, where I am using the AppDelegate to create a custom recording window using appkit and also defining the DocumentGroup to handle the custom .myapp file opens. However, when I launch the app, its showing my appkit window as well as the macOs native file Selector to select the file I want to open.
I want when the user opens the app normally, it should not open the document selector or create a document automatically. Instead, it should show my custom SwiftUI or AppKit window. However, the app should still fully support opening .myapp documents by double clicking from Finder, using the standard File → Open and File → New menu options, also having multiple document windows open at once.
This is my AppDelegate.swift file :-
import AppKit
import SwiftUI
class AppDelegate: NSObject, NSApplicationDelegate {
var panel: Panel?
private var statusItem: NSStatusItem?
func applicationDidFinishLaunching(_ notification: Notification) {
showWindow()
}
// MARK: - Window control
func showWindow() {
if panel == nil {
let root = RecordingViewMain()
let newPanel = Panel(rootView: root)
if let screen = NSScreen.main {
let size = NSSize(width: 360, height: 240)
let origin = NSPoint(
x: screen.visibleFrame.midX - size.width / 2,
y: screen.visibleFrame.midY - size.height / 2
)
newPanel.setFrame(NSRect(origin: origin, size: size), display: true)
}
panel = newPanel
}
panel?.makeKeyAndOrderFront(nil)
}
func hideWindow() {
panel?.orderOut(nil)
}
@objc private func showPanelAction() {
showWindow()
}
@objc private func quitAction() {
NSApp.terminate(nil)
}
}
When I update the macOS from 15.5 to 15.6, Preview error.
1、I try remove simulator cache, sdk
2、remove Xcode build cache
3、reinstall Xcode
4、try with this method https://byby.dev/uninstall-xcode#:%7E:text=Delete%20old%20simulators%20and%20devices,moving%20them%20to%20the%20Trash
but all failed
swiftui log.txt
onContinueUserActivity(CSSearchableItemActionType, perform) works as expected on iOS when we search and select an item from Spotlight, but nothing happens when we do the same on a SwiftUI macOS app.
var body: some Scene {
WindowGroup {
MyView()
.onContinueUserActivity(CSSearchableItemActionType, perform: handleSpotlight)
}
}
func handleSpotlight(_ userActivity: NSUserActivity) {
// Is not called...
}
How can we respond to a user clicking a Spotlight result from our apps on macOS?
Hi, I have started app development fairly recently and I decided to develop for Apple due to the fact that my school uses iPads and they were so convincing that I decided to buy more Apple products adding to the experience with the iPad such as a Mac where I learned Xcode, Swift and SwiftUI as far as I could comprehend.
I am working on a document based app for my school and I want to implement a toolbar that’s user customizable. There seems to be no way to get a customizable toolbar running on iPadOS26 though iPadOS16 has supported this feature and it has been till 18, I believe. I have set up a doc-based app in Xcode and that and all of its views do work except the toolbar that I added to my NavigationSplitView. The items show, when their defaultCustomization isn’t set to .hidden. The toolbar is given an id and the items are all wrapped in the ToolbarItem structure that also is given an id and the placement of .secondaryAction. The items show up and behave as expected in terms of grouping and making space if there isn’t enough room for all items so some appear in the overflow menu. From apps like Preview, Reminders and MindNode I know that the customization is supposed to still be available but it lives in the menu bar, where I haven’t seen it under view. It seems like there is a thing that my toolbar does not conform to or that there is a method that‘s called, when the user wants to customize the toolbar that I don’t know about. I would much appreciate a quick fix, solution or suggestion.
Any idea how to achieve this?
I've tried:
ToolbarItemGroup(placement: .principal)
and
ToolbarItem(placement: .principal)
also tried with a VStack but it does not work.
'm trying to write my own stack, and the issue I'm encountering is how to get the child content of a ForEach.
//
// ContentView.swift
// test
//
// Created by cnsinda on 2025/10/18.
//
import SwiftUI
public struct MyStack<Content: View>: View {
var content: [Content]
public init(@MyStackBuilder<Content> content: @escaping () -> [Content]) {
self.content = content()
}
public var body: some View {
VStack {
// I expect to get 9, but it always returns 1.
Text("count:\(content.count)")
}
}
}
@resultBuilder public enum MyStackBuilder<Value: View> {
static func buildBlock() -> [Value] {
[]
}
public static func buildBlock(_ components: Value...) -> [Value] {
components
}
public static func buildBlock(_ components: [Value]...) -> [Value] {
components.flatMap {
$0
}
}
// hit
public static func buildExpression(_ expression: Value) -> [Value] {
[expression]
}
public static func buildArray(_ components: [[Value]]) -> [Value] {
components.flatMap { $0 }
}
static func buildFinalResult(_ components: [Value]) -> [Value] {
components
}
public static func buildExpression(_ expression: ForEach<[Int], Int, Value>) -> [Value] {
expression.data.flatMap { index in
[expression.content(index)]
}
}
public static func buildEither(first: [Value]) -> [Value] {
return first
}
public static func buildEither(second: [Value]) -> [Value] {
return second
}
public static func buildIf(_ element: [Value]?) -> [Value] {
return element ?? []
}
}
struct ContentView: View {
var body: some View {
ZStack {
MyStack {
ForEach([100, 110, 120, 130, 140, 150, 160, 170, 180], id: \.self) {
item in
Rectangle().frame(width: item, height: 20).padding(10)
}
}
}
.frame(width: 600, height: 600)
}
}
My expectation is to get each individual Rectangle(), but the actual result is that the entire ForEach is treated as a single View. What should I do?
I have a SwiftUI View containing a basic NavigationStack structure. I host this in a UIHostingController and display modally as a sheet in UIKit using UIViewController.present().
Problem: When I rotate my iOS device to landscape from portrait, the navigation bar's back button extends past the safe area into the left corner of the device. Then, rotating back to portrait the back button is pushed further towards the center - not matching the intended position. (see images below).
Is there an API call I am missing to handle this rotation case? Thanks!
Code Example
SwiftUI view - ContentView.swift
import SwiftUI
struct ContentView: View {
var body: some View {
NavigationStack {
Form {
NavigationLink {
Form {
Text("Hello")
}
.navigationTitle("Filter")
.navigationBarTitleDisplayMode(.inline)
} label: {
Text("Filter")
}
}
.navigationTitle("Filter")
.navigationBarTitleDisplayMode(.inline)
}
}
}
Main UIKit ViewController - ViewController.swift
import UIKit
import SwiftUI
class ViewController: UIViewController {
let swiftUIView = ContentView()
var hostingController: UIHostingController<ContentView>?
override func viewDidLoad() {
super.viewDidLoad()
hostingController = UIHostingController(rootView: swiftUIView)
guard let hostingController else { return }
hostingController.modalPresentationStyle = .formSheet
// Immediately present modally
DispatchQueue.main.async {
self.present(hostingController, animated: true)
}
}
}
More Detail
The issue only seems to appear for sheet modal presentation including these UIModalPresentationStyle:
.formSheet
.pageSheet
.popover
The issue does not appear in an app with SwiftUI app lifecycle or when using UIKit and adding the hosting controller as a child view controller. This specifically happens when presenting modally and when the view gets rendered as a sheet.
I tried various combinations of UIHostingController.sizingOptions and UIHostingController.safeAreaRegions, but never found something that fixed the issue.
To Build and Reproduce
Make a new Xcode project > iOS > App > Storyboard UI
Add file ContentView.swift with contents above.
Replace contents of existing file ViewController.swift with contents above.
Set minimum deployment target to iOS 18
Build and deploy to device running iOS 18.
Hold device in portrait.
Rotate device to landscape - observe back button extends past safe area.
Rotate device to portrait - observe back button is shifted too far towards the center.
Device & Builds Specs
iOS 18.6.2 - minimum deployment of 18.0
Devices Observed:
iPhone 12 Pro Max
iPhone 16 Pro Max
Xcode 26
Image Examples
I am currently developing a macOS app that can show system HUDs in the Notch
Till Sequoia I used to kill the OSDUIHelper process (which displays the default macOS Volume and Brightness control HUDs) - and replaced it with my app's HUDs
But, it is not working on macOS Tahoe anymore as the OSDUIHelper process is no longer there due to the UI changes
Has the process been renamed - or is there any other way to kill the process?
Topic:
App & System Services
SubTopic:
Processes & Concurrency
Tags:
Swift
macOS
SwiftUI
Background Tasks
I'm developing an iOS application in Swift that performs API calls using URLSession.shared. The requests work correctly when the app is in the foreground. However, when the app transitions to the background (for example, when the user switches to another app), the ongoing API calls are either paused or do not complete as expected.
What I’ve tried:
Using URLSession.shared.dataTask(with:) to initiate the API requests
Observing application lifecycle events like applicationDidEnterBackground, but haven't found a reliable solution to allow requests to complete when backgrounded
Goal:
I want certain API requests to continue running or be allowed to complete even if the app enters the background.
Question:
What is the correct approach to allow API calls to continue running or complete when the app moves to the background?
Should I be using a background URLSessionConfiguration instead of URLSession.shared?
If so, how should it be properly configured and used in this scenario?
I'm developing an iOS application in Swift that performs API calls using URLSession.shared. The requests work correctly when the app is in the foreground. However, when the app transitions to the background (for example, when the user switches to another app), the ongoing API calls are either paused or do not complete as expected.
What I’ve tried:
Using URLSession.shared.dataTask(with:) to initiate the API requests
Observing application lifecycle events like applicationDidEnterBackground, but haven't found a reliable solution to allow requests to complete when backgrounded
Goal:
I want certain API requests to continue running or be allowed to complete even if the app enters the background.
Question:
What is the correct approach to allow API calls to continue running or complete when the app moves to the background?
Should I be using a background URLSessionConfiguration instead of URLSession.shared?
If so, how should it be properly configured and used in this scenario?
When showing an Alert from within a Popover that has a fixed height, the newly presented Alert is in the same position but gets limited by the Popovers height causing the title of the Alert to be hidden. Is this intentional behavior or are Alerts not supported within Popovers and I'd have to pass it through to my main view?
Code:
//
// DemoalertPopover.swift
// ********
//
// Created by Thilo on 26.06.2023.
//
import SwiftUI
struct DemoAlertPopover: View {
@Environment(\.dismiss) var dismiss
@State private var showDeleteConfirmation = false
let dateFormatter: DateFormatter = {
let formatter = DateFormatter()
formatter.dateFormat = "dd.MM.yyyy"
return formatter
}()
var body: some View {
VStack(alignment: .leading, spacing: 0) {
HStack {
Text("Title").font(.extraLargeTitle).lineLimit(1)
Spacer()
Button(action: {
dismiss()
}) {
Label("Close", systemImage: "xmark").labelStyle(.iconOnly)
}
}
HStack(alignment: .center) {
Text("Content").font(.largeTitle)
Text("Content2").foregroundStyle(.secondary)
}
LazyVGrid(columns: [GridItem(.flexible(), spacing: 10),GridItem(.flexible(), spacing: 10),], spacing: 10) {
Button(action: {
showDeleteConfirmation = true
}) {
ZStack{
Image(systemName: "trash.fill").resizable().foregroundColor(.primary)
}.aspectRatio(1/1,contentMode: .fit)
.frame(maxWidth: .infinity).padding(5)
}.aspectRatio(3/1,contentMode: .fit)
}.alert("Are you sure you want to delete ...?", isPresented: $showDeleteConfirmation) {
Button("Trash",role: .destructive, action: {
print("Deleted")
dismiss()
})
Button("Cancel", role: .cancel) {}
} message: {
Text("This is a small message below the title, just so you know.")
}
}
.padding(.all, 10).frame(width: 300)
}
}
#Preview {
DemoAlertPopover()
}
Video:
https://www.youtube.com/shorts/31Kl7qbJIiA
Hi there,
Upon using List View for tabular information showcase on both iOS and iPadOS, I have come to realize that the drag and drop support works only for iPadOS but not iOS.
Although it is possible to workaround this by using a ScrollView wrapping around a LazyVStack instead, the editing mode along with left-wipe to delete feature would be missing. Not to mention that this workaround only supports single item rather than multiple items.
Therefore, I am here to ask if the drag and drop will come to support devices running iOS, and if so, when will this feature ship. If not, will LazyVStack/LazyHStack support native editing mode.
Thank you for your time.
When a TextField is set to a rightToLeft layout, it gets strange and unnecessary padding on the left side. This pushes the text away from the edge. This issue doesn't occur in the leftToRight layout, where the text aligns correctly. Does anyone know how to get rid of this extra padding?
Environment:
Xcode version: 26.0.1
Device: iPhone 13
iOS version: 26.0
Code:
struct ContentView: View {
@State var textInput: String = ""
var body: some View {
VStack {
Text("rightToLeft")
TextField("placeholder", text: $textInput)
.background(Color.red)
.environment(\.layoutDirection, .rightToLeft)
Text("leftToRight")
TextField("placeholder", text: $textInput)
.background(Color.red)
.environment(\.layoutDirection, .leftToRight)
}
.padding()
}
}