import SwiftUI
struct ContentView: View {
@State private var selection = 1
var body: some View {
TabView(selection: $selection) {
Tab("1", systemImage: "1.circle", value: 1) {
Text("Tab 1")
}
Tab("2", systemImage: "2.circle", value: 2) {
Text("Tab 2")
}
}
.tabViewBottomAccessory {
if selection == 1 {
Text("Bottom Bar for Tab 1")
}
}
}
}
With this structure, I'm supposing when I select tab 2, the bottom accessory will be hidden, but it is not hidden for the first time, after I click back to tab 1, then click tab 2, it is hidden.
I think this is a bug?
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
I’m trying to customize the keyboard focus appearance in SwiftUI.
In UIKit (see WWDC 2021 session Focus on iPad keyboard navigation), it’s possible to remove the default UIFocusHaloEffect and change a view’s appearance depending on whether it has focus or not.
In SwiftUI I’ve tried the following:
.focusable() // .focusable(true, interactions: .activate)
.focusEffectDisabled()
.focused($isFocused)
However, I’m running into several issues:
.focusable(true, interactions: .activate) causes an infinite loop, so keyboard navigation stops responding
.focusEffectDisabled() doesn’t seem to remove the default focus effect on iOS
Using @FocusState prevents Space from triggering the action when the view has keyboard focus
My main questions:
How can I reliably detect whether a SwiftUI view has keyboard focus? (Is there an alternative to FocusState that integrates better with keyboard navigation on iOS?)
What’s the recommended way in SwiftUI to disable the default focus effect (the blue overlay) and replace it with a custom border?
Any guidance or best practices would be greatly appreciated!
Here's my sample code:
import SwiftUI
struct KeyboardFocusExample: View {
var body: some View {
// The ScrollView is required, otherwise the custom focus value resets to false after a few seconds. I also need it for my actual use case
ScrollView {
VStack {
Text("First button")
.keyboardFocus()
.button {
print("First button tapped")
}
Text("Second button")
.keyboardFocus()
.button {
print("Second button tapped")
}
}
}
}
}
// MARK: - Focus Modifier
struct KeyboardFocusModifier: ViewModifier {
@FocusState private var isFocused: Bool
func body(content: Content) -> some View {
content
.focusable() // ⚠️ Must come before .focused(), otherwise the FocusState won’t be recognized
// .focusable(true, interactions: .activate) // ⚠️ This causes an infinite loop, so keyboard navigation no longer responds
.focusEffectDisabled() // ⚠️ Has no effect on iOS
.focused($isFocused)
// Custom Halo effect
.padding(4)
.overlay(
RoundedRectangle(cornerRadius: 18)
.strokeBorder(
isFocused ? .red : .clear,
lineWidth: 2
)
)
.padding(-4)
}
}
extension View {
public func keyboardFocus() -> some View {
modifier(KeyboardFocusModifier())
}
}
// MARK: - Button Modifier
/// ⚠️ Using a Button view makes no difference
struct ButtonModifier: ViewModifier {
let action: () -> Void
func body(content: Content) -> some View {
content
.contentShape(Rectangle())
.onTapGesture {
action()
}
.accessibilityAction {
action()
}
.accessibilityAddTraits(.isButton)
.accessibilityElement(children: .combine)
.accessibilityRespondsToUserInteraction()
}
}
extension View {
public func button(action: @escaping () -> Void) -> some View {
modifier(ButtonModifier(action: action))
}
}
I have SwiftData models containing arrays of Codable structs that worked fine before adding CloudKit capability. I believe they are the reason I started seeing errors after enabling CloudKit.
Example model:
@Model
final class ProtocolMedication {
var times: [SchedulingTime] = [] // SchedulingTime is Codable
// other properties...
}
After enabling CloudKit, I get this error logged to the console:
'NSKeyedUnarchiveFromData' should not be used to for un-archiving and will be removed in a future release
CloudKit Console shows this times data as "plain text" instead of "bplist" format.
Other struct/enum properties display correctly (I think) as "bplist" in CloudKit Console.
The local SwiftData storage handled these arrays fine - this issue only appeared with CloudKit integration.
What's the recommended approach for storing arrays of Codable structs in SwiftData models that sync with CloudKit?
I’m facing an issue and I’d like to know if anyone has already run into this.
I have a ContentView that presents a SettingsView as a sheet. SettingsView applies a change to the app’s colorScheme. ContentView reacts correctly to the change, and SettingsView does too (so far, so good).
What’s strange is that when I set nil on the preferredColorScheme modifier (which, according to the docs, corresponds to the system color scheme), ContentView correctly picks up the change and refreshes, while SettingsView does pick up the change but doesn’t refresh. (In the video you can clearly see that when I switch from Dark to System, the parent view refreshes properly but not the presented sheet.)
I’ve tried everything—switching to UIKit, changing the sheet’s ID… nothing works
Another strange thing: if I present SettingsView through a NavigationLink, everything works normally…
Here is a sample code to reproduce:
import SwiftUI
enum AppTheme: Int {
case system = 0
case dark = 1
case light = 2
var colorScheme: ColorScheme? {
switch self {
case .system: return nil
case .light: return .light
case .dark: return .dark
}
}
}
struct SettingsView: View {
@AppStorage("theme") var appTheme: AppTheme = .system
var body: some View {
VStack(spacing: 8) {
Button {
select(theme: .system)
} label: {
Text("Systeme")
}
Button {
select(theme: .dark)
} label: {
Text("Dark")
}
Button {
select(theme: .light)
} label: {
Text("Light")
}
}
.preferredColorScheme(appTheme.colorScheme)
}
func select(theme: AppTheme) {
appTheme = theme
}
}
struct ContentView: View {
@AppStorage("theme") var appTheme: AppTheme = .system
@State var isPresented = false
var body: some View {
NavigationStack {
VStack {
Button {
isPresented = true
} label: {
Text("Present settings")
}
// NavigationLink("Present settings") {
// SettingsView()
// }
}
.preferredColorScheme(appTheme.colorScheme)
.sheet(isPresented: $isPresented) {
SettingsView()
}
}
}
}
#Preview {
ContentView()
}
Hi everyone!
I've encountered an issue on Mac Catalyst: using the latest inspector modifier causes abnormal Sidebar and Columns state in NavigationSplitView.
Sample Code:
struct ContentView: View {
@State private var isPresented = false
var body: some View {
NavigationSplitView {
List {
ForEach(0..<20, id: \.self) { item in
Text("Item \(item)")
}
}
} content: {
List {
ForEach(0..<20, id: \.self) { item in
Text("Item \(item)")
}
}
} detail: {
List {
}
}
.inspector(isPresented: $isPresented) {
Form {
}
}
}
}
Steps to reproduce:
Xcode 16 beta 7, create a new iOS project
Paste the code above
Enable Mac Catalyst
Run on Mac (macOS 15 beta 9)
Press Command+N three times to open 3 new windows
Click the Sidebar Toggle button
The issue occurs (see screenshot below)
Through testing, I found that as long as the inspector modifier is attached, the issue occurs.
Also, the problem only appears in the 3rd and subsequent newly opened windows—the first two windows work as expected.
FB20061521
My Xcode project fails to run with the following crash log any time I use a new SwiftUI symbol such as ConcentricRectangle or .glassEffect. I've tried using the legacy linker to no avail. It compiles perfectly fine, and I've tried targeting just macOS 26 also to no avail. This is a macOS project that's compiled just fine for years and compiles and runs on macOS going back to 13.0.
Failed to look up symbolic reference at 0x118e743cd - offset 1916987 - symbol symbolic _____y_____y_____y_____yAAyAAy_____y__________G_____G_____yAFGGSg_ACyAAy_____y_____SSG_____y_____SgGG______tGSgACyAAyAAy_____ATG_____G_AVtGSgtGGAQySbGG______Qo_ 7SwiftUI4ViewPAAE11glassEffect_2inQrAA5GlassV_qd__tAA5ShapeRd__lFQO AA15ModifiedContentV AA6VStackV AA05TupleC0V AA01_hC0V AA9RectangleV AA5ColorV AA12_FrameLayoutV AA24_BackgroundStyleModifierV AA6IDViewV 8[ ]012EditorTabBarC0V AA022_EnvironmentKeyWritingS0V A_0W0C AA7DividerV A_0w4JumpyC0V AA08_PaddingP0V AA07DefaultgeH0V in /Users/[ ]/Library/Developer/Xcode/DerivedData/[ ]-grfjhgtlsyiobueapymobkzvfytq/Build/Products/Debug/[ ]/Contents/MacOS/[ ].debug.dylib - pointer at 0x119048408 is likely a reference to a missing weak symbol
Example crashing code:
import SwiftUI
struct MyView: View {
var body: some View {
if #available(macOS 26.0, *) {
Text("what the heck man").glassEffect()
}
}
}
I'm looking for a way to implement Liquid Glass effect in a Text, and I have issues.
If I want to do gradient effect in a Text, no problem, like below.
Text("Liquid Glass")
.font(Font.system(size: 30, weight: .bold))
.multilineTextAlignment(.center)
.foregroundStyle(
LinearGradient(
colors: [.blue, .mint, .green],
startPoint: .leading,
endPoint: .trailing
)
)
But I cannot make sure that I can apply the .glassEffect with .mask or .foregroundStyle. The Glass type and Shape type argument looks like not compatible with the Text shape itself.
Any solution to do this effect on Text ?
Thanks in advance for your answers.
Hello,
In iOS 26 beta, we are seeing an unexpected behavior when using SwiftUI WebView (or a custom WKWebView via UIViewRepresentable).
When an alert is presented above the WebView, the WebView immediately reloads to its initial page. The alert itself also disappears instantly, making it impossible for the user to interact with it.
This issue occurs both with the new SwiftUI WebView / WebPage API and with a wrapped WKWebView. The problem was not present in previous iOS versions (iOS 17/18).
Steps to reproduce:
Create a SwiftUI view with a WebView (pointing to any URL).
Add a toolbar button that toggles a SwiftUI alert.
Run the app on iOS 26 beta.
Tap the button to trigger the alert.
Expected behavior:
The WebView should remain as-is, and the alert should stay visible until the user dismisses it.
Actual behavior:
As soon as the alert appears, the WebView reloads and resets to the initial page. The alert disappears immediately.
Minimal Example:
struct ContentView: View {
@State private var showAlert = false
var body: some View {
NavigationStack {
WebView(URL(string: "https://apple.com")!)
.toolbar {
ToolbarItem(placement: .topBarTrailing) {
Button("Close") {
showAlert = true
}
}
}
.alert("Confirm close?", isPresented: $showAlert) {
Button("Cancel", role: .cancel) {}
Button("Close", role: .destructive) {}
}
}
}
}
I'm using Xcode Version 26.0 beta 7
Thanks for your help.
The launch argument -com.apple.TipKit.HideAllTips 1 does not work if it is defined in xctestplan arguments passed on launch.
I tested it with the apple provided example app, where I created simple UI test and added xctestplan with launch argument -com.apple.TipKit.HideAllTips 1.
The app does not hide the tips when it is running the UI Tests.
Is there any solution that works?
Thanks for reply.
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")
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()
}
Hi everyone,
I’ve been working on migrating my app (SwimTimes, which helps swimmers track their times) to use Core Data + CKSyncEngine with Swift 6.
After many iterations, forum searches, and experimentation, I’ve created a focused sample project that demonstrates the architecture I’m using.
The good news:
👉 I believe the crashes I was experiencing are now solved, and the sync behavior is working correctly.
👉 The demo project compiles and runs cleanly with Swift 6.
However, before adopting this as the final architecture, I’d like to ask the community (and hopefully Apple engineers) to validate a few critical points, especially regarding Swift 6 concurrency and Core Data contexts.
Architecture Overview
Persistence layer: Persistence.swift sets up the Core Data stack with a main viewContext and a background context for CKSyncEngine.
Repositories: All Core Data access is abstracted into repository classes (UsersRepository, SwimTimesRepository), with async/await methods.
SyncEngine: Wraps CKSyncEngine, handles system fields, sync tokens, and bridging between Core Data entities and CloudKit records.
ViewModels: Marked @MainActor, exposing @Published arrays for SwiftUI. They never touch Core Data directly, only via repositories.
UI: Simple SwiftUI views bound to the ViewModels.
Entities:
UserEntity → represents swimmers.
SwimTimeEntity → times linked to a user (1-to-many).
Current Status
The project works and syncs across devices. But there are two open concerns I’d like validated:
Concurrency & Memory Safety
Am I correctly separating viewContext (main/UI) vs. background context (used by CKSyncEngine)?
Could there still be hidden risks of race conditions or memory crashes that I’m not catching?
Swift 6 Sendable Compliance
Currently, I still need @unchecked Sendable in the SyncEngine and repository layers.
What is the recommended way to fully remove these workarounds and make the code safe under Swift 6’s stricter concurrency rules?
Request
Please review this sample project and confirm whether the concurrency model is correct.
Suggest how I can remove the @unchecked Sendable annotations safely.
Any additional code improvements or best practices would also be very welcome — the intention is to share this as a community resource.
I believe once finalized, this could serve as a good reference demo for Core Data + CKSyncEngine + Swift 6, helping others migrate safely.
Environment
iOS 18.5
Xcode 16.4
macOS 15.6
Swift 6
Sample Project
Here is the full sample project on GitHub:
👉 [https://github.com/jarnaez728/coredata-cksyncengine-swift6]
Thanks a lot for your time and for any insights!
Best regards,
Javier Arnáez de Pedro
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).
What is the recommended way to obtain the concentric corner radius for views within grouped UICollectionView cells?
In the most basic example, a UICollectionView with one section and one cell, we observe the cell takes almost the shape of a capsule, but it is indeed not a capsule.
What is the way to obtain the radius of the grouped area from within the cell or its registration? I would like to layer elements on top that are concentric to the cell's clip shape.
I've tried using custom views with .concentric UICornerConfigurations, setting .cornerConfiguration on the cell and on a custom backgroundView and I've even tried obtaining the .effectiveRadius of the cell after layout (returns 0.0). As of Xcode 26.0 Beta 7, nothing works.
This seems like a huge omission; what am I missing here?
Hi 🙋
Has anybody gotten subtitles in macOS Tahoe Control Widgets to show up in their custom control widgets? Seems macOS is able to do it (see attached screenshot of the Bluetooth control widget), but my widget, which shows a title and subtitle on iOS, will only show the title on macOS.
I tried all the different ControlWidgetButton init methods to no avail. I tried a VStack for my title and subtitle Texts, I tried just two Texts without a VStack, I tried the controlWidgetStatus and controlWidgetActionHint modifiers out of desperation... nothing worked.
Any pointers much appreciated!
Thank you,
– Matthias
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.
Note: in this post I discuss sceneDidEnterBackground/WillResignActive but I assume any guidance provided would also apply to the now deprecated applicationDidEnterBackground/applicationWillResignActive and SwiftUI's ScenePhase (please call out if that's not the case!).
A common pattern for applications with sensitive user data (banking, health, private journals, etc.) is to obsurce content in the app switcher. Different apps appear to implement this in two common patterns. Either immediately upon becoming inactive (near immediately upon moving to task switcher) or only upon becoming backgrounded (not until you've gone to another app or back to the home screen).
I’d like to make sure we’re aligned with Apple’s intended best practices and am wondering if an anti-pattern of using sceneWillResignActive(_:) may be becoming popularized and has minor user experience inconviences (jarring transitions to the App Switcher/Control Center/Notification Center and when the system presents alerts.)
Our applications current implementation uses sceneDidEnterBackground(_:) to obscure sensitive elements instead of sceneWillResignActive(_:), based on the recomendations from tech note QA1838 and the documentation in sceneDidEnterBackground(_:)
... Shortly after this method [sceneWillEnterBackground] returns, UIKit takes a snapshot of your scene’s interface for display in the app switcher. Make sure your interface doesn’t contain sensitive user information.
Both QA1838 and the sceneDidEnterBackground documentation seem to indicate backgrounding is the appropriate event to respond to for this pattern but I am wondering if "to display in the app switcher" may be causing confusion since your app can also display in the app switcher upon becoming inactive and if some guidance could be added to sceneWillResignActive that it is not nesscary to obsure content during this state (if that is true).
In our testing, apps seems to continue to play any in-progress animations when entering the app switcher from the application (inactive state), suggesting no snapshot capture. We also discovered that it appears sceneWillResignActive not always be called (it usually is) but occasionally you can swipe into the app switcher without it being called but that sceneDidEnterBackground is triggered more consistently.
It appears the Wallet app behaves as I'd expect with sceneDidEnterBackground on card details screens as well (ejecting you to the card preview if you switch apps) but will keep you on the card details screen upon becoming inactive.
Questions:
Is sceneDidEnterBackground(_:) still Apple’s recommended place to obscure sensitive content, or should apps handle this earlier (e.g. on inactive)?
Would it actually be recommended against using sceneWillResignActive active given it seems to not be gauranteed to be called?
Ask:
Provide an updated version of QA1838 to solidfy the extrapolation of applicationDidEnterBackground -> sceneDidEnterBackground
Consider adding explicit guidance to sceneWillResignActive documentation
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!