In one of my applications I use several List views with Sections. After upgrading to Sequoia I faced the issue, that after selecting an item, the List suddenly scrolls to a different position. Sometimes the selection even gets out of the view, but in every case a double click just went to the wrong item.
At one list I found out, that the issue could be solved after changing the data source. I used a computed property, what seems to be a stupid idea. After changing this it now works.
Unfortunately there is another List, where this didn't bring the solution. And unfortunately, I cannot reproduce the issue in a code example. One guess of mine is, that it could be related to the fact, that the rows have different heights (because in some are two lines of text and in some are three). And it seems to happen only in very long lists.
It worked perfectly in Sonoma.
Does anyone face the same issue?
SwiftUI
RSS for tagProvide views, controls, and layout structures for declaring your app's user interface using SwiftUI.
Post
Replies
Boosts
Views
Activity
Hi,
In the visionOS documentation
Positioning and sizing windows - Specify initial window position
In visionOS, the system places new windows directly in front of people, where they happen to be gazing at the moment the window opens.
Positioning and sizing windows - Specify window resizability
In visionOS, the system enforces a standard minimum and maximum size for all windows, regardless of the content they contain.
The first thing I don't understand is why it talk about macOS in visionOS documentation.
The second thing, what is this page for if it's just to tell us that on visionOS we have no control over the position and size of 2D windows. Whereas it is precisely the opposite that would be interesting. I don't understand this limitation. It limits so much the use of 2D windows under visionOS.
I really hope that this limitation will disappear in future betas.
Is there a way to structure three views vertically with a top, middle divider, and bottom view, where the…
Middle divider view “hugs” its contents vertically (grows and shrinks based on height of child views)
Top and bottom views fill the space available above and below the divider
Divider can be dragged all the way up (or down), to completely hide the top view (or bottom view)
I’ve been working on this for a while and still can’t get it quite right. The code below is close, but the parent view’s bottom edge shifts when the divider resizes. As a result, the bottom view shifts upward when the divider shrinks, whereas I want it to continue to fill the space to the bottom of the screen.
import SwiftUI
struct ContentView: View {
@State private var topRatio: CGFloat = 0.5
@State private var dividerHeight: CGFloat = 44
var body: some View {
GeometryReader { geometry in
let topInset = geometry.safeAreaInsets.top
let bottomInset = geometry.safeAreaInsets.bottom
let totalHeight = geometry.size.height
let availableHeight = max(totalHeight - bottomInset - dividerHeight, 0)
VStack(spacing: 0) {
TopView()
.frame(height: max(availableHeight * topRatio - topInset, 0))
.frame(maxWidth: .infinity)
.background(Color.red.opacity(0.3))
DividerView()
.background(GeometryReader { proxy in
Color.clear.preference(key: DividerHeightKey.self, value: proxy.size.height)
})
.onPreferenceChange(DividerHeightKey.self) { height in
dividerHeight = height
}
.gesture(
DragGesture()
.onChanged { value in
let maxDragDistance = availableHeight + dividerHeight
let translation = value.translation.height / max(maxDragDistance, 1)
let newTopRatio = topRatio + translation
topRatio = min(max(newTopRatio, 0), 1)
}
)
.zIndex(1)
BottomView()
.frame(height: max(availableHeight * (1 - topRatio), 0))
.frame(maxWidth: .infinity)
.background(Color.green.opacity(0.3))
}
}
}
}
struct DividerHeightKey: PreferenceKey {
static var defaultValue: CGFloat = 44
static func reduce(value: inout CGFloat, nextValue: () -> CGFloat) {
value = nextValue()
}
}
struct DividerView: View {
@State private var showExtraText = true
var body: some View {
VStack(spacing: 0) {
Text(showExtraText ? "Tap to hide 'More'" : "Tap to show 'More'")
.frame(height: 44)
if showExtraText {
Text("More")
.frame(height: 44)
}
}
.frame(maxWidth: .infinity)
.background(Color.gray)
.onTapGesture {
showExtraText.toggle()
}
}
}
struct TopView: View {
var body: some View {
VStack {
Spacer()
Text("Top")
}
.padding(0)
}
}
struct BottomView: View {
var body: some View {
VStack {
Text("Bottom")
Spacer()
}
.padding(0)
}
}
#Preview {
ContentView()
}
Before I waste time creating an Apple Developer Support ticket, I’m hoping an Apple DTS engineer can confirm if this is just log noise.
Here’s the code:
import SwiftUI
struct ContentView: View {
@State private var editMode: EditMode = .inactive
@State private var items = ["Item 1", "Item 2", "Item 3"]
var body: some View {
NavigationStack {
List {
ForEach(items, id: \.self) { item in
Text(item)
}
.onDelete { indexSet in
items.remove(atOffsets: indexSet)
}
}
.environment(\.editMode, $editMode)
.toolbar {
ToolbarItem(placement: .topBarTrailing) {
EditButton()
.environment(\.editMode, $editMode)
}
}
}
}
}
#Preview {
ContentView()
}
When you run this code and tap Edit, you’ll initially get:
CoreSVG has logged an error. Set environment variabe [sic] "CORESVG_VERBOSE" to learn more.
After setting CORESVG_VERBOSE = YES, you’ll see:
CoreSVG: Error: NULL ref passed to getObjectCoreSVG: Error: NULL ref passed to getObject
This error only appears the first time Edit is tapped after a build and run. It won't happen again, even after force-quitting and reopening the app. The issue also only happens on iOS 18.0 and 18.1—I can’t reproduce it on iOS 17.5. Fortunately, it doesn’t seem to cause any negative side effects.
Is this just log noise?
I'm trying to use a SwiftUI view as UICalendarView decoration and I get Call to main actor-isolated instance method 'makeContentView()' in a synchronous nonisolated context; this is an error in the Swift 6 language mode in the following code:
class Coordinator: NSObject, UICalendarViewDelegate {
func calendarView(_ calendarView: UICalendarView, decorationFor dateComponents: DateComponents) -> UICalendarView.Decoration? {
.customView {
UIHostingConfiguration {
...
}
.makeContentView()
}
}
}
I've fixed using MainActor.assumeIsolated but is this the correct approach or is there a better one?
class Coordinator: NSObject, UICalendarViewDelegate {
func calendarView(_ calendarView: UICalendarView, decorationFor dateComponents: DateComponents) -> UICalendarView.Decoration? {
.customView {
MainActor.assumeIsolated {
UIHostingConfiguration {
...
}
.makeContentView()
}
}
}
}
Don’t over-engineering! No suggested architecture for SwiftUI, just MVC without the C.
On SwiftUI you get extra (or wrong) work and complexity for no benefits. Don’t fight the system.
I'm using Xcode 14.1 to start a Core Data project. I created a new Project, checking CoreData. The resulting program works in Preview and in the Simulator.
I've changed the data from a Item/timestamp to Locations/title. I plan to add more Attributes but that's for later.
I think I've got all the Item instances changed to Locations and timestamp to title. It seems to work OK when in Preview for ContentView.swift but crashes in the Simulator with the error
Swift/UnsafeRawBufferPointer.swift:946: Fatal error: UnsafeRawBufferPointer with negative count
Any suggestions on what I have done wrong? Thanks.
PS, the New Project includes the line Text("Select a location") but Select a location doesn't appear in the Preview.
I want to create a custom presentation detent to set a custom height for a sheet presentation. For that, I added a struct conforming to CustomPresentationDetent which has an only method static function height(in: Self.Context) -> CGFloat?.
Implementation works fine, the view presented inside the sheet modifier has the height returned by the custom detent. The problem comes when I try to access the Context's environment values inside the protocol conformance method.
PresentationDetent.Context has a subscript that enables accessing any environment value subscript<T>(dynamicMember _: KeyPath<EnvironmentValues, T>) -> T but using it from the custom detents height method only returns the default value for each one.
I'm trying to set the environment values through environment<V>(WritableKeyPath<EnvironmentValues, V>, V) modifier but it does not seem to work. When accessed via @Environment property wrapper from the view it does get the updated value though.
Is there any other way to set an environment value or any special way to set it so that it is visible from a presentation detent?
Family activity picker looses icon and incudes parent apps after 20 seconds...and you never see the kids icons again until you reboot. Any ideas?
family controls authorized on both apps
Share across devices activated
Web & activity activated.
Before...
...and after 22 seconds.
I'm facing an issue with SwiftUI's NavigationStack when using the searchable modifier. Everything works as expected when navigating between views, but if I use the search bar to filter a list and then tap on a filtered result, I can navigate to the next view. However, in the subsequent view, my "Set and Return to Root" button, which is supposed to call popToRoot(), does not work. Here's the setup:
Structure: RootView: Contains a list with items 1-7. ActivityView: Contains a list of activities that can be filtered with the searchable modifier. SettingView: Contains a button labeled "Set and Return to Root" that calls popToRoot() to navigate back to the root view.
RootView
struct RootView: View {
@EnvironmentObject var navManager: NavigationStateManager
var body: some View {
NavigationStack(path: $navManager.selectionPath) {
List(1...7, id: \.self) { item in
Button("Element \(item)") {
// Navigate to ActivityView with an example string
navManager.selectionPath.append(NavigationTarget.activity)
}
}
.navigationTitle("Root View")
.navigationDestination(for: NavigationTarget.self) { destination in
switch destination {
case .activity:
ActivityView()
case .settings:
SettingsView()
}
}
}
}
}
ActivityView
struct ActivityView: View {
@EnvironmentObject var navManager: NavigationStateManager
let activities = ["Running", "Swimming", "Cycling", "Hiking", "Yoga", "Weightlifting", "Boxing"]
@State private var searchText = ""
var filteredActivities: [String] {
if searchText.isEmpty {
return activities
} else {
return activities.filter { $0.localizedCaseInsensitiveContains(searchText) }
}
}
var body: some View {
List {
ForEach(filteredActivities, id: \.self) { activity in
NavigationLink(
destination: SettingsView(), // Navigiere zur SettingsView
label: {
HStack {
Text(activity)
.padding()
Spacer()
}
}
)
}
}
.navigationTitle("Choose Activity")
.searchable(text: $searchText, placement: .navigationBarDrawer(displayMode: .always), prompt: "Search Activities")
}
}
SettingView
struct SettingsView: View {
@EnvironmentObject var navManager: NavigationStateManager
var body: some View {
VStack {
Text("Settings")
.font(.largeTitle)
.padding()
Button("Set and Return to Root") {
// Pop to the root view when the button is pressed
navManager.popToRoot()
}
.padding()
.background(Color.blue)
.foregroundColor(.white)
.cornerRadius(10)
}
.navigationTitle("Settings")
}
}
NavigationStateManager
// Define enum globally at the top
enum NavigationTarget {
case activity
case settings
}
class NavigationStateManager: ObservableObject {
@Published var selectionPath = NavigationPath()
func popToRoot() {
selectionPath = NavigationPath()
}
func popView() {
selectionPath.removeLast()
}
}
Problem
When I search in the ActivityView and tap on a filtered result, I successfully navigate to the SettingView. However, in this view, pressing the "Set and Return to Root" button does not trigger the navigation back to RootView, even though popToRoot() is being called.
This issue only occurs when using the search bar and filtering results. If I navigate without using the search bar, the button works as expected.
Question
Why is the popToRoot() function failing after a search operation, and how can I ensure that I can return to the root view after filtering the list?
Any insights or suggestions would be greatly appreciated!
Hello guys,
I have such a big coding problem since a half year now about data saving.
I have a fitness app where we can add our exercices depend of the muscle, so you can choose it and then select your weight and number of repetitions and valid your exercise.
But when I do my exercises and my watch screen is also turn off, my muscle and muscleExercise variables are going back to their default value.
Here some code for you :
@EnvironmentObject var dataManager: DataManager
@Environment(\.modelContext) private var context
@AppStorage("savedGroupName") private var savedGroupName: String = ""
@AppStorage("savedExerciceName") private var savedExerciceName: String = ""
@State var groupName: String = "À choisir"
@State var ExerciceChoose: String = "À choisir"
I use my variables here :
HStack {
Text("Muscle:")
Spacer()
NavigationLink(destination: MusclesView()) {
Text(savedGroupName.isEmpty ? "À choisir" : savedGroupName)
}
.buttonStyle(PlainButtonStyle())
}
.onAppear {
savedGroupName = groupName
}
HStack {
Text("Exercise:")
Spacer()
NavigationLink(destination: MuscleExercicesView(groupName: groupName, ExerciceChoose: ExerciceChoose)) {
Text(savedExerciceName.isEmpty ? "À choisir" : savedExerciceName)
}
.onAppear {
savedExerciceName = ExerciceChoose
}
.buttonStyle(PlainButtonStyle())
}
The value of my muscle variable is taking in an other view :
struct MusclesView: View {
let muscleGroup = ExerciceData.muscleGroups
var body: some View {
NavigationStack {
List(muscleGroup, id: \.name) { group in
NavigationLink(destination: MuscleExercicesView(groupName: group.name, ExerciceChoose: "À choisir")) {
Text(group.name)
}
}
}
}
}
#Preview {
MusclesView()
}
and the value of the exerciseMuscle variable is also taking in an other view :
```import SwiftUI
struct MuscleExercicesView: View {
let exerciceGroup = ExerciceData.muscleGroups
@State var groupName: String
@State var ExerciceChoose: String
var body: some View {
if let group = ExerciceData.muscleGroups.first(where: { $0.name == groupName }) {
List(group.exercices, id: \.id) { exercice in
NavigationLink(exercice.name, destination: CurrentInformationsView(groupName: groupName, ExerciceChoose: exercice.name))
}
/*.onTapGesture {
print("Selected exercise: \(ExerciceChoose) for muscle group: \(groupName)")
}*/
.navigationTitle(Text("Exercices pour \(groupName)"))
} else {
Text("Aucun exercice trouvé pour \(groupName)")
.navigationTitle(Text("Erreur"))
}
}
}
#Preview {
MuscleExercicesView(groupName: "Pectoraux", ExerciceChoose: "À choisir")
}
I tried many things (like userDefault, put my values in an array to save it etc..) to keep my variables with the same value during the session but nothing works.
I wish I could have some help from you guys.
Have a good day !
Cyrille
The app added control widgets and crashed online。
SwiftU!
static ControlWidgetConfigurationAdaptor._makeWidgetConfiguration(widget inputs:)
Hello,
I have an NSViewRepresentable displaying an NSTextView in SwiftUI.
GeometryReader() { geometry in
ScrollView([.vertical, .horizontal]) {
Representable()
// -18 for vertical scroller
.frame(minWidth: geometry.size.width - 18)
}
}
When I use the vertical scrollbar the mouse click is passed to the Representable and is not registered by the Scroll bar. In the image you can see I tried to use the scroll bar and it highlighted some text instead.
There is a suggestion on stackoverflow to use an overlay. This fixes the scrolling issue, but will then make the Representable uninteractable.
How can I use the horizontal scroll bar here as expected?
Hi guys, I have a really odd problem. Whenever I try to add a vertical ScrollView, VStack or a LazyVStack to this code everything disappears. Anyone have an idea why this is happening and how to fix it? No errors show up in my code.
GeometryReader{ geometry in
VStack(alignment: .center, spacing: 100){
ScrollView(.horizontal, showsIndicators: false){
HStack(spacing: 250){
CardView1(
showOnlyImage: false,
imagename1: "TheMiceGalaxiesHubble",
heading1: "The Mice Galaxies",
description1: "Located in the constellation Coma Berenices."
)
.scaleEffect(getScale(proxy: geometry))
.animation(.easeOut(duration: 0.3), value: getScale(proxy: geometry))
CardView1(
showOnlyImage: false,
imagename1: "TheMiceGalaxiesHubble",
heading1: "The Mice Galaxies",
description1: "Located in the constellation Coma Berenices."
)
.scaleEffect(getScale(proxy: geometry))
.animation(.easeOut(duration: 0.3), value: getScale(proxy: geometry))
}
}
.frame(height: -200)
ScrollView(.horizontal, showsIndicators: false){
HStack(spacing: 250){
CardView1(
showOnlyImage: false,
imagename1: "TheMiceGalaxiesHubble",
heading1: "The Mice Galaxies",
description1: "Located in the constellation Coma Berenices."
)
.scaleEffect(getScale(proxy: geometry))
.animation(.easeOut(duration: 0.3), value: getScale(proxy: geometry))
}
}
}
}
}
.contentMargins(50, for: .scrollContent)
.scrollTargetBehavior(.viewAligned)
.scrollTargetLayout()
.padding(.horizontal, 10)
.padding(.top, -35)
.padding(.bottom, 50)
}
}
}
}
}
There seems to be a performance issue when scrolling using the track pad with SwiftUI scroll views in macOS 15. This issue is NOT present in macOS 14.
When using the track pad the scrolling is not smooth, but "stutters". However scrolling using the scroll bars is very smooth. The "stuttering" is worse if the SwiftUI ScrollView is in the detail view of a NavigationSplitView.
The problem is not noticeable in scroll views with a small number views, but when the more views inside the scroll view, the more prominent the problem becomes.
I have a simple example app that illustrates the problem here (the example app is a simplification of my app Yammixer): https://github.com/danwaltin/SwiftUIScrollViewPerformance
When running this example app on macOS 14 (Sonoma) on an Intel i7 Mac book pro from 2019 the scrolling is "buttery smooth".
But on macOS 15 (Sequoia) on my Apple Silicon M1 Mac book pro the issue is very obvious.
When using Instruments I see that on macOS 15 "flame graph" shows that 85% of the execution time is in a "_hitTestForEvent" method. If the test app does not use NavigationSplitView about 70% of execution time is in the _hitTestForEvent method.
Using this adapted code snippet from the Apple Developer Documentation,
struct ContentView: View {
@State var nameComponents = PersonNameComponents()
var body: some View {
Form {
TextField(
"Proper name",
value: $nameComponents,
format: .name(style: .medium)
)
.onSubmit {
}
.disableAutocorrection(true)
.border(.secondary)
Text(nameComponents.debugDescription)
}
}
}
It runs and works as expected on my iOS device. When I use this same code in my macOS app, it has unexpected results. The validation mechanism (likely caused by format: .name(style: .medium) in order to bind the TextField to a PersonNameComponents instance, will not let me add spaces or delete all the text in the TextField. I have to write the first name in this format: "FirstLast" and then add a space in between the t and L. Are there any ways I can fix this on macOS while still binding my TextField to a PersonNameComponents instance?
I created a simple animation of a circle that changes sizes. The circle pulses like a heartbeat in the center of the screen. My expectation was for the CPU use to be very low, but that is not the case. In addition, even if the CPU use isn't as low as I would expect, I did not expect the CPU use to increase over time because nothing else is happening in the app. Here is the code:
import SwiftUI
@main
struct TestApp: App {
var body: some Scene {
WindowGroup {
SplashScreenView()
}
}
}
import SwiftUI
struct SplashScreenView: View {
var body: some View {
ZStack {
SplashNucleusView(minSize: 50, maxSize: 100)
}
}
}
import SwiftUI
struct SplashNucleusView: View {
let minSize: Double
let maxSize: Double
@State private var nucleusColor: Color = .primary
@State private var nucleusRadius: Double = 10
@State private var nucleusOpacity: Double = 1.0
private var nucleusAnimation: Animation {
.easeInOut(duration: 0.25)
.repeatForever(autoreverses: true)
}
let timer = Timer.publish(every: 0.5, on: .main, in: .common).autoconnect()
var body: some View {
Circle()
.fill(nucleusColor)
.frame(width: nucleusRadius)
.opacity(nucleusOpacity)
.onReceive(timer) { _ in
withAnimation(nucleusAnimation) {
nucleusRadius = Double.random(in: minSize...maxSize)
}
}
}
}
This is how the animation looks:
The animation is snappy until the CPU use reaches 95%, at which point there is visible stuttering. Here is how the CPU looks when the animation duration value is 0.5 seconds and the timer publishing interval is 3 seconds:
Changing the animation duration value to 0.25 seconds and the timer publishing interval to 0.5 seconds changes the CPU use as follows:
The complete view has many other moving parts, which make the issue much worse. The issue is evident with only the circle view. I spent hours working with the debugger, reading about animations, and testing new approaches, but the result is always the same.
Why is this happening?
I am working on creating a file viewer to browse a network directory as a way to introduce myself to iOS app development, and was trying to implement a feature that would allow users to drag and drop both files and folders onto another folder inside of the app to move items around. However, it seems that if the View that is set to draggable, and then the view that is set as the Drop Destination is in the same List, then the Drop Destination will not detect when the draggable view has been dropped onto it. Here is the structure of my code:
List {
Section(header: Text("Folders")) {
ForEach($folders, id: \.id) { $folder in
FolderCardView()
.onDrop(of: [UTType.item], isTargeted: $fileDropTargeted, perform: { (folders, cgPoint) -> Bool in
print("Dropped")
return true
})
}
}
Section(header: Text("Files")) {
ForEach($files, id: \.id) { $file in
FileCardView()
.onDrag({
let folderProvider = NSItemProvider(object: file)
return folderProvider
})
}
}
}
I have verified that the issue comes down to the list, because if I move both of the ForEach loops out on their own, or even into their own respective lists, the code works perfectly. I have not only tested this with the older .onDrop and .onDrag modifiers as shown above, but also the newer .draggable and .dropDestination modifiers, and the result is the same.
Does anyone know if this is intended behavior? I really like the default styling that the List element applies to other elements within, so I am hoping that it might just be a bug or an oversight. Thanks!
Hi,
I am writing a calculator app in Swift 5 and decided to support eastern asian numerals to make it a bit interesting. The numeric display itself works well in Arabic langauge setting, but I have a protocol view that reports the entered data and results. I do it in a Grid with two Text items, one for the input and one for the result. The result contains a numeric string in U0660... arabic numerals, and that looks fine. The input is a construct looking like Text(number1) + Text(" ") + Text(operation), so it goes into a single Grid cell.
The standard version looks like this:
but the arabic version shows the numbers and operation symbols in the wrong sequence:
I guess that has something to do with the mathematical symbols such as + and = simply register as ltr Text and confuse the text layout. If I localize π, the result looks different:
So my question would be: How do I force a fragment such as Text(" +") to go in rtl direction? Is this a SwiftUI topic or doesit go deeper? I am looking at the Text element now, but may be that is the wrong approach.
Hi all,
by chance, we introduced code similar to the following in the body of one of our views:
struct MyView: View {
let myInt: Int
var body: some View {
EmptyView() // Empty body
.onChange(of: myInt) { newValue in
…
}
}
}
Notice that a simple let of type Int is used here, rather than State or something similar. While it works and onChange is actually triggered when views are rebuilt, I’d like to clarify a few things:
Is this behavior actually expected and reliable, or is it a gray area and can be changed in the future?
If it is expected, can this be made clearer in the documentation?
If it is a gray area, can the documentation be improved to address it?
Thanks!