I recently compiled my macOS App with Swift 6 in Xcode 16 (was using Swift 5 previously) and noticed that AppKit Integration doesn't appear to be working as before. All my instances of NSHostingView which allow me to add a SwiftUI View to an AppKit NSWindow view controller no longer respond to mouse input anymore. All my NSHostingView instances display but refuse to accept any user interaction. Has anyone else noticed this and is there a workaround to get NSHostingView to once again be able to accept user/mouse events with Swift 6?
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
Hi!
I am working on an app that requires displaying special characters and I have currently implemented it to just use Text() in swiftUI.
Unfortunately, it can't display the full height of the text.
Attached is one example of this happening.
I have attempted to do .linespacing() but that method doesn't work. .frame also doesn't seem to make a change. Does anyone have a solution to this?
Thanks!
Hi,
I have a button view that is used in many different ways in an app that I'm working on. One of the ways it is used is in an account creation form. Since the button is in a child view, the action: { } button function isn't available in the view where the input field variables are. I could import the class with the function to the button view but I don't want to pass the input field variables into the button view. I tried binding a boolean variable to the button view and checked for it's state change in the parent view using .onChange(), but the use case for that I found was depreciated and I'm unable to revert the state of the variable in the .onChange function.
To reiterate, in a main view, I need to call a function in a given class and pass variables to it, upon a button being pressed in a child view. Any help would be greatly appreciated.
I found an issue when implementing an alert with a TextField to input a name. I want the action button to be disabled until a name has been entered, but the action block is never executed when the button has become enabled and pressed. The problem seems to appear only when name is initially an empty string. Tested with iOS 17.0.
struct MyView: View {
@State private var name = ""
var body: some View {
SomeView()
.alert(...) {
TextField("Name", text: $name)
Button("Action") {
// Action
}.disabled(name.isEmpty)
Button("Cancel", role: .cancel) {}
}
}
}
In ios17 and above, I can detect when swiftUI app goes into and out of background using:
@Environment(\.scenePhase) private var phase
...
.onChange(of: phase) {
switch phase {
case .background:
print("entering background...")
case .active:
print("entering foreground...")
default: break
}
}
Is there a straightforward way to do this in SwiftUI for ios 16? I've found some examples using UIKit, but I am not that swift (sorry, couldn't resist) with that framework.
This is a question regarding the specification of ObservalObject.
The following code does not cause a compilation error when the deployment target is set to iOS 16, but it does cause the following error when set to iOS 15:
class Model: ObservableObject {
let player: AVPlayer
@Published var isPlaying = false
var playerObserver: NSKeyValueObservation?
init() {
self.player = AVPlayer()
self.playerObserver = self.player.observe(\.rate, options: [.new, .old]) { player, change in
NSLog("changed rate: \(String(describing: change.newValue))")
}
}
func setup() {
let name = "sample"
let url = Bundle.main.url(forResource: name, withExtension: "m4a")!
let playerItem = AVPlayerItem(url: url)
self.player.replaceCurrentItem(with: playerItem)
}
func play() {
self.player.play()
self.isPlaying = true
}
}
The following error occurs in iOS 15:
Cannot form key path to main actor-isolated property 'rate'
Call to main actor-isolated instance method 'play()' in a synchronous nonisolated context
Additionally, if the code is modified as follows, the error does not occur even in iOS 15. Specifically, adding @MainActor to the Model resolves the issue.
@MainActor
class Model: ObservableObject {
...
}
From this behavior, I guessed that ObservableObject is implicitly a MainActor in iOS 16 and later. Is this understanding correct?
I am trying to use a ShareLink to share multiple transferrable, and I cannot work out which of the initialisers to use - none seem to work.
Assuming I have a transferable that takes some data and processes it asynchronously:
struct MyTransferable: some Transferable {
let renderer: Renderer
static var transferRepresentation: some TransferRepresentation {
DataRepresentation(exportedContentType: .png) { transferable in
let image = try await transferable.render.render()
return image
}
}
}
In SwiftUI, I want to share N of these transferables. For example:
struct MyView: View {
private var transferables: [any Transferable] {
[MyTransferable(), MyTransferable()]
}
var body: some View {
ShareLink("Renders", items: transferables)
}
}
But the compiler doesn't like this - it complains with "No exact matches in call to initializer".
Is this possible? I feel like it should be?
I was adding WidgetExtension target for my old project.
The widget target is running fine in iOS 17, In my case, widget need to support iOS 14 and above, so I updated my widget code to old style, To removing WidgetConfigurationIntent and AppIntentTimelineProvider.
import WidgetKit
import SwiftUI
struct Provider: TimelineProvider {
func placeholder(in context: Context) -> SimpleEntry {
SimpleEntry()
}
func getSnapshot(in context: Context, completion: @escaping (SimpleEntry) -> Void) {
completion(SimpleEntry())
}
func getTimeline(in context: Context, completion: @escaping (Timeline<SimpleEntry>) -> Void) {
completion(Timeline(entries: [SimpleEntry()], policy: .never))
}
typealias Entry = SimpleEntry
}
struct SimpleEntry: TimelineEntry {
let date: Date = Date()
}
struct NCWidgetEntryView : View {
var entry: Provider.Entry
var body: some View {
VStack {
Text("Time:")
Text(entry.date, style: .time)
}
}
}
struct NCWidget: Widget {
let kind: String = "NCWidget"
var body: some WidgetConfiguration {
StaticConfiguration(kind: kind, provider: Provider()) { entry in
NCWidgetEntryView(entry: entry)
}
.configurationDisplayName("DisplayName")
.description("description")
}
}
In my case, the code was working fine in iOS 17 simulator, But if I try to run in iOS 15, it returns the below error
code-SendProcessControlEvent:toPid: encountered an error: Error Domain=com.apple.dt.deviceprocesscontrolservice Code=8 "Failed to show Widget 'com.name-pprd.NCWidgetExtension' error: Error Domain=FBSOpenApplicationServiceErrorDomain Code=5 "The request to open "com.apple.springboard" failed." UserInfo={NSLocalizedDescription=The request to open "com.apple.springboard" failed., NSLocalizedFailureReason=Unexpected error type., NSUnderlyingError=0x600003570b40 {Error Domain=BSServiceConnectionErrorDomain Code=3 "XPC error received on message reply handler" UserInfo={BSErrorCodeDescription=OperationFailed, NSLocalizedFailureReason=XPC error received on message reply handler}}, BSErrorCodeDescription=InvalidResponse}." UserInfo={NSLocalizedDescription=Failed to show Widget 'com.name-pprd.NCWidgetExtension' error: Error Domain=FBSOpenApplicationServiceErrorDomain Code=5 "The request to open "com.apple.springboard" failed." UserInfo={NSLocalizedDescription=The request to open "com.apple.springboard" failed., NSLocalizedFailureReason=Unexpected error type., NSUnderlyingError=0x600003570b40 {Error Domain=BSServiceConnectionErrorDomain Code=3 "XPC error received on message reply handler" UserInfo={BSErrorCodeDescription=OperationFailed, NSLocalizedFailureReason=XPC error received on message reply handler}}, BSErrorCodeDescription=InvalidResponse}., NSUnderlyingError=0x600003570bd0 {Error Domain=FBSOpenApplicationServiceErrorDomain Code=5 "The request to open "com.apple.springboard" failed." UserInfo={NSLocalizedDescription=The request to open "com.apple.springboard" failed., NSLocalizedFailureReason=Unexpected error type., NSUnderlyingError=0x600003570b40 {Error Domain=BSServiceConnectionErrorDomain Code=3 "XPC error received on message reply handler" UserInfo={BSErrorCodeDescription=OperationFailed, NSLocalizedFailureReason=XPC error received on message reply handler}}, BSErrorCodeDescription=InvalidResponse}}}
Domain: DTXMessage
Code: 1
User Info: {
DVTErrorCreationDateKey = "2024-07-20 17:30:58 +0000";
}
--
System Information
macOS Version 14.5 (Build 23F79)
Xcode 15.0.1 (22266) (Build 15A507)
Timestamp: 2024-07-20T23:00:58+05:30
In widget target Minimum target is 14.0
In App target Minimum target is 13.0
Hello, so I created a custom TabBar using the .overlay modifier on TabView. However, when clicking/pressing on a TextField, the keyboard causes the TabBar to be pushed up in the view. From Reddit, I found that this is caused by using the .overlay modifier.
How should I go about fixing this issue or what is the standard way of implementing custom tab bars?
Thanks in advance!
-- Kohl J
Screenshot
TabView Code
struct RootView: View {
@State var selectedTab : Tabs = .home;
var body: some View {
TabView(selection: $selectedTab) {
HomeView(selectedTab: $selectedTab)
.tag(Tabs.home)
TaskListView(selectedTab: $selectedTab)
.tag(Tabs.taskList)
CreateTaskView(selectedTab: $selectedTab)
.tag(Tabs.create)
TrophiesView(selectedTab: $selectedTab)
.tag(Tabs.trophies)
SettingsView(selectedTab: $selectedTab)
.tag(Tabs.settings)
}
.overlay(alignment: .bottom) {
TabBar(selectedTab: $selectedTab)
.padding(.horizontal)
}
}
}
Custom TabBar Code
struct TabBar: View {
@Binding var selectedTab : Tabs
var body : some View {
HStack (alignment: .center) {
Button(action: {
// switch to home view
selectedTab = Tabs.home
}, label: {
TabBarButton(buttonText: "Home", imageName: "house.fill", size: 24, isActive: selectedTab == .home, hasTopBar: true)
})
Button(action: {
// switch to task list view
selectedTab = Tabs.taskList
}, label: {
TabBarButton(buttonText: "Task List", imageName: "list.bullet.clipboard.fill", size: 24, isActive: selectedTab == .taskList, hasTopBar: true)
})
Button(action: {
// switch to create view
selectedTab = Tabs.create
}, label: {
TabBarButton(buttonText: "Create", imageName: "plus.circle.fill", size: 32, isActive: selectedTab == .create, hasTopBar: false)
})
Button(action: {
// switch to trophies view
selectedTab = Tabs.trophies
}, label: {
TabBarButton(buttonText: "Trophies", imageName: "trophy.fill", size: 24, isActive: selectedTab == .trophies, hasTopBar: true)
})
Button(action: {
// switch to settings view
selectedTab = Tabs.settings
}, label: {
TabBarButton(buttonText: "Settings", imageName: "gearshape.fill", size: 24, isActive: selectedTab == .settings, hasTopBar: true)
})
}
.frame(height: 60)
}
}
Hello,
I'm using the Picker component to enable the user to pick a payment method but the menu items are flipped
Hello,
With iOS 18, when NavigationStack is in new TabView, with path parameter containing current navigation state is set, the navigation destination view is pushed twice.
See below with example that pushes twice on iOS 18 but is correct on iOS 17
@MainActor
class NavigationModel: ObservableObject {
static let shared = NavigationModel()
@Published var selectedTab: String
@Published var homePath: [Route]
@Published var testPath: [Route]
}
struct ContentView: View {
@StateObject private var navigationModel: NavigationModel = NavigationModel.shared
var body: some View {
TabView(selection: $navigationModel.selectedTab){
HomeView()
.tabItem {
Label("Home", systemImage: "house")
}
.tag("home")
TestView()
.tabItem {
Label("Test", systemImage: "circle")
}
.tag("test")
}
}
}
struct HomeView: View {
@StateObject private var navigationModel: NavigationModel = NavigationModel.shared
var body: some View {
NavigationStack(path: $navigationModel.homePath){
VStack{
Text("home")
NavigationLink(value: Route.test1("test1")){
Text("Go to test1")
}
}
.navigationDestination(for: Route.self){ route in
NavigationModelBuilder.findFinalDestination(route:route)
}
}
}
}
I don't what causes the issue because it works well on iOS 16 and iOS 17. I think the path is somehow reset but I don't why (maybe by the TabView ?)
Note that the bug only occurs with TabView.
Don't really know if it is a TabView bug or if it is on my side.
I filed a feedback with sample project FB14312064
The following WatchOs App example is very short, but already not functioning as it is expected, when using Digital Crown (full code):
import SwiftUI
struct ContentView: View {
let array = ["One","Two","Three","Four"]
@State var selection = "One"
var body: some View {
Picker("Array", selection: $selection) {
ForEach(array, id: \.self) {
Text($0)
}
}
}
}
The following 2 errors are thrown, when using Digital Crown for scrolling:
ScrollView contentOffset binding has been read; this will cause grossly inefficient view performance as the ScrollView's content will be updated whenever its contentOffset changes. Read the contentOffset binding in a view that is not parented between the creator of the binding and the ScrollView to avoid this.
Error: Error Domain=NSOSStatusErrorDomain Code=-536870187 "(null)"
Any help appreciated. Thanks a lot.
HI,
I'm trying to deeplink from my widget to a view in my app.
I'm using the "SwiftUI app lifecycle".
This the code I'm currently using:
var body: some Scene {
WindowGroup {
RootView()
.onContinueUserActivity("NextDeparturesWidgetConfigurationIntent") { userActivity in
guard let configuration: NextDeparturesWidgetConfigurationIntent = userActivity
.widgetConfigurationIntent(),
let stationEntity = configuration.stationEntity else { return }
NotificationCenter.default.post(name: .onOpenStation, object: stationEntity.id)
}
}
}
It is working fine when the app is already running (in the background).
However when the app is "cold starting" (ie. not in memory) onContinueUserActivity is never called.
I tried adding a UIApplicationDelegateAdaptor:
func application(
_ application: UIApplication,
configurationForConnecting connectingSceneSession: UISceneSession,
options: UIScene.ConnectionOptions
) -> UISceneConfiguration {
if let userActivity = options.userActivities.first {
let configuration: NextDeparturesWidgetConfigurationIntent? = userActivity.widgetConfigurationIntent()
// casting fails
}
return UISceneConfiguration(
name: nil,
sessionRole: connectingSceneSession.role
)
}
I can see that the activity is received but it is never casted to NextDeparturesWidgetConfigurationIntent.
What am I missing ?
In SwiftUI, I have noticed that sometimes at the end of a keyboard dismiss animation, it leaves a white "inset" on the screen. The white inset would then disappear without any animation.
For more detailed demonstration, I have filed feedback FB13694633. Is there a way to work around this white inset for now? Thanks!
I am trying to change the highlight color of the tabs in SwiftUI, but when I applied .tint() to the TabView (which is the root view of my app), the entire app seems to be affected. What's more, the views under each seems to randomly switch between the default blue tint and the custom tint I configured.
Is there a way to only change the tab bar's tint color? Thanks!
I'm trying to implement multiple window support for my app, but the system restores the wrong scene when the app is relaunched. Here's my code:
import SwiftUI
@main
struct TestApp: App {
@Environment(\.openWindow) private var openWindow
var body: some Scene {
WindowGroup(id: "Navigator") {
Button {
openWindow(id: "Editor", value: "test")
} label: {
Text("Open Window")
}
}
WindowGroup(id: "Editor", for: String.self) { id in
Text(id.wrappedValue ?? "none")
}
}
}
If I run the app and tap the button, the Editor window opens. If I force quit and open the app again, the app still has two windows open but both are Navigator windows.
I've tried adding handlesExternalEvents to the Scene and advertising an activity with .userActivity(isActive:), neither changes this behaviour. Any advice?
Hi folks,
I've used a NavigationSplitView within one of the tabs of my app since iOS 16, but with the new styling in iOS 18 the toolbar region looks odd. In other tabs using e.g. simple stacks, the toolbar buttons are horizontally in line with the new tab picker, but with NavigationSplitView, the toolbar leaves a lot of empty space at the top (see below). Is there anything I can do to adjust this, or alternatively, continue to use the old style?
Thanks!
I'm pursuing a design that necessitates a dual app architecture — using a NavigationStack for compact-sized screens, and a NavigationSplitView for regular-sized screens.
I've encountered what might be a bug in NavigationSplitView on iPadOS 17.x. Or perhaps it's a mistake in my code.
When navigating into nested views (relying on NavigationPath), everything works fine... until I background the app on iPad.
At this point, the navigation stack appears to collapse in the NavigationSplitView detail area — merging the parent and child views.
Adding to the mystery... I can reproduce this bug on iPadOS 17.x. But the problem goes away when running on iPadOS 18.x beta.
Key questions:
Is there a problem in my code?
Should I file a feedback with the Apple SwiftUI team?
If iPadOS 18.x fixes this bug, can I expect a SwiftUI fix to be back-ported to 17.x or earlier?
Steps to reproduce:
Run my sample code on iPadOS simulator.
Navigate to select a color, and then a shape.
Put the app into the background (e.g., go to Home Screen).
Return to app.
What you can expect:
When running on iPadOS 17.x, you'll see that the two most recent views in the stack have merged (meaning the title has changed, and the "back" button has disappeared).
On iPadOS 18.x, you'll see that everything is working fine (title isn't changed, and back button remains available).
App Purchase Validation and In-App Purchase Persistence with the older StoreKit APIs is complicated. I’m curious to learn whether the new StoreKit SwiftUI views and .subscriptionStatusTask modifier simplify the process — or ideally eliminates the need to implement complex Validation and persistence logic using AppStorage, Keychain or App Receipts. Any thoughts on this?
I am using Model3D to display an RCP scene/model in my UI.
How can I get to the entities so I can set material properties to adjust the appearance?
I looked at interfaces for Model3D and ResolvedModel3D and could not find a way to get access to the RCP scene or RealityKit entity.