I've got an array of items that I use as a source of truth, and I copy that array into another array (filteredItems) and use that to power a NavigationSplitView (on MacOS).
I can sort the items in filteredItems by create date, title, last modified date, forward and reverse, no problem. And I have a text filter field that I can use to filter out items in the filteredItems field and that works great.
So far so good.
But if I reduce the filter text or remove it altogether—thus increasing the number of items in filteredItems or returning it to its original state—weird things happen.
Clicking on items in the navigation portion of the view doesn't bring up the detail view as it did before the reduction and re-adding of items.
After clicking on several of the non-responsive nav items, it freezes up.
I know there are different ways to do this, but my view is set up like this:
NigationSplitView {
// filter tool, etc.
List {
ForEach(ascending ? filteredItems : filteredItems.reversed()) { item in
NavigationLink {
ItemView(item: item)
} label: {
// yadda yadda
}
}
}
(ascending is just a boolean state variable)
I know there's not much detail here, but I should be able to change filteredItems as much as I want, right? Or is this construct wrong?
SwiftUI
RSS for tagProvide views, controls, and layout structures for declaring your app's user interface using SwiftUI.
Post
Replies
Boosts
Views
Activity
The main view contains a Form with multiple Sections, including TextFields and NavigationLinks. I used an @FocusState variable to automatically pop up the keyboard when entering the main view, making it easier for users to input content directly in the TextField.
However, when I keep the keyboard open and click a NavigationLink in the Section to enter a child view, I can't find a way to automatically dismiss the keyboard upon entering the child view. I've seen several official Apple apps, like Reminders, achieve this.
Not dismissing the keyboard causes it to automatically pop up again when returning to the main view, along with triggering a "Unable to simultaneously satisfy constraints" error in the console.
I asked GPT for help, but the suggestions, like using simultaneousGesture or adding isActive to the NavigationLink (which might be deprecated), haven't worked. Has anyone in iOS development encountered this issue?
Hi,
Im trying to use ForEach without list to get rid of the navigation chevron , but the sipe to delete modifier stop working, is there a some solution ?
Kind Regards
Button(role: .destructive) {
deletePatient(patient: patient)
} label: {
VStack {
Label("Delete", systemImage: "trash")
Image(systemName: "Trash")
}
}
}
I used standard font styles in an iOS app. For example .font(.headline). I hoped that developing this way would allow the adoption of the app to other platforms, relatively easy.
However, when trying to run for iPadOS, the text did not increase in size to occupy the more abundant space offered by larger screen, but it actually shrank. Overall, the app does not look great "automatically".
Why does it happen?
What is the best practice for cross platform development with SwiftUI (with regards to font sizes). I want to make as little as possible human interface design decisions on my own and just let SwiftUI take care of everything. (But I also want the results to look as Apple would consider great looking)
I'm new to Swift and I got this error today. I have another SwiftUI page with the same code but the error doesn't appear there.
struct CardView: View {
var location: String
var description: String
var imageName: String
var body: some View {
VStack{
Image(imageName)
.resizable()
.aspectRatio(contentMode: .fill)
.frame(width: 300, height: 200) // Set a fixed height for each card
.background(Color.black.opacity(0.7))
VStack(alignment: .leading) {
Spacer()
Text(location)
.padding(15)
.font(.headline)
.fontWeight(.bold)
.frame(width:300, alignment: .init(horizontal: .leading, vertical: .center))
.foregroundColor(.black)
.bold()
.background(Color.white)
.clipShape(RoundedCorner(radius: 10, corners: [.topLeft, .topRight]))
.padding([.leading, .trailing], -14)
.padding(.bottom, 10)
.offset(y: -213)
.offset(x: 28)
Text(description)
.font(.body)
.foregroundColor(.black)
.frame(width:300, alignment: .init(horizontal: .leading, vertical: .center))
.background(Color.white)
.clipShape(RoundedCorner(radius: 10, corners: [.bottomLeft, .bottomRight]))
.padding([.leading, .trailing], 14)
.padding(.bottom, 10)
.multilineTextAlignment(.leading)
.lineLimit(nil)
.offset(y: 2)
}
.padding()
.frame(width: 200)
.fixedSize()
}
.frame(height: 350) // Ensure each card has a fixed height
.background(Color.white)
.cornerRadius(10)
.shadow(radius: 5)
.padding([.leading, .trailing], 5) // Add padding to the sides for spacing
}
}
}
}
I am very knew to SwiftUL. First first Projectv was to copy a working SwiftUL code as follows:
//
// ContentView.swift
// Project2
//
// Created by Ian Steward on 10/20/24.
//
import SwiftUI
struct ContentView: View {
var body: some View {
VStack(spacing: 20) {
Text("SwiftUI Button")
.font(.largeTitle)
Text("Enabled & Disabled")
.font(.title)
.foregroundColor(.gray)
/* Disabled */
Button("Enabled") {}
.buttonStyle(.borderedProminent)
.tint(.blue)
.controlSize(.large)
Button("Disabled") {}
.buttonStyle(.borderedProminent)
.tint(.blue)
.controlSize(.large)
.disabled(true)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
I get and error saying:
"Reference to member 'tint' cannot be resolved without a contextual type" on both both lines that have .tint(.blue)
Any ideas on how to correct the issue
I am building an app where tasks can be shown on multiple selected days. The user will select a day and the available tasks should be shown. I am struggling to build a view hierarchy where the visible tasks will update when added to the currently shown day.
A simplified model looks like the below:
@Model final class Day
{
private(set) var dayID: UUID = UUID()
var show: [Item]?
}
@Model final class Item
{
private(set) var itemID: UUID = UUID()
@Relationship(inverse: \Day.show) var showDays: [Day]?
}
I have a view representing a day, and I would like it to display a list of associated tasks below.
The view doesn't update if I list a day's tasks directly, e.g. List(day.show) {}
I get a compile error if I build a sub view that queries Item using the day's show array:
let show = day.show ?? []
let predicate = #Predicate<Item> { item in
show.contains(where: { $0.itemID == item.itemID }) }
I get runtime error if I flip the predicate:
let dayID = day.dayID
let predicate: Predicate<Item> = #Predicate<Item> { item in
item.showDays.flatMap { $0.contains(where: { $0.dayID == dayID }) } ?? false }
I'm at a loss of how to approach this, other that just forcing the whole view hierarchy to update every time a make a change.
Is there a recommended approach to this situation please?
Does anyone have any idea why withAnimation is buggy when you apply a clip shape to an image? I've attached a screenshot of what happens below. Sometimes when hovering, it looks like the item gets drawn at the wrong location for a frame or two and then is placed back into position and the animation starts. It doesn't happen when the hover state ends, only the very initial hover event. This also doesn't happen without the .clipShape. I've also tried using .mask, but the same issue occurs. Has anyone ran into this?
When first opening my app, the first view navigated to loads and then a second later reloads. When navigating away and back to the view, it only loads once as designed.
Has anyone ever experienced this before and knows of any obvious reasons?
I can upload code snippets later, the views are wrapped in navigation links.
Thanks for any help
The sample code provided in "Building a document-based app with SwiftUI" (https://developer.apple.com/documentation/swiftui/building-a-document-based-app-with-swiftui) does not work as expected.
The DocumentGroup/StoryView toolbar does not appear for documents opened in the App.
By removing the DocumentGroupLaunchScene block from the App the toolbar does appear and works as expected - but of course the App's DocumentGroupLaunchScene customizations are lost.
I've tested this on 18.0 devices, as well as production 18.0 and 18.1 beta 6 simulators.
If I modify the StoryView by wrapping the content in a NavigationStack I can make some progress - but the results are unstable and hard to pin down - with this change the first time a document is opened in the WritingApp the toolbar appears as expected. When opening a document subsequently the toolbar is corrupted.
Please is this a bug or is there a good example of incorporate both DocumentGroupLaunchScene customizations at the App level and retina the toolbar in documents presented via DocumentGroup?
I have noticed a strange bug with TabView in the settings window of an macOS app. When text is typed into a textbox, the icon jiggles a little bit, but ONLY on a non-retina monitor (1920x1200 in my test). Some icons jiggle, others don’t. Below is code for the gearshape which exhibits this behavior. “sparkle” doesn’t. Very odd. Tried on macOS 15.0.1, Xcode 16.
You can see it in action here
https://imgur.com/a/huCw7sN
// App file
@main
struct TabViewJiggleApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
Settings {
SettingsView()
}
}
}
// Settings view
struct SettingsView: View {
@State private var input: String = ""
var body: some View {
TabView {
TextField("Enter text", text: $input)
.tabItem {
Label("General", systemImage: "gearshape")
.font(.system(size: 20))
}
}
}
}
Hello.
I'm developing a program for macOS.
It's so difficult because it hasn't been long since I developed it.
I have a question while looking at the memo app or calendar app.
The calendar comes in red when selected (context menu is also red) and the memo app comes in yellow when selected and I was wondering if I could implement that function with swiftUI.
I’m trying to use TabView as a page view, but I’m having some trouble. When I select a tab, the content gets cut off. I tried setting scrollClipDisabled, but that didn’t help.
var body: some View {
TabView {
Button {
} label: {
AsyncImage(
url: URL(
string:
"https://plus.unsplash.com/premium_photo-1693227521269-d90b70e3ee06?q=80&w=2940&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
)
) { image in
image
.resizable()
.aspectRatio(contentMode: .fit)
} placeholder: {
Color.red
}
}
.buttonStyle(.borderless)
}
.scrollClipDisabled()
.tabViewStyle(.page(indexDisplayMode: .always))
.indexViewStyle(.page(backgroundDisplayMode: .always))
Button("Button") {
}
}
If you switch between tab content and the button, you will notice that the bottom corner radius is clipped.
Does anyone have any idea how to avoid this action?
I’m currently working on a VisionOS project and was wondering if Apple provides an official component for dragging UI elements, similar to how you can drag a window from its footer in vi sion os. Specifically, I’m looking for a way to allow users to drag and move UI elements without directly interacting with the component itself (since this could trigger unintended interactions with its content, like on a webpage). I’ve tried adding a draggable rectangle below the component, but it causes flickering and doesn’t feel smooth, but I’d like to use any built-in functionality that Apple might already offer for this in VisionOS.
If anyone has experience with this or knows if such a component exists, I’d really appreciate your insights!
Thanks in advance!
Let me know if you’d like to tweak anything!
Hi,
I'm a bit stuck when it comes to implementing live activities.
I'm trying to start one by sending a push.
my activity attributes looks like:
import Foundation
import ActivityKit
public struct NeoPrototypeActivity: ActivityAttributes {
public let classId: String
public let name: String
public let room: String
public let startTime: Date
public init(classId: String, name: String, room: String, startTime: Date) {
self.classId = classId
self.name = name
self.room = room
self.startTime = startTime
}
public struct ContentState: Codable & Hashable {
public let participationState: ParticipationState
public init(participationState: ParticipationState) {
self.participationState = participationState
}
}
}
public enum ParticipationState: String, Codable, Hashable, Equatable {
case upcoming
case upcomingOnWaitingList
case checkedIn
case waitingList
case lostSpot
case lostSpotFromWaitingList
case classCompleted
public var description: String {
switch self {
case .upcoming: return "Upcoming"
case .upcomingOnWaitingList: return "Upcoming on Waiting List"
case .checkedIn: return "Checked In"
case .waitingList: return "Waiting List"
case .lostSpot: return "Lost Spot"
case .lostSpotFromWaitingList: return "Lost Spot from Waiting List"
case .classCompleted: return "Class completed"
}
}
}
which I have in a SPM package that is imported by my widget and iOS targets.
Then I am sending a push notification (to my simulator in this case) with the following payload
{
"aps": {
"timestamp": 1728419211,
"event": "start",
"content-state": {
"participationState": "upcoming"
},
"attributes-type": "NeoPrototypeActivity",
"attributes": {
"classId": "1234",
"name": "Indoor Running",
"room": "room 2",
"startTime": "2024-10-19T13:22:59+02:00"
},
"alert": {
"title": "Hola Mundo",
"body": "Todo Bien"
}
}
}
I am using the right values for the deviceID when sending the push.
I get a 200 ok from the CloudKit console.
yet my live activity doesn't start.
I'm trying to look at the errors in the Console app and the only relevant thing is see is:
[NeoPrototypeActivity] Error creating activity: NSCocoaErrorDomain (4864) The data couldn’t be read because it isn’t in the correct format.
It seems like a decoding error, but I don't know what exactly failed
I wrote some test to try the decoding like:
import Testing
import Foundation
@testable import PrototypeActivities
@Test func decoding() async throws {
struct StateContainer: Codable {
let participationState: ParticipationState
}
let jsonString = """
{
"participationState": "upcoming"
}
"""
let json = try #require(jsonString.data(using: .utf8))
let result = try JSONDecoder().decode(StateContainer.self, from: json)
#expect(result.participationState == .upcoming)
}
@Test func decodingActivity() throws {
// let jsonString = """
// {
// "classId": "1234",
// "name": "Indoor Running",
// "room": "room 2",
// "startTime": "2024-10-19T11:22:59Z"
// }
// """
let jsonString = """
{
"classId": "1234",
"name": "Indoor Running",
"room": "room 2",
"startTime": 1729337784
}
"""
let json = try #require(jsonString.data(using: .utf8))
let jsonDecoder = JSONDecoder()
// jsonDecoder.dateDecodingStrategy = .iso8601
let activity = try jsonDecoder.decode(NeoPrototypeActivity.self, from: json)
#expect(activity.classId == "1234")
#expect(activity.name == "Indoor Running")
}```
but even with using the default JSON decoder date format, I still get the same error.
Not sure how to fix this or to get more details.
Hey there,
Is there a way to launch another view by tapping on the preview of a context menu? Something like the behavior of the Photos app where tapping on the preview navigates to the details view.
Tap gesture handlers on the preview don't seem to get called, even as high priority gestures.
Thanks for the help!
Gab
I've got another issue with Gesture.updating(_:body:).. This looks a bit like this thread, but it's different. My problem occurs when creating a simultaneous gesture combining a RotateGesture with a MagnifyGesture.
struct ManipulationState: Equatable {
var magnification: CGFloat?
var rotation: Angle?
}
@GestureState var state: ManipulationState? = nil
var gesture: GestureStateGesture<SimultaneousGesture<RotateGesture, MagnifyGesture>, ManipulationState?> {
SimultaneousGesture(
RotateGesture(minimumAngleDelta: .degrees(5)),
MagnifyGesture(minimumScaleDelta: 0.1)
)
.updating($state) { value, state, transaction in
state = ManipulationState(
magnification: value.second?.magnification,
rotation: value.first?.rotation
)
}
}
When rotating and magnifying quite a bit, at some point, something happens, the gesture stops working altogether and the state never resets to the initial value any more.
When adding an onChange handler to some view in the body, you can watch state never gets nil again.
.onChange(of: state, { oldValue, newValue in
print("\(oldValue) \(newValue)")
})
I noticed the same happening when using ExclusiveGesture instead of SimultaneousGesture.
Full code example here: https://github.com/teameh/GestureIssueTester/blob/main/GestureTester/ContentView.swift
Video demonstrating issue here: https://github.com/teameh/GestureIssueTester/raw/refs/heads/main/screen-recording.mov
I've tried using Gesture.onChanged(_:) and Gesture.onEnded(_:)as well, butonEnded` is also not always called.
Is there anyone here who ran into the same problem or perhaps someone can share tips on a workaround or a fix?
Tested using Xcode 16.0 (16A242d)
With iOS 18, Text has a new initializer that takes in a TimeDataSource and a DiscreteFormatStyle.
Similar to this question, I'd like to make a compact timer but can't find a way to do that with any of the system formats.
Since the new API takes in a DiscreteFormatStyle though I figure I could make my own. This works in an app but not in a Live Activity; in Previews it crashes and in the simulator the view looks like placeholder.
Are custom format styles not supported in this case? Or might there something wrong with my implementation?
Formatter
Preview Crash Log
Hello, This code has a NavigationSplitView, whose sidebar is a List and its detail contains a NavigationStack. It is controlled by two @Observable properties, a selection and a path. The path shown in the detail depends upon the selection in the List. If I programmatically change the selection and path, the path will be set, but via SwiftUI backtraces (pasted below), it will clear out my path. This makes my code lose state. What am I doing wrong? Is this a bug? I'm using Xcode16 running against the iOS 18 simulator (although this also happens with iOS17).
To reproduce, Launch the App, Note that you are on the "first" selection. Tap "Nav Path: Path: second-100". You'll go to the "second" selection, but the path will be empty. If you place a breakpoint when the $path is cleared, you'll see it is being cleared by SwiftUI.
Backtrace when the path is emptied:
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 2.1
* frame #0: 0x00000001043295c0 DoubleNav.debug.dylib`Navigation.path.setter(newValue=0 values) at ContentView.swift:86:22
frame #1: 0x00000001043296d0 DoubleNav.debug.dylib`key path setter for Navigation.path : Navigation at <compiler-generated>:0
frame #2: 0x000000019485b500 libswiftCore.dylib`Swift.NonmutatingWritebackBuffer.__deallocating_deinit + 132
frame #3: 0x0000000194a351c4 libswiftCore.dylib`_swift_release_dealloc + 28
frame #4: 0x0000000194a35bd4 libswiftCore.dylib`bool swift::RefCounts<swift::RefCountBitsT<(swift::RefCountInlinedness)1>>::doDecrementSlow<(swift::PerformDeinit)1>(swift::RefCountBitsT<(swift::RefCountInlinedness)1>, unsigned int) + 156
frame #5: 0x00000001d2f5f584 SwiftUICore`closure #1 () -> () in SwiftUI.ObjectLocation.set(_: τ_0_1, transaction: SwiftUI.Transaction) -> () + 132
frame #6: 0x00000001d2f5f6b0 SwiftUICore`partial apply forwarder for closure #1 () -> () in SwiftUI.ObjectLocation.set(_: τ_0_1, transaction: SwiftUI.Transaction) -> () + 28
frame #7: 0x00000001d2801da8 SwiftUICore`generic specialization <()> of closure #1 () throws -> τ_0_0 in SwiftUI.withTransaction<τ_0_0>(SwiftUI.Transaction, () throws -> τ_0_0) throws -> τ_0_0 + 296
frame #8: 0x00000001d2f5f4d8 SwiftUICore`SwiftUI.ObjectLocation.set(_: τ_0_1, transaction: SwiftUI.Transaction) -> () + 336
frame #9: 0x00000001d2c42468 SwiftUICore`SwiftUI.LocationBox.set(_: τ_0_0.Value, transaction: SwiftUI.Transaction) -> () + 148
frame #10: 0x00000001d2c42c84 SwiftUICore`protocol witness for SwiftUI.Location.set(_: τ_0_0.Value, transaction: SwiftUI.Transaction) -> () in conformance SwiftUI.LocationBox<τ_0_0> : SwiftUI.Location in SwiftUI + 20
frame #11: 0x00000001d2c42e90 SwiftUICore`SwiftUI.ProjectedLocation.set(_: τ_0_1.Projected, transaction: SwiftUI.Transaction) -> () + 196
frame #12: 0x00000001d2c42468 SwiftUICore`SwiftUI.LocationBox.set(_: τ_0_0.Value, transaction: SwiftUI.Transaction) -> () + 148
frame #13: 0x00000001d2cf2fe8 SwiftUICore`SwiftUI.Binding.ScopedLocation.set(_: τ_0_0, transaction: SwiftUI.Transaction) -> () + 28
frame #14: 0x00000001d2c42468 SwiftUICore`SwiftUI.LocationBox.set(_: τ_0_0.Value, transaction: SwiftUI.Transaction) -> () + 148
frame #15: 0x00000001d2cf3190 SwiftUICore`function signature specialization <Arg[0] = Owned To Guaranteed> of SwiftUI.Binding.wrappedValue.setter : τ_0_0 + 32
frame #16: 0x00000001d2cf12c0 SwiftUICore`SwiftUI.Binding.wrappedValue.setter : τ_0_0 + 28
frame #17: 0x00000001d1d0e538 SwiftUI`closure #1 () -> () in SwiftUI.NavigationColumnState.popAllForSelectionChange(popReplacedRoots: Swift.Bool) -> SwiftUI.NavigationState.RequestResults + 524
frame #18: 0x00000001d281be58 SwiftUICore`partial apply forwarder for reabstraction thunk helper from @callee_guaranteed (@guaranteed Swift.Dictionary<__C.NSAttributedStringKey, Any>, @unowned __C._NSRange, @unowned Swift.UnsafeMutablePointer<ObjectiveC.ObjCBool>) -> () to @escaping @callee_guaranteed (@guaranteed Swift.Dictionary<__C.NSAttributedStringKey, Any>, @unowned __C._NSRange, @unowned Swift.UnsafeMutablePointer<ObjectiveC.ObjCBool>) -> () + 20
frame #19: 0x00000001d2b3b64c SwiftUICore`static SwiftUI.Update.dispatchActions() -> () + 1080
frame #20: 0x00000001d2b3ac4c SwiftUICore`static SwiftUI.Update.end() -> () + 108
frame #21: 0x00000001d18daf44 SwiftUI`closure #1 (Swift.Optional<Swift.UnsafeMutableRawPointer>, Swift.Double, Swift.UnsafePointer<__C._UIUpdateTiming>) -> () in static SwiftUI.UIKitUpdateCycle.addPreCommitObserver(() -> ()) -> () + 168
frame #22: 0x00000001d18dafbc SwiftUI`reabstraction thunk helper from @escaping @callee_guaranteed (@unowned Swift.Optional<Swift.UnsafeMutableRawPointer>, @unowned Swift.Double, @unowned Swift.UnsafePointer<__C._UIUpdateTiming>) -> () to @escaping @callee_unowned @convention(block) (@unowned Swift.Optional<Swift.UnsafeMutableRawPointer>, @unowned Swift.Double, @unowned Swift.UnsafePointer<__C._UIUpdateTiming>) -> () + 64
frame #23: 0x0000000185030388 UIKitCore`_UIUpdateSequenceRun + 76
frame #24: 0x00000001859d22e8 UIKitCore`schedulerStepScheduledMainSection + 168
frame #25: 0x00000001859d1720 UIKitCore`runloopSourceCallback + 80
frame #26: 0x000000018041b324 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 24
frame #27: 0x000000018041b26c CoreFoundation`__CFRunLoopDoSource0 + 172
frame #28: 0x000000018041a9d0 CoreFoundation`__CFRunLoopDoSources0 + 232
frame #29: 0x00000001804150b0 CoreFoundation`__CFRunLoopRun + 788
frame #30: 0x0000000180414960 CoreFoundation`CFRunLoopRunSpecific + 536
frame #31: 0x0000000190183b10 GraphicsServices`GSEventRunModal + 160
frame #32: 0x0000000185aa2b40 UIKitCore`-[UIApplication _run] + 796
frame #33: 0x0000000185aa6d38 UIKitCore`UIApplicationMain + 124
frame #34: 0x00000001d1e2eab4 SwiftUI`closure #1 (Swift.UnsafeMutablePointer<Swift.Optional<Swift.UnsafeMutablePointer<Swift.Int8>>>) -> Swift.Never in SwiftUI.KitRendererCommon(Swift.AnyObject.Type) -> Swift.Never + 164
frame #35: 0x00000001d1e2e7dc SwiftUI`SwiftUI.runApp<τ_0_0 where τ_0_0: SwiftUI.App>(τ_0_0) -> Swift.Never + 84
frame #36: 0x00000001d1b70c8c SwiftUI`static SwiftUI.App.main() -> () + 148
frame #37: 0x0000000104333df0 DoubleNav.debug.dylib`static DoubleNavApp.$main() at <compiler-generated>:0
frame #38: 0x0000000104333ea0 DoubleNav.debug.dylib`main at DoubleNavApp.swift:11:8
frame #39: 0x00000001048f9410 dyld_sim`start_sim + 20
frame #40: 0x000000010440e154 dyld`start + 2476
Thanks for any tips!
Here's the code.
Hello
Is it possible to access the blocked calls list, from CallKit or something similar ?
Thank you