Hello Apple forum !
I spotted a weird behaviour with LazyVStack in a ScrollView. I understand that it loads its views only once upon appearance unlinke VStack that loads everything in one shot.
What I noticed also, it seems to reload its views sometimes when scrolling back up to earlier loaded views. The thing is, it isn't always the case.
struct LazyVStackTest: View {
var body: some View {
ScrollView {
LazyVStack {
ForEach(0..<1000, id: \.self) { _ in
// if true {
MyText()
// }
}
}
}
}
struct MyText: View {
var body: some View {
let _ = Self._printChanges()
HStack {
Text("hello")
}
}
}
}
If we consider the code above on XCode 26 beta 7 on an iOS 26 or iOS 18.2 simulator.
Scroll to the bottom : you'll see one "LazyVStackTest.MyText: @self changed" for each row.
Then scroll back up to the top, we'll see again the same message printed multiple times.
--> So I gather from this that LazyVStack not only loads lazily but also removes old rows from memory & recreates them upon reappearance.
What I don't get however is that if you uncomment the "if true" statement, you won't see the reloading happening. And I have absolutely no clue as to why 😅
If someone could help shed some light on this weird behaviour, it would be greatly appreciated ^^
PS : the issue is also present with XCode 16.2 but at a deeper lever (ex: if we embed another custom View "MyText2" inside "MyText", the reloading is in "MyText2" & not "MyText")
SwiftUI
RSS for tagProvide views, controls, and layout structures for declaring your app's user interface using SwiftUI.
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
When using SwiftUI's TextEditor, the application crashes immediately on launch.
This occurs even in a brand new project with the simplest usage.
If I remove the TextEditor, the application runs normally.
Environment:
OS: macOS 15.6.1
Xcode: 16.4
SDK: macOS 14 (and also tried with macOS 15 SDK)
Steps to Reproduce:
Create a new SwiftUI macOS App project.
Replace ContentView with the following code:
import SwiftUI
struct ContentView: View {
@State private var text = "114514"
var body: some View {
TextEditor(text: $text)
}
}
Run the app.
Expected Result:
The app should display a working TextEditor.
Actual Result:
The app immediately crashes, and the debugger shows a Metal assertion error.
If I remove the TextEditor, the app works fine.
Screenshot:
Additional Notes:
This issue did not occur on macOS 14 / Xcode 15.4.
It reproduces even in an empty project.
Possibly related to SwiftUI/Metal integration on macOS 15.6.1.
這樣寫更專業、清楚,Apple 工程師能快速重現和定位問題。
如果你要用中文回報也可以,我能幫你翻譯。
Topic:
UI Frameworks
SubTopic:
SwiftUI
I'm building a SwiftUI app for iPad using a NavigationSplitView as the navigation root. Below is a simplified version of the app's navigation. There are a Home Page and a Settings Page, each with its own NavigationStack. The page that appears in the detail column depends on the sidebar's selection value. The issue I'm facing is that when I navigate deeply into the Home Page's NavigationStack (e.g., to a Home Page Child view), switch to the Settings Page, and then switch back to the Home Page, the Home Page's navigation path has been reset to [] and the previous state is lost. The same issue occurs if I navigate deeply into the Settings Page (e.g., to a Settings Page Child view), switch to the Home Page, and then return to the Settings Page: the navigation state for the Settings Page is lost, and it reverts to the root of the NavigationStack. Why is this happening and how can I fix it so that switching pages in the sidebar doesn't reset the NavigationStack of each individual page in the detail column? Thank you.
struct ContentView: View {
@State var selection: String?
@State var firstPath = [String]()
@State var secondPath = [String]()
var body: some View {
NavigationSplitView {
List(selection: $selection) {
Text("Home")
.tag("home")
Text("Settings")
.tag("settings")
}
} detail: {
if selection == "home" {
HomePage(path: $firstPath)
} else {
SettingsPage(path: $secondPath)
}
}
}
}
struct HomePage: View {
@Binding var path: [String]
var body: some View {
NavigationStack(path: $path) {
NavigationLink("Home Page", value: "Home")
.navigationDestination(for: String.self) { _ in
Text("Home Page Child")
}
}
}
}
struct SettingsPage: View {
@Binding var path: [String]
var body: some View {
NavigationStack(path: $path) {
NavigationLink("Settings Page", value: "Settings")
.navigationDestination(for: String.self) { _ in
Text("Settings Page Child")
}
}
}
}
#Preview {
ContentView()
}
I've encountered a potential bug where a TextField connected to an optional value (not a string) works as expected when bound to a @State property, but won't update a @Binding property.
Here is some example code
import SwiftUI
struct ContentView: View
{
@Binding var boundValue: Double?
@State private var stateValue: Double? = 55
var body: some View
{
TextField("Bound value", value: $boundValue, format: .number)
Text("\(boundValue ?? .nan)")
TextField("State value", value: $stateValue, format: .number)
Text("\(stateValue ?? .nan)")
}
}
#Preview
{
ContentView(boundValue: .constant(42.00))
}
It's as though the optional value stored externally is preventing the value updating. Can anyone confirm whether this is intentional, or a bug?
This is in Xcode 26b6, on macOS Tahoe 26b8, but from this query it looks like the problem has existed for years.
Topic:
UI Frameworks
SubTopic:
SwiftUI
Hello !
I manage to displays tips on tvOS no issue.
However when I want to add actions, they are not visible. Is there something specific to do here ?
I just provided the actions attributes to my tips.
The documentation does not say anything more.
Thanks!
According to the UtilityWindow documentation:
• They receive FocusedValues from the focused main scene in an application, similar to commands in the main menu, which can be used to display information on the active content as the user focuses on different scenes.
This makes me think that any UtilityWindow, even across Scenes, should always receive @FocusedValues from the currently focused window of any scene.
However, the following code doesn't quite work:
@Observable class Info: Identifiable {
let id = UUID()
}
struct ExampleApp: App {
var body: some Scene {
WindowGroup {
ContentView() // Inside, it uses .focusedSceneValue(info)
}
UtilityWindow("Test") {
UtilityWindowContent()
}
}
}
struct UtilityWindowContent: View {
@FocusedValue(Info.self) var info
var body: some View {
Text(info?.id ?? "<nil>") // This always shows "<nil>"
}
}
Here's some annotated screenshots of what's happening in a project:
Menu bar commands do work with the same setup:
As a workaround, attempting to use @FocusedValue in the App struct works, but as a result, the value appears to instantiate multiple times in the background, and they re-instantiate with every focus change.
The @FocusedValue variable gets the correct instance, but it's needlessly initializing others in the background.
This is on macOS 26.0 Tahoe Beta 8 (25A5349a).
Anytime I have 1 item, then add another, the app crashes with the following error:
Swift/IntegerTypes.swift:8835: Fatal error: Double value cannot be converted to Int because it is either infinite or NaN
I'm not working with Int values though, so I'm not sure why this is happening. It's also not point me towards any specific line. I've printed out all of the values being used for the chart and none of them are showing as infinite or NaN.
The data being used is created in a View.
@State private var pieChartData: [PieChartDataPoint] = []
Then in the onAppear and onChange its gets loaded using the following function:
func getPieChartDataPoints() -> [PieChartDataPoint] {
self.map({ PieChartDataPoint(label: $0.name, value: $0.monthlyAmount()) })
}
That's an extension on a SwiftData model type I have called Recurring.
@Model
final class Recurring {
var id = UUID()
enum Kind: String, CaseIterable, Codable {
case income = "Income"
case bill = "Bill"
func plural() -> String {
switch self {
case .income:
"Income"
case .bill:
"Bills"
}
}
}
enum Frequency: String, CaseIterable, Codable, Identifiable {
var id: Frequency { self }
case weekly = "Weekly"
case biweekly = "Biweekly"
case monthly = "Monthly"
case quarterly = "Quarterly"
case annually = "Annually"
}
var name: String = ""
var kind: Kind = Kind.income
var frequency: Frequency = Frequency.biweekly
var amount: Double = 0
init(name: String, kind: Kind, frequency: Frequency, amount: Double) {
self.name = name
self.kind = kind
self.frequency = frequency
self.amount = amount
}
func amount(from cycle: Cycle) -> Double {
switch cycle {
case .weekly:
monthlyAmount() * 12 / 52
case .biweekly:
monthlyAmount() * 12 / 26
case .monthly:
monthlyAmount()
}
}
func monthlyAmount() -> Double {
switch frequency {
case .weekly:
amount * 52 / 12
case .biweekly:
amount * 26 / 12
case .monthly:
amount
case .quarterly:
amount * 4 / 12
case .annually:
amount / 12
}
}
}
Here is the DataPoint structure.
struct PieChartDataPoint: Identifiable, Equatable {
var id = UUID()
var label: String
var value: Double
}
Finally here is the chart.
Chart(sorted, content: { dataPoint in
SectorMark(
angle: .value(dataPoint.label, getValue(from: dataPoint)),
innerRadius: 50,
angularInset: 5
)
.foregroundStyle(by: .value("Label", dataPoint.label))
.cornerRadius(10)
.opacity(getSectorMarkOpacity(for: dataPoint))
})
.scaledToFill()
.chartLegend(.hidden)
.chartAngleSelection(value: $chartSelection)
.onChange(of: chartSelection, checkSelection)
For testing purposes, I have removed all of the modifiers and only had a simple SectorMark in the Chart, however, that was still crashing.
Does anyone know why this is happening?
Summary
In a SwiftUI drag-and-drop flow, the only robust way I’ve found to detect cancellation (user drops outside any destination) is to rely on the NSItemProvider created in .onDrag and run cleanup when it’s deallocated, via a custom onEnded callback tied to its lifecycle.
On iOS 26, the provider appears to be deallocated immediately after .onDrag returns (unless I keep a strong reference), so a deinit/onEnded-based cancel hook fires right away and no longer reflects the true end of the drag session.
I’d like to know:
1. Is there a supported, reliable way to detect when a drag ends outside any drop target so I can cancel and restore the source row?
2. Is the iOS 26 NSItemProvider deallocation timing a bug/regression or intended behavior?
Minimal SwiftUI Repro
This example shows:
• creating a custom NSItemProvider subclass with an onEnded closure
• retaining it to avoid immediate dealloc (behavior change on iOS 26)
• using performDrop to mark the drag as finished
import SwiftUI
import UniformTypeIdentifiers
final class DragProvider: NSItemProvider {
var onEnded: (() -> Void)?
deinit {
// Historically: called when the system drag session ended (drop or cancel).
// On iOS 26: can fire immediately after .onDrag returns unless the provider is retained.
onEnded?()
}
}
struct ContentView: View {
struct Item: Identifiable, Equatable { let id = UUID(); let title: String }
@State private var pool: [Item] = (1...4).map { .init(title: "Option \($0)") }
@State private var picked: [Item] = []
@State private var dragged: Item?
@State private var dropFinished: Bool = true
@State private var activeProvider: DragProvider? // Retain to avoid immediate dealloc
private let dragType: UTType = .plainText
var body: some View {
HStack(spacing: 24) {
// Destination list (accepts drops)
VStack(alignment: .leading, spacing: 8) {
Text("Picked").bold()
VStack(spacing: 8) {
ForEach(picked) { item in
row(item)
}
}
.padding()
.background(RoundedRectangle(cornerRadius: 8).strokeBorder(.quaternary))
.onDrop(of: [dragType], delegate: Dropper(
picked: $picked,
pool: $pool,
dragged: $dragged,
dropFinished: $dropFinished,
activeProvider: $activeProvider
))
}
.frame(maxWidth: .infinity, alignment: .topLeading)
// Source list (draggable)
VStack(alignment: .leading, spacing: 8) {
Text("Pool").bold()
VStack(spacing: 8) {
ForEach(pool) { item in
row(item)
.onDrag {
startDrag(item)
return makeProvider(for: item)
} preview: {
row(item).opacity(0.9).frame(width: 200, height: 44)
}
.overlay(
RoundedRectangle(cornerRadius: 8)
.fill(item == dragged ? Color(.systemBackground) : .clear) // keep space
)
}
}
.padding()
.background(RoundedRectangle(cornerRadius: 8).strokeBorder(.quaternary))
}
.frame(maxWidth: .infinity, alignment: .topLeading)
}
.padding()
}
private func row(_ item: Item) -> some View {
RoundedRectangle(cornerRadius: 8)
.strokeBorder(.secondary)
.frame(height: 44)
.overlay(
HStack { Text(item.title); Spacer(); Image(systemName: "line.3.horizontal") }
.padding(.horizontal, 12)
)
}
// MARK: Drag setup
private func startDrag(_ item: Item) {
dragged = item
dropFinished = false
}
private func makeProvider(for item: Item) -> NSItemProvider {
let provider = DragProvider(object: item.id.uuidString as NSString)
// NOTE: If we DO NOT retain this provider on iOS 26,
// its deinit can run immediately (onEnded fires too early).
activeProvider = provider
provider.onEnded = { [weak self] in
// Intended: run when system drag session ends (drop or cancel).
// Observed on iOS 26: may run too early unless retained;
// if retained, we lose a reliable "session ended" signal here.
DispatchQueue.main.async {
guard let self else { return }
if let d = self.dragged, self.dropFinished == false {
// Treat as cancel: restore the source item
if !self.pool.contains(d) { self.pool.append(d) }
self.picked.removeAll { $0 == d }
}
self.dragged = nil
self.dropFinished = true
self.activeProvider = nil
}
}
return provider
}
// MARK: DropDelegate
private struct Dropper: DropDelegate {
@Binding var picked: [Item]
@Binding var pool: [Item]
@Binding var dragged: Item?
@Binding var dropFinished: Bool
@Binding var activeProvider: DragProvider?
func validateDrop(info: DropInfo) -> Bool { dragged != nil }
func performDrop(info: DropInfo) -> Bool {
guard let item = dragged else { return false }
if let idx = pool.firstIndex(of: item) { pool.remove(at: idx) }
picked.append(item)
// Mark drag as finished so provider.onEnded won’t treat it as cancel
dropFinished = true
dragged = nil
activeProvider = nil
return true
}
}
}
Questions
Is there a documented, source-side callback (or best practice) to know the drag session ended without any performDrop so we can cancel and restore the item?
Has the NSItemProvider deallocation timing (for the object returned from .onDrag) changed intentionally on iOS 26? If so, what’s the recommended replacement signal?
Is there a SwiftUI-native event to observe the end of a drag session that doesn’t depend on the provider’s lifecycle?
I'm being faced with an issue when using SwiftUI's WebView on iOS 26. In many websites, the top/bottom content is unaccessible due to being under the app's toolbars. It feels like the WebView doesn't really understand the safe areas where it's being shown, because the content should start right below the navigation bar, and only when the user scrolls down, the content should move under the bar (but it's always reachable if the users scroll back up).
Here's a demo of the issue:
Here's a 'fix' by ensuring that the content of the WebView never leaves its bounds. But as you can see, it feels out of place on iOS 26 (would be fine on previous OS versions if you had a fully opaque toolbar):
Code:
struct ContentView: View {
var body: some View {
NavigationStack {
WebView(url: URL(string: "https://apple.com")).toolbar {
ToolbarItem(placement: .primaryAction) {
Button("Top content covered, unaccessible.") {}
}
}
}
}
}
Does anyone know if there's a way to fix it using some sort of view modifier combination or it's just broken as-is?
Hi, i'm using the PasteButton component to paste content from clipboard. On the docs it says that the PasteButton will handle internally permissions and will not present the prompt. But in my case seems to be not true.
I removed all the occurrencies of
UIPasteboard.general.string
since i read that this will cause the prompt to appear. Also as you can see on the code below i'm not doing fancy or weird things, even with the base component this behaviour is still there.
PasteButton(payloadType: String.self) { strings in
if let first = strings.first {
print("clipboard text: \(first)")
}
}
I can see other apps using this paste button without asking for permissions every time, but i cannot see any issue in my code.
Hello,
I am experiencing a crash in a SwiftUI app.
It happens when I place multiple views inside a ScrollView.
The crash occurs only on a physical device (it does not reproduce in the Simulator).
It happens during runtime, seemingly while SwiftUI is updating or laying out the view hierarchy.
I have not been able to determine the exact cause.
I am attaching a text file with the entire backtrace from LLDB.
swiftui_crash_backtrace
Is this a known SwiftUI issue?
Any recommendations on how to further investigate or work around it?
Any help or suggestions would be appreciated.
Xcode 16.3 / iOS 18.6.2
Thank you!
Hello!
I have experienced a weird bug in iOS 26 Beta (8) and previous beta versions. The safe area inset is not correctly aligned with the keyboard toolbar on real devices and simulators.
When you focus a new textfield the bottom safe area is correctly placed aligned the keyboard toolbar.
On real devices the safe area inset view is covered slightly by the keyboard toolbar, which is even worse than on the simulator.
Here's a clip from a simulator:
Here's the code that reproduced the bug I experienced in our app.
#Preview {
NavigationStack {
ScrollView {
TextField("", text: .constant(""))
.padding()
.background(Color.secondary)
TextField("", text: .constant(""))
.padding()
.background(Color.green)
}
.padding()
.safeAreaInset(edge: .bottom, content: {
Color.red
.frame(maxWidth: .infinity)
.frame(height: 40)
})
.toolbar {
ToolbarItem(placement: .keyboard) {
Button {} label: {
Text("test")
}
}
}
}
}
have a SwiftUI View where I can edit financial transaction information. The data is stored in SwiftData. If I enter a TextField element and start typing, it is super laggy and there are hangs of 1-2 seconds between each input (identical behaviour if debugger is detached). On the same view I have another TextField that is just attached to a @State variable of that view and TextField updates of that value work flawlessly. So somehow the hangs must be related to my SwiftData object but I cannot figure out why.
This used to work fine until a few months ago and then I could see the performance degrading.
I have noticed that when I use a placeholder variable like
@State private var transactionSubject: String = ""
and link that to the TextField, the performance is back to normal. I am then using
.onSubmit {
self.transaction.subject = self.transactionSubject
}
to update the value in the end but this again causes a 1 s hang. :/
Below the original code sample with some unnecessary stuff removed:
struct EditTransactionView: View {
@Environment(\.modelContext) var modelContext
@Environment(\.dismiss) var dismiss
@State private var testValue: String = ""
@Bindable var transaction: Transaction
init(transaction: Transaction) {
self.transaction = transaction
let transactionID = transaction.transactionID
let parentTransactionID = transaction.transactionMasterID
_childTransactions = Query(filter: #Predicate<Transaction> {item in
item.transactionMasterID == transactionID
}, sort: \Transaction.date, order: .reverse)
_parentTransactions = Query(filter: #Predicate<Transaction> {item in
item.transactionID == parentTransactionID
}, sort: \Transaction.date, order: .reverse)
print(_parentTransactions)
}
//Function to keep text length in limits
func limitText(_ upper: Int) {
if self.transaction.icon.count > upper {
self.transaction.icon = String(self.transaction.icon.prefix(upper))
}
}
var body: some View {
ZStack {
Form{
Section{
//this one hangs
TextField("Amount", value: $transaction.amount, format: .currency(code: Locale.current.currency?.identifier ?? "USD"))
//this one works perfectly
TextField("Test", text: $testValue)
HStack{
TextField("Enter subject", text: $transaction.subject)
.onAppear(perform: {
UITextField.appearance().clearButtonMode = .whileEditing
})
Divider()
TextField("Select icon", text: $transaction.icon)
.keyboardType(.init(rawValue: 124)!)
.multilineTextAlignment(.trailing)
}
}
}
.onDisappear(){
if transaction.amount == 0 {
// modelContext.delete(transaction)
}
}
.onChange(of: selectedItem, loadPhoto)
.navigationTitle("Transaction")
.navigationBarTitleDisplayMode(.inline)
.toolbar{
Button("Cancel", systemImage: "trash"){
modelContext.delete(transaction)
dismiss()
}
}
.sheet(isPresented: $showingImagePickerView){
ImagePickerView(isPresented: $showingImagePickerView, image: $image, sourceType: .camera)
}
.onChange(of: image){
let data = image?.pngData()
if !(data?.isEmpty ?? false) {
transaction.photo = data
}
}
.onAppear(){
cameraManager.requestPermission()
setDefaultVendor()
setDefaultCategory()
setDefaultGroup()
}
.sheet(isPresented: $showingAmountEntryView){
AmountEntryView(amount: $transaction.amount)
}
}
}
}
I have a custom list and I want to make the names in the list editable through double tap. I know how to solve this hacky ways.
But are there no solid way to achieve this? like having .disabled without graying it out?
Topic:
UI Frameworks
SubTopic:
SwiftUI
The following code shows that a selected button in a list gots blurred if a glass effect is applied to the list. This happens if the button style is plain or glass. It does not happen if the button style is bordered. Is this a wanted documented behavior or is this a bug?
struct ContentView: View {
@State private var items = [
"Item 1", "Item 2", "Item 3", "Item 4"]
var body: some View {
ZStack {
Image(systemName: "globe")
.resizable()
List(items, id: \.self) { item in
Button(action: {}, label: { Text(item) })
}
.padding()
.glassEffect(in: Rectangle())
}
}
}
Environment
iOS Version: iOS 26 Beta 8
Xcode Version: iOS 26 Beta 6
StoreKit: StoreKit 2
Description
When calling AppStore.showManageSubscriptions(in:) on iOS 26 beta, I'm experiencing an unusual presentation behavior that wasn't present in earlier versions.
An empty/blank view appears first
Then the actual StoreKit manage subscriptions sheet appears on top
When dismissing the StoreKit sheet, it closes properly
But then I have to dismiss the empty view underneath as well
This creates a poor user experience showing double sheets.
Code Sample
@MainActor
func showManageSubscriptions() {
guard let scene = UIApplication.shared.connectedScenes
.first(where: { $0 is UIWindowScene }) as? UIWindowScene else {
return
}
Task {
do {
try await AppStore.showManageSubscriptions(in: scene)
} catch {
// Handle error
}
}
}
Expected Behavior
The StoreKit manage subscriptions sheet should present directly without any intermediate empty view, as it did in previous iOS versions.
Actual Behavior
An empty view layer appears between my app and the StoreKit sheet, requiring users to dismiss twice.
Questions
Is anyone else experiencing this issue with iOS 26 beta?
Is this a known beta issue that will be addressed?
Are there any recommended workarounds while waiting for a fix?
Hello,
I’ve encountered what seems to be a bug with the keyboard dismissal animation on iOS 26.0 Beta (25A5349a), Xcode Version 26.0 beta 5 (17A5295f).
When dismissing the keyboard from a SwiftUI TextField using @FocusState, the keyboard does not animate downward as expected. Instead, it instantly disappears, which feels jarring and inconsistent with system behavior.
I am attaching a short video demonstrating the issue. Below is the minimal reproducible code sample:
//
// ContentView.swift
// TestingKeyboardDismissal
//
// Created by Sasha Morozov on 27/08/25.
//
import SwiftUI
struct ContentView: View {
@State private var text: String = ""
@FocusState private var isFocused: Bool
var body: some View {
ZStack {
Color.clear.ignoresSafeArea()
VStack(spacing: 20) {
TextField("Enter text here...", text: $text)
.textFieldStyle(.roundedBorder)
.focused($isFocused)
.padding(.horizontal)
HStack {
Button("Focus") { isFocused = true }
.buttonStyle(.borderedProminent)
Button("Unfocus") { isFocused = false }
.buttonStyle(.bordered)
}
}
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .center)
.padding()
}
.ignoresSafeArea(.keyboard, edges: .bottom)
}
}
#Preview {
ContentView()
}
Steps to reproduce:
Run** the app on iOS 26.0 beta 5 (17A5295f).
Tap Focus → keyboard appears as expected.
Tap Unfocus → keyboard disappears instantly without the usual slide-down animation.
Expected result:
Keyboard should animate smoothly downwards when dismissed.
Actual result:
Keyboard instantly vanishes without animation.
p.s. we should be really able to upload videos here for demostration
I really enjoyed using SwiftData for persistence until I found out that the CloudKit integration ensures changes are only eventually consistent, and that changes can propagate to other devices after as long as minutes, making it useless for any feature that involves handoff between devices. Devastating news but I guess it’s on me for nrtfm. I may try my hand at a custom model context DataStore integrating Powersync, but that’s a whole trip and before I embark on it I was wondering if anyone had suggestions for resolving this problem in a simple and elegant manager that allows me to keep as much of the machinery within Apple’s ecosystem as possible, while ensure reliable “live” updates to SwiftData stores on all eligible devices.
Hi guys!
I wanted to study this new ManipulationComponent(), but I keep getting a warning that I don’t understand, even in a very simple scenario.
i don't have any collisions just binding the Manipulation
the warning message is :
** Entity returned from EntityWrapper.makeEntity(context:) was already parented to another entity. This is not supported and may lead to unexpected behavior. SwiftUI adds entities to internally-managed entity hierarchies.**
RealityView { content, attachments in
if let loadedModel = try? await Entity(named: "cloud_glb", in: realityKitContentBundle) {
content.add(loadedModel)
loadedModel.components.set(ManipulationComponent())
}
Thanks !
In my SwiftUI iOS app, I need to detect which key (and modifier flags – Command, Option, Shift, Control) a user presses, but I don't want to pre-register them using .keyboardShortcut(_:modifiers:).
My use case is that keyboard shortcuts are user-configurable, so I need to capture the actual key + modifier combination dynamically at runtime and perform the appropriate action based on the user’s settings.
Questions:
What is the recommended way to detect arbitrary key + modifier combinations in SwiftUI on iOS?
Is there a SwiftUI-native solution for this, or should I rely on UIPressesEvent and wrap it with UIViewControllerRepresentable?
If UIKit bridging is necessary, what is the cleanest pattern for integrating this with SwiftUI views (e.g., Buttons)?
Any official guidance or best practices would be greatly appreciated!