I am noticing an issue that when .popoverTip() is presented, any tap gesture will only dismiss the tip and will not be passed down.
This means that if tip is applied to a button, tapping the button will only dismiss the tip but will not trigger the action.
Which logically breaks user expectation and defeats the whole point of a popover tip, as user will need to tap twice on the button to activate intended functionality.
Button("Settings", systemImage: "gear") {
// Will not trigger until tip is dismissed and button is tapped again.
showSettings.toggle()
}
.popoverTip(SettingsTip())
How did we do? We’d love to know your thoughts on this year’s conference. Take the survey here
SwiftUI
RSS for tagProvide views, controls, and layout structures for declaring your app's user interface using SwiftUI.
Posts under SwiftUI tag
200 Posts
Sort by:
Post
Replies
Boosts
Views
Activity
Without developer mode, I was able to get Password AutoFill to work in my SwiftUI app with my local Vapor server using ngrok and adding the Associated Domains capability with the value webcredentials:....ngrok-free.app and the respective apple-app-site-association file on my local server in /.well-known/. (works on device, but not in the simulator).
However, if I use the developer mode (webcredentials:....ngrok-free.app?mode=developer) it only works halfway when running from Xcode: I get asked to save the password, but the saved passwords are not picked up, when I try to login again. Neither on device, nor in the simulator. If I remove the ?mode=developer it seems to work as expected.
Is this by design, or am I missing something?
var body: some View {
...
Section(header: Text("Email")) {
TextField("Email", text: $viewModel.credentials.username)
.textContentType(.username)
.autocapitalization(.none)
.keyboardType(.emailAddress)
}
Section(header: Text("Passwort")) {
SecureField("Passwort", text: $viewModel.credentials.password)
.textContentType(.password)
}
...
}
Topic:
Privacy & Security
SubTopic:
General
Tags:
SwiftUI
Universal Links
Authentication Services
Autofill
I have a TextEditor, to the constructor of which in addition to the text I pass an object of the TextSelection? type. I check on the Simulator with iOS 18.2. An attempt to clear the text leads to a crash with the message "Thread 1: Fatal error: String index is out of bounds" in Xcode.
More about the error:
libswiftCore.dylib`_swift_runtime_on_report:
-> 0x194f32024 <+0>: ret
More about the reproduction conditions:
struct MyView: View {
@Bindable private var viewModel = MyViewModel()
@State var myTextSelection: TextSelection? = nil
var body: some View {
ZStack {
// Some other code
myEditor
// Some other code
}
.toolbar {
ToolbarItem(placement: .primaryAction) {
Button {
viewModel.clear()
} label: {
Label("Clear", systemImage: "eraser")
}
}
}
}
var myEditor: some View {
ZStack(alignment: .topLeading) {
TextEditor(text: $viewModel.text, selection: $myTextSelection)
.disableAutocorrection(true)
.autocapitalization(.sentences)
}
// Some other code
}
}
MyViewModel:
@Observable
final class MyViewModel: ObservableObject {
var text: String = ""
func clear() {
text = ""
}
}
Hey folks
I'm trying to use .onDrop() on a view that needs to accept files. This works fine, I specify a supportedContentTypes of [.fileURL] and it works great.
I got a request to add support for dragging the macOS screenshot previews into my app and when I looked at it, they aren't available as a URL, only an image, so I changed my array to [.fileURL, .image].
As soon as I did that, I noticed that dragging any image file, even from Finder, calls my onDrop() closure with an NSItemProvider that only knows how to give me an image, with no suggestedName.
Am I missing something here? I had been under the impression that:
The order of my supportedContentTypes indicates which types I prefer (although I now can't find this documented anywhere)
Where an item could potentially vend multiple UTTypes, the resulting NSItemProvider would offer up the union of types that both it, and I, support.
If it helps, I put together a little test app which lets you select which UTTypes are in supportedContentTypes and then when a file is dragged onto it, it'll tell you which content types are available - as far as I can tell, it's only ever one, and macOS strongly prefers to send me an image vs a URL.
Is there anything I can do to convince it otherwise?
Looking to start developing at Swift. What is the best way to get started with a job related to Swift development? Is there any specific demanded certification I could pursue?
Thank you.
Introduction
Hello,
As part of our ongoing migration to SwiftUI, we are currently managing navigation using UIKit. Our SwiftUI views are embedded in UIHostingController instances and pushed or presented via UINavigationController.
We’ve encountered an issue that causes either a UI glitch on iOS 18 or a crash on iOS 17 when using the .refreshable modifier in a SwiftUI view that is added to a UINavigationController via setViewControllers(_:animated:).
To reproduce the issue, we’re using the following simple SwiftUI view:
struct TestView: View {
var body: some View {
List {
ForEach(0...100, id: \.self) {
Text("Number: \($0)")
}
}
.refreshable {
// No action needed — the presence of this modifier alone triggers the issue
}
}
}
Problematic Scenario
The following code causes the issue:
class ViewController: UIViewController {
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let initialNav = self.navigationController
let hostingController = UIHostingController(rootView: TestView())
let newNav = UINavigationController()
// This causes a freeze (iOS 18) or crash (iOS 17)
newNav.setViewControllers([hostingController], animated: true)
initialNav?.present(newNav, animated: true)
}
}
After presenting the navigation controller, our app is freezing on iOS 18 or crashing on iOS 17.
Working scenario
When using pushViewController(_:animated:), the issue does not occur:
class ViewController: UIViewController {
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let initialNav = self.navigationController
let hostingController = UIHostingController(rootView: TestView())
let newNav = UINavigationController()
// This works without issue
newNav.pushViewController(hostingController, animated: true)
initialNav?.present(newNav, animated: true)
}
}
Conclusion
We would like to better understand the root cause of this behavior. While using pushViewController is a viable workaround, there are scenarios where we must rely on setViewControllers, and currently, that approach breaks the experience or crashes the app.
Is this a known issue, or are we missing something about how UIHostingController interacts with .refreshable in this context?
Thanks for your time — we look forward to any insights you can share.
I have a SwiftUI app. It fetches records through CoreData. And I want to show some records on a widget. I understand that I need to use AppGroup to share data between an app and its associated widget.
import Foundation
import CoreData
import CloudKit
class DataManager {
static let instance = DataManager()
let container: NSPersistentContainer
let context: NSManagedObjectContext
init() {
container = NSPersistentCloudKitContainer(name: "DataMama")
container.persistentStoreDescriptions = [NSPersistentStoreDescription(url: FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: group identifier)!.appendingPathComponent("Trash.sqlite"))]
container.loadPersistentStores(completionHandler: { (description, error) in
if let error = error as NSError? {
print("Unresolved error \(error), \(error.userInfo)")
}
})
context = container.viewContext
context.automaticallyMergesChangesFromParent = true
context.mergePolicy = NSMergePolicy(merge: .mergeByPropertyObjectTrumpMergePolicyType)
}
func save() {
do {
try container.viewContext.save()
print("Saved successfully")
} catch {
print("Error in saving data: \(error.localizedDescription)")
}
}
}
// ViewModel //
import Foundation
import CoreData
import WidgetKit
class ViewModel: ObservableObject {
let manager = DataManager()
@Published var records: [Little] = []
init() {
fetchRecords()
}
func fetchRecords() {
let request = NSFetchRequest<Little>(entityName: "Little")
do {
records = try manager.context.fetch(request)
records.sort { lhs, rhs in
lhs.trashDate! < rhs.trashDate!
}
} catch {
print("Fetch error for DataManager: \(error.localizedDescription)")
}
WidgetCenter.shared.reloadAllTimelines()
}
}
So I have a view model that fetches data for the app as shown above.
Now, my question is how should my widget get data from CoreData? Should the widget get data from CoreData through DataManager? I have read some questions here and also read some articles around the world. This article ( https://dev.classmethod.jp/articles/widget-coredate-introduction/ ) suggests that you let the Widget struct access CoreData through DataManager. If that's a correct fashion, how should the getTimeline function in the TimelineProvider struct get data? This question also suggests the same. Thank you for your reading my question.
Without using a custom preview, you can set .contentShape(RoundedRectangle(cornerRadius: 30)) so that in the "zoomed in" preview of the contextMenu you can have a custom cornerRadius. However, this does not work if you create a custom preview, because then the ContentShape gets applied only to the LIFT PREVIEW, and not to the FINAL PREVIEW state. Heres a sample code - I'd love some support! :)
import SwiftUI
struct ContentView: View {
var body: some View {
VStack {
Rectangle()
.fill(Color.blue)
.frame(width: 300, height: 300)
.cornerRadius(30)
.contentShape(.contextMenuPreview, RoundedRectangle(cornerRadius: 30))
.contextMenu {
Button("Hello") {}
Button("Goofy") {}
} preview: {
Rectangle()
.fill(Color.blue)
.frame(width: 300, height: 300)
.cornerRadius(30)
//.contentShape(RoundedRectangle(cornerRadius: 30))
//.contentShape(.contextMenuPreview, RoundedRectangle(cornerRadius: 30))
}
Text("contextMenu item with large cornerRadius is not working as expected... No way to set contentShape to custom corner radius for final preview - not the lift preview")
}
}
}
I noticed that when using .searchable inside a NavigationStack thats inside a TabView, the searchbar briefly overlays the content before disappearing. After that, it is hidden and appears as expected when swiping down.
This only happens when the .searchable is inside the NavigationStack, there is at least one navigationTitle and the NavigationStack is inside a TabView.
Tested on simulator and real device.
I would appreciate any help.
Thanks!
struct FirstScreen: View {
var body: some View {
TabView {
Tab("Tab", systemImage: "heart") {
NavigationStack {
NavigationLink {
SecondScreen()
} label: {
Text("Go to second screen")
}
.navigationTitle("First Screen")
}
}
}
}
}
struct SecondScreen: View {
@State private var text: String = ""
var body: some View {
List {
Text("Some view that extends all the way to the top")
}
.searchable(text: $text)
.navigationTitle("Second Screen")
}
}
In iOS 18, using .highPriorityGesture does not interfere with Button tap detection. However, on iOS 17 and earlier, setting a .highPriorityGesture causes the Button's tap action to stop responding.
I am using .highPriorityGesture in an attempt to support both tap and long-press gestures on a Button, which works as expected in iOS 18. However, the same implementation prevents taps on earlier versions.
Is using .highPriorityGesture on a Button not recommended in this case? Or is this an issue specific to how .highPriorityGesture behaves on iOS 17 and earlier?
Below is a sample code:
struct SampleButton: View {
let title: String
let action: () -> Void
var body: some View {
Button {
NSLog("Tapped")
action()
} label: {
Text(title)
}.highPriorityGesture(LongPressGesture(minimumDuration: 0.5).onEnded { _ in
NSLog("Long press.")
action()
})
}
}
struct ContentView: View {
var body: some View {
VStack {
SampleButton(title: "Tap or LongPress") {}
}
}
}
Environment:
Xcode: Version 16.3 (16E140)
iOS: iOS 18.4(simulator), iOS 17.5, iOS 16.4, iOS 15.2
A document-based app with NavigationSplitView shows duplicate file navigation controls on iPad.
This can be easily replicated by creating a multiplatform app in Xcode. The template app shows this behaviour when running on iPad.
This looks very much like a bug.
While trying the new ScrollPosition API I noticed that scrollTo(id: anchor:) behaves different than ScrollViewProxy.scrollTo(_: anchor:).
Consider the following example:
struct ContentView: View {
@State private var position = ScrollPosition(edge: .top)
var body: some View {
NavigationStack {
ScrollViewReader { proxy in
ScrollView {
VStack(spacing: 8) {
ForEach(1..<100) { index in
Text(verbatim: index.formatted())
.frame(maxWidth: .infinity)
.background(.gray)
.id(index)
}
}
}
.scrollPosition($position)
.toolbar {
ToolbarItemGroup(placement: .bottomBar) {
Spacer()
Button("50 (T)") {
withAnimation {
position.scrollTo(id: 50, anchor: .top)
// proxy.scrollTo(50, anchor: .top)
}
}
Button("50 (B)") {
withAnimation {
position.scrollTo(id: 50, anchor: .bottom)
// proxy.scrollTo(50, anchor: .bottom)
}
}
Spacer()
}
}
}
}
}
}
The position methods don't align top and bottom edges, but the proxy ones do.
Is this expected or is it a bug?
https://github.com/apple/sample-food-truck
Hi! I'm seeing what looks like some weird navigation issue in the Food Truck app. It's from the Live Activity that should deep link to a specific point in the app. There seems be some state where the app is not linking to the correct component. Here are my repro steps on iPhone:
Start live activity from OrderDetailView.
Navigate to Sidebar component.
Tap the Live Activity.
App opens TruckView.
The App should be opening the OrderDetailView for the Order that was passed to the Live Activity. This seems to work when the app is not currently on Sidebar.
Any ideas? I'm testing this on iPhone OS 18.4.1. Is this an issue inside NavigationSplitView? Is this an issue with how Food Truck handles deeplinking?
https://github.com/apple/sample-food-truck
Hi! I'm following along with the sample-food-truck application from WWDC 2022. I'm seeing some weird navigation issues when building the app for iPadOS.
The Table component displays a Select Button for selecting elements and a Done Button disabling that state. These buttons seem to be breaking something about navigation on iOS 18.4.1. It's a nondeterministic issue… but tapping the buttons seems to lead to some corrupt state where the app transitions out of OrdersView and back to TruckView.
This code from FoodTruckModel seems to be making a difference:
Task(priority: .background) {
var generator = OrderGenerator.SeededRandomGenerator(seed: 5)
for _ in 0..<20 {
try? await Task.sleep(nanoseconds: .secondsToNanoseconds(.random(in: 3 ... 8, using: &generator)))
Task { @MainActor in
withAnimation(.spring(response: 0.4, dampingFraction: 1)) {
self.orders.append(orderGenerator.generateOrder(number: orders.count + 1, date: .now, generator: &generator))
}
}
}
}
Commenting out that code and disabling the new Order values coming in seems to fix the issue.
Is there any public documentation for me to learn about the Select and Done buttons? I don't see anywhere for me to learn about how these work and what my ability is to customize their behavior.
Any ideas? I can repro from device and simulator.
Seeing this magical sand table, the unfolding and folding effects are similar to spreading out cards, which is very interesting. But I don't know how to achieve it. I want to see if there are any ways to achieve this effect and give some ideas. May I ask if this effect can be achieved under the existing API
In the AVP project, a selector pops up, only wanting to filter spatial videos. When selecting the material of one of the spatial videos, the selection result returns empty. How can we obtain the video selected by the user and get the path and the URL of the file
The code is as follows:
PhotosPicker(selection: $selectedItem, matching: .videos) {
Text("Choose a spatial photo or video")
}
func loadTransferable(from imageSelection: PhotosPickerItem) -> Progress {
return imageSelection.loadTransferable(type: URL.self) { result in
DispatchQueue.main.async {
// guard imageSelection == self.imageSelection else { return }
print("加载成功的图片集合:(result)")
switch result {
case .success(let url?):
self.selectSpatialVideoURL = url
print("获取视频链接:(url)")
case .success(nil):
break
// Handle the success case with an empty value.
case .failure(let error):
print("spatial错误:(error)")
// Handle the failure case with the provided error.
}
}
}
}
Using the native SwiftUI.Picker to set a @State which is then used to render different child views based on the selected state (using a switch-case inside body) seems to cause those child views to be unresponsive.
The following code below is a replicates the issue. The solution I am currently using is to build my own custom Picker that relies on SwiftUI.Buttons to set the state. This works.
enum PickerSelection: Hashable {
case binding, ownState
}
struct MainApp: View {
@State private var pickerSelection: PickerSelection? = nil
@State private var isToggled: Bool = false
var body: some View {
VStack(alignment: .leading) {
/// Changing `pickerSelection` via `SwiftUI.Picker` causes child views' toggles to be unresponsive.
Picker("Picker", selection: $pickerSelection) {
Text("No Option").tag(Optional<PickerSelection>(nil))
Text("Binding").tag(PickerSelection.binding)
Text("Own state").tag(PickerSelection.ownState)
}
/// Changing `pickerSelection` via a custom `Button`-based picker works as expected.
CustomPickerWithButtonBased(pickerSelection: $pickerSelection)
switch pickerSelection {
case .binding:
ChildViewWithBinding(isToggled: $isToggled)
case .ownState:
ChildViewManagingOwnState()
case .none:
EmptyView()
}
Spacer()
}
.padding()
}
}
struct ChildViewWithBinding: View {
@Binding var isToggled: Bool
var body: some View {
Toggle("ChildViewWithBinding", isOn: $isToggled)
}
}
struct ChildViewManagingOwnState: View {
@State private var isToggled: Bool = false
var body: some View {
Toggle("ChildViewManagingOwnState", isOn: $isToggled)
}
}
struct CustomPickerWithButtonBased: View {
@Binding var pickerSelection: PickerSelection?
var body: some View {
HStack {
Button {
pickerSelection = .binding
} label: {
Text("Binding")
}
Button {
pickerSelection = .ownState
} label: {
Text("OwnState")
}
}
}
}
Am I missing something with Picker?
Hi! I develop an iOS library and I met an issue with SwiftUI previews in iOS app project with my library integrated. After I open preview, build for preview finishes successfully, but preview itself never appears. I failed to find any error messages or any other indicators of what went wrong or how to fix it. Switching to legacy preview execution seems to fix problem, but I think that is not ideal. Could you help fixing this?
Xcode 16.2, Simulator iPhone 16, iOS 18.2
Project to reproduce -
https://drive.google.com/file/d/1cU6JKwshK_wQfe9YIqcMg3UGWq45OYlx/view?usp=sharing
Preview diagnostics - https://drive.google.com/file/d/1kPcgVSSqreiepGuqhdIoCW2rLSicgsWr/view?usp=sharing
Hello,
I tried to use the ManagedAppView component to display a list of apps, I have a text field above my list to make it searchable.
The problem is that when the keyboard appear, all my ManagedAppView components shift half of their height up, inside there list cell, so they are only half visible with the rest of the cell blank.
As the component is Apple Internal, I didn't find any solution to avoid that, is there any fix to have this component stays in place even when the keyboard appear ?
I tried to replace the ManagedAppView by other components and the issue arise only with ManagedAppView.
I'm running into a crash when trying to delete an item from a list that's loaded using SwiftData. The app works fine when selecting or displaying the data, but the moment I confirm a deletion, it crashes with this error:
SwiftData/ModelSnapshot.swift:46: Fatal error: A ModelSnapshot must be initialized with a known-keys dictionary
This happens right after I delete an item from the list using modelContext.delete(). I’ve double-checked that the item exists and is valid, and I'm not sure what I'm doing wrong. The data is loaded using @Query and everything seems normal until deletion.
For further information, I have tried this on a new IOS project where I have one super Model class with a cascading relationship on a child class. When trying to delete the parent class while connected to one or more children, it still gives me the error.
The same thing is happening with my original project. Class A has a relationship (cascading) with Class B. Attempting to delete Class A while there are relationships with Class B throws this error.
If anyone has experienced this or knows what causes it, please let me know. I’m not even sure where to start debugging this one.
Thanks in advance!