Task:
A child view should show depending on a boolean flag the corresponding view. The flag is calculated from a model which is given by parent view.
Problem:
The flag is false in init, which is correct. However in body it's true, which is incorrect. Why value in body isn't consistent to init? Is there a race condition? The child view's is rendered thrice, that's another issue, but flag is in init and body as described before.
Parent view looks like this:
struct ParentView: View {
private var groupedItems: [GroupedItems] = []
init(items: [Item]) {
Dictionary(grouping: items) { $0.category.name }
.forEach {
let groupedItems = GroupedItems(categoryName: $0.key, items: $0.value)
self.groupedItems.append(groupedItems)
}
}
var body: some View {
ChildView(groupedItems)
}
}
Child view looks like this:
struct ChildView: View {
@State private var showItems: Bool
init(_ groupedItems: GroupedItems) {
self._showItems = State(initialValue: !groupedItems.completed)
}
var body: some View {
if showItems {
AView()
} else {
BView()
}
}
}
Model looks like this:
@Model
final class Item: Identifiable {
@Attribute(.unique) public var id: String
public var name: String
public var completed = false
}
struct GroupedItems {
var categoryName: String
var items: [Item]
var completed: Bool {
items.filter { !$0.completed }.isEmpty
}
}
Explore the various UI frameworks available for building app interfaces. Discuss the use cases for different frameworks, share best practices, and get help with specific framework-related questions.
Post
Replies
Boosts
Views
Activity
Is there a trick to getting the new Live Activities on Apple Watch working via the simulator? I have an iPhone paired to a watch simulator, but live activities created on the phone aren't appearing on the watch Smart Stack.
It looks like maybe the Smart Stack isn't functional on the watch simulator, as there are a bunch of blank tiles where the Smart Stack should be.
when I click on a mapview pin, a PopupView comes up with some text and a button. I want to be able to navigate to another DetailsView by clicking on the button display in the popup, the button is embedded inside NavigationLink. But clicking on the button nothing happens. How to navigate from button click?
struct MyMapView: View {
@State var position: MapCameraPosition = .automatic
@State var showCallout: Bool = false
@State var selected: PinAnnotation?
@Binding var locationPins: [PinAnnotation]
@State private var toggler = false
var body: some View {
Map(position: $position) {
ForEach(locationPins, id: \.self) { result in
Annotation(result.title!, coordinate: result.coordinate) {
ZStack {
Image(systemName: "mappin.circle.fill")
.resizable()
.scaledToFit()
.frame(width: 30, height: 30)
.onTapGesture {
selected = result
toggler.toggle()
}
.foregroundStyle(.white, .purple)
if selected == result && toggler {
PopupView(pin: selected)
} else {
EmptyView()
}
}
}
}
}
}
struct PopupView: View {
@State var pin: PinAnnotation?
@State private var select: Int? = 0
var body: some View {
VStack (alignment: .leading) {
HStack {
if let val = pin {
Text(val.text)
.font(.system(size: 12, weight: .light, design: .default))
NavigationLink(destination: DetailsView(), label: {
Button(action: {select = 1}){
Image(systemName: "play.circle")
}
.scaledToFit()
.frame(width: 50, height: 50)
.background(Color.blue)
.foregroundColor(.white)
.clipShape(Circle())
})
} else {
Text("no data")
}
}
// .fixedSize()
}
.scaledToFit()
.foregroundStyle(.purple)
.frame(maxWidth: .infinity)
.background(Color.white)
.cornerRadius(10)
.shadow(radius: 5)
.offset(x: 0, y: -45)
}
}
struct DetailsView: View {
@Environment(\.presentationMode) var presentation
var body: some View {
Group {
Button("Back") {
self.presentation.wrappedValue.dismiss()
}
}
}
}
}
public func getVideoThumbnailImage(url: URL) -> Image {
let urlAsset = AVURLAsset(url: url, options: nil)
let assetImageGenerator = AVAssetImageGenerator(asset: urlAsset)
assetImageGenerator.appliesPreferredTrackTransform = true
assetImageGenerator.apertureMode = .encodedPixels
let cmTime = CMTime(seconds: 1, preferredTimescale: 60)
var thumbnailCGImage: CGImage?
var errorOccurred = false
let semaphore = DispatchSemaphore(value: 0)
assetImageGenerator.generateCGImageAsynchronously(for: cmTime) { generatedImage, timeGenerated, error in
if error == nil {
if let cgVideoImage = generatedImage {
thumbnailCGImage = cgVideoImage
} else {
errorOccurred = true
}
} else {
errorOccurred = true
}
semaphore.signal()
return
}
_ = semaphore.wait(timeout: .now() + 30)
if errorOccurred {
return Image("ImageUnavailable")
}
if let thumbnailImage = thumbnailCGImage {
let uiImage = UIImage(cgImage: thumbnailImage)
return Image(uiImage: uiImage)
}
return Image("ImageUnavailable")
}
I am using Xcode 16 beta 2 for iOS 18 with SwiftUI.
My code above works instantly and correctly; however, Xcode produces the purple warning: "Thread running at User-interactive quality-of-service class waiting on a lower QoS thread running at Default quality-of-service class. Investigate ways to avoid priority inversions"
How can I change the code to avoid the purple warning?
Hi everyone,
I’m having an issue with SwiftUI where my entire Section becomes clickable, instead of just the “Edit profile” button. Here’s my code:
VStack(alignment: .center) {
KFImage(authManager.user?.photoURL)
.resizable()
.scaledToFill()
.frame(width: 80, height: 80)
.clipShape(Circle())
Text(authManager.user?.displayName ?? "")
.font(.system(.title, design: .rounded))
Text(authManager.user?.email ?? "")
.font(.subheadline)
.foregroundColor(.gray)
NavigationLink {
EditProfileView()
} label: {
Text("Edit profile")
.frame(minWidth: 0, maxWidth: .infinity)
.font(.system(size: 18))
.padding(10)
.foregroundColor(.white)
.background(Color.blue)
.cornerRadius(25)
}
.padding(.top, 5)
}
.frame(maxWidth: .infinity, alignment: .center)
}
I want only the button to be clickable. How can I fix this?
Thanks!
Link to issue: https://imgur.com/a/iO9aNSM
The SwiftUI previews have been working fine in Xcode 16.0 beta, but ever since I added Firebase into my app, I've been getting error with previews.
CrashReportError: IshaanCord crashed
IshaanCord crashed. Check ~/Library/Logs/DiagnosticReports for crash logs from your application.
Process: IshaanCord[5651]
Date/Time: 2024-07-04 19:29:51 +0000
Log File: <none>
"Cannot preview in this file"
Does anyone know how to fix this? Thank you.
Hi, I can't get onScrollPhaseChange to fire when using a List. It works as expected when using a ScollView and LazyVStack.
Interestingly, onScrollGeometryChange gets called as expected for both List and ScrollView.
Has anyone successfully used onScrollPhaseChange with a List?
I am running into some Swift 6 concurrency errors that I think are due to an odd oversight in the UIAccessibility Swift interface.
There are a number of constants defined in here for various things, most of which are marked "let" (appropriately).
However, the constants for notifications in extension UIAccessibility.Notification are all marked as var for some reason. For example:
public static var pageScrolled: UIAccessibility.Notification
Because it is var, not let, anytime I try to access it, I get a concurrency violation. I am baffled as to how I am supposed to work around this.
For example, this line of code:
UIAccessibility.post(notification: .pageScrolled, argument: "test")
gives the error: "Reference to static property 'pageScrolled' is not concurrency-safe because it involves shared mutable state"
I can't for the life of me figure out how to work around this. I guess maybe define my own constant somewhere and suss out the rawValue somehow for now? This really needs to be fixed in the SDK.
I am trying to replace the navigation tab bar with a custom bottom toolbar when a view enters edit mode. Currently, I am using the following code to achieve this:
content
.toolbar(isEditing ? .hidden : .visible, for: .tabBar)
. toolbar(isEditing ? .visible : .hidden, for: .bottomBar)
However, this results in a janky animation. When the bottom bar appears, it animates in above (in contrast to in place of) the tab bar, then "jumps" back down to the correct offset without animation. I had to workaround this by delaying the appearance of bottom bar by 0.3s. I am already using withAnimation().
Is this a bug or am I using the APIs incorrectly? Is there a more seamless way to achieve this switching effect other than delaying the bottom bar? Thanks!
Hey, I am natively an ML Engineer so not really well versed in swift.
I am currently trying to use a model of mine in a swift app. The model detects knives and has an input size of 640x640.
i have set up AV capture and that works well I can just see the camera on my screen. I have also set up the coreML model and it also works and detects the objects.
so what doesnt work is the way I draw boxes around the object. e.g. the objects box params are Raw model output: x=342.25, y=293.0, w=105.375, h=150.5 when Im in the middle of the screen. seems ok for me, I want to draw a box now with these params. But the CGRect object is really weird to me, firstly the x value is the y value in the box (i notice this because when I move the object up and down , the x val will change but not the y val). then if I just switch the values, the drawn box will move ok in the y direction but mirrored in the x direction.
what things need to be considered/changed here, is it something about the layer setup? See my implementation here:
func setupLayers() {
previewLayer = AVCaptureVideoPreviewLayer(session: session)
previewLayer.videoGravity = AVLayerVideoGravity.resizeAspectFill
rootLayer = previewView.layer
previewLayer.frame = rootLayer.bounds
rootLayer.addSublayer(previewLayer)
inferenceTimeBounds = CGRect(x: rootLayer.frame.midX-75, y: rootLayer.frame.maxY-70, width: 150, height: 17)
inferenceTimeLayer = createRectLayer(inferenceTimeBounds, [1,1,1,1])
inferenceTimeLayer.cornerRadius = 7
rootLayer.addSublayer(inferenceTimeLayer)
detectionLayer = CALayer()
detectionLayer.frame = rootLayer.bounds
detectionLayer.position = CGPoint(x: rootLayer.bounds.midX, y: rootLayer.bounds.midY)
rootLayer.addSublayer(detectionLayer)
}
I have a project with two local packages
One client package with an interface and some models with dynamic type in the Package.Swift
One feature package with the UI and a dependency to the client package
When I try to preview a view that is not using any models or code from the client package, it loads just fine e.g. a view that is just a container to display things like a card
But when I tried to preview any other view that actually uses models from the client package, it just fails
the first few lines of the preview error display
LinkDylibError: Failed to build <filename>.swift
Linking failed: linker command failed with exit code 1 (use -v to see invocation)
ld: warning: search path '/Applications/Xcode-15.4.0.app/Contents/SharedFrameworks-iphonesimulator' not found
Undefined symbols for architecture arm64:
Also, I'm using Xcode 15.4 and iOS 17 as the min version
So I am banging my head, I realized my stand along Watch App had a STUPID long name of "App Name - WatchKit App" so I went into my Target and changed the Display Name to "App Name" removing WatchKit App. Well now my app won't validate when uploading to the Appstore. I get the message - Invalid Info.plist key. The key
WKExtensionDelegateClassName in bundle App Name.app/Watch/App Name WatchKit App.app is invalid.
My Info.plist has the value of
<key>WKExtensionDelegateClassName</key>
<string>$(PRODUCT_MODULE_NAME).ExtensionDelegate</string>
I have confirmed that I have @WKExtensionDelegateAdaptor(ExtensionDelegate.self) var delegate in my @main for the SwiftUI App. And when I print a few values in my app launch I get the following confirmations:
Super Init - ExtensionDelegate
Contentview
applicationDidFinishLaunching for watchOS
Super Init - ExtensionDelegate
Optional(My_App_Extension.Setup)
Optional(My_App_Extension.Statistics)
Optional(My_App_Extension.Other)
applicationDidBecomeActive for watchOS
update complication
I create three classes at launch and print this in the log with print(ExtensionDelegate.shared.Setup as Any) , etc. The other lines are just confirming where I am at app startup.
This is a WatchOS8 application and I am running Xcode version Version 13.1 (13A1030d).
DESCRIPTION OF PROBLEM
I have changed my app to the @Observable-Macro.
When using an iPhone (on simulator and on real device) the navigation from a player to the player detail view and back breaks. In the attached video on my GitHub you can see me tapping on both players in the team, but the navigation ist not showing the detail view.
What is the reason? Is my usage/understanding of @Observable wrong? Is it wrong to have the selectedPlayer within the PlayerController which is @Observable? And why does it sometimes work and sometimes not?
The project can be found here: GitHub Project
STEPS TO REPRODUCE
Start the App, add one or two demo teams, tap on a team and add two or more demo players.
tap a player and then go back, tap the player again and back again. After a while (number of taps is always different), the navigation breaks. See my video attached.
PLATFORM AND VERSION
iOS
Development environment: Xcode 15.4, macOS 14.5 (23F79)
Run-time configuration: iOS 17.5,
I‘m using a UITextView to allow users to post messages in AR in my app virtual tags - you may check by yourself, it is free - but it just allows to append text at end with no possibility of moving the cursor or do everything else. I opened a new project adding a UITextView and everything worked fine.
What could it be, and how to know more?
thanks, Fabrizio
Hey,
I have a setup in my app that I am currently building, that uses @Observable router objects that hold the app's entire navigation state, so that I can easily set it globally and let SwiftUI show the appropriate views accordingly. Each view gets passed in such a router object and there is a global "app" router that the app's root view can access as an entry point:
@Observable @MainActor
final class AppRouter {
static let shared = AppRouter() // Entry point used by the app's root view
var isShowingSheet = false // Navigation state
let sheetRouter = SheetRouter() // Router that's passed to the sheet view. This router could contain other routers for sheets it will show, and so on
}
@Observable @MainActor
final class SheetRouter { // Example of a "nested" router for a sheet view
var path = NavigationPath()
var isShowingOtherSheet = false
func reset() {
path = .init()
isShowingOtherSheet = false
}
}
To open a sheet, I have a button like this:
@Bindable var appRouter = AppRouter.shared
// ...
Button("Present") {
appRouter.sheetRouter.reset() // Reset sheet router
appRouter.isShowingSheet = true // show sheet
}
This seems to work perfectly fine. However, this produces tons of "error" logs in the console, whenever I open the sheet for a second time:
Mutating observable property \SheetRouter.path after view is torn down has no effect.
Mutating observable property \SheetRouter.path after view is torn down has no effect.
Mutating observable property \SheetRouter.path after view is torn down has no effect.
Mutating observable property \SheetRouter.path after view is torn down has no effect.
Mutating observable property \SheetRouter.isShowingOtherSheet after view is torn down has no effect.
These errors appear when calling the reset() of the sheet view's router before opening the sheet. That method simply resets all navigation states in a router back to their defaults. It's as if the sheetRouter is still connected to the dismissed view from the previous sheet, causing a mutation to trigger these error logs.
Am I misusing SwiftUI here or is that a bug? It's also worth mentioning that these error logs do not appear on iOS 17. Only on iOS 18. So it might be a bug but I just want to make sure my usage of these router objects is okay and not a misuse of the SwiftUI API that the runtime previously simply did not catch/notice. Then I'd have to rewrite my entire navigation logic.
I do have an example project to demonstrate the issue. You can find it here: https://github.com/SwiftedMind/PresentationBugDemo.
I have also filed a feedback for this: FB14162780
STEPS TO REPRODUCE
Open the example project.
Open the sheet in the ContentView twice by tapping "Present"
Close that sheet
Open it again.
Then the console will show these error logs from above.
I'd appreciate any help with this.
Cheers
A crash when Use UITextfield to display special characters "美҈̛̍̐̃͒̑́̌̆̾̒̿̒̚̚҈҉̵̶̸̷̷҇̒́̎͐͊̎̑̆́̓̽͂̊͋̑͛͑̈́̉̄̿́̏̽̎̓̋̓́̀̿͒͗͐̇҇͌̏͛͐̈́̑̀̏̏̋̏͑̊͋̈́̉̃̀̉͌̾̍͐͊̃́̉̍̈̎̒̊̉̚̕̚͠͝͠ 】". the system is iOS 16.3.1 and iOS 17.5.1
0
CoreFoundation
___exceptionPreprocess + 164
1
libobjc.A.dylib
_objc_exception_throw + 60
2
Foundation
_blockForLocation
3
UIFoundation
-[NSTextLineFragment _defaultRenderingAttributesAtCharacterIndex:effectiveRange:] + 104
4
UIFoundation
___53-[NSTextLineFragment initWithAttributedString:range:]_block_invoke + 72
5
CoreText
TLine::DrawGlyphsWithAttributeOverrides(CGContext*, __CFDictionary const* ( block_pointer)(long, CFRange*), void ( block_pointer)(CTLineDecorationType, void const*, bool, double, double, double, int, CGPoint, CFRange)) const + 424
6
UIFoundation
__NSCoreTypesetterRenderLine + 368
7
UIFoundation
-[NSTextLineFragment drawAtPoint:graphicsContext:] + 164
8
UIFoundation
-[NSTextLineFragment drawAtPoint:inContext:] + 88
9
UIFoundation
-[NSTextLayoutFragment drawAtPoint:inContext:] + 244
10
UIKitCore
__UITextCanvasDrawWithFadedEdgesInContext + 256
11
UIKitCore
-[_UITextLayoutFragmentView drawRect:] + 228
12
UIKitCore
-[UIView(CALayerDelegate) drawLayer:inContext:] + 508
13
QuartzCore
CABackingStoreUpdate + 252
14
QuartzCore
___ZN2CA5Layer8display_Ev_block_invoke + 64
15
QuartzCore
-[CALayer _display] + 1636
16
QuartzCore
CA::Layer::layout_and_display_if_needed(CA::Transaction*) + 416
17
QuartzCore
CA::Context::commit_transaction(CA::Transaction*, double, double*) + 464
18
QuartzCore
CA::Transaction::commit() + 648
19
QuartzCore
CA::Transaction::flush_as_runloop_observer(bool) + 88
20
UIKitCore
__UIApplicationFlushCATransaction + 52
21
UIKitCore
__UIUpdateSequenceRun + 84
22
UIKitCore
_schedulerStepScheduledMainSection + 172
23
UIKitCore
_runloopSourceCallback + 92
24
CoreFoundation
_CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION + 28
25
CoreFoundation
___CFRunLoopDoSource0 + 176
26
CoreFoundation
___CFRunLoopDoSources0 + 244
27
CoreFoundation
___CFRunLoopRun + 828
28
CoreFoundation
_CFRunLoopRunSpecific + 608
29
GraphicsServices
_GSEventRunModal + 164
30
UIKitCore
-[UIApplication _run] + 888
31
UIKitCore
_UIApplicationMain + 340
32
UIKitCore
_keypath_get_selector_hoverStyle + 11024
See FB13917278 (App Becomes Unresponsive for iOS/iPadOS 18 Regular Size Class Interactions When Selecting One Particular View in Sidebar).
Dear Apple Support Team,
I am currently developing a control in my app that uses UIDatePicker for time input. To ensure that the time display format is consistently in 24-hour notation regardless of the region, I have set the locale of UIDatePicker to ‘systemLocale’.
However, while this worked as expected up to iPadOS15, displaying the time in 24-hour format, it has switched to a 12-hour format from iPadOS16 onwards. I am wondering if there have been any changes in the behavior of UIDatePicker’s locale between the updates from iPadOS15 to iPadOS16?
Additionally, I would like to know if there are any workarounds to this issue that do not involve modifying the program. In other words, is there a way to revert back to the 24-hour format without changing the code?
Any information you could provide on this issue would be greatly appreciated. Thank you for your assistance.
How to make some label UI render to the front of 3D objects in the development of vision pro
I have a live activity, that works fine when the Lock Screen showing, but as soon as it "sleeps" dims down for always on display, everything in the widget disappears and an Activity Indicator(spinner), displays in its place, but non-animating.