Provide views, controls, and layout structures for declaring your app's user interface using SwiftUI.

SwiftUI Documentation

Post

Replies

Boosts

Views

Activity

#Preview a Widget placeholder?
While I am able to use #Preview to preview a Widget, it seems to be not possible to easily preview a Widget placeholder. With a "classic" preview I can use .redacted(reason: .placeholder), but this has limitation e.g. it will ignore .contentMarginsDisabled() struct MyWidget_Previews: PreviewProvider { static var previews: some View { Group { MyWidgetView(entry: SimpleEntry(date: .now, emoji: "😀")) MyWidgetView(entry: SimpleEntry(date: .now, emoji: "😀")) .redacted(reason: .placeholder) } .previewContext(WidgetPreviewContext(family: .systemMedium)) .containerBackground(.white, for: .widget) } } If I use #Preview, the .redacted modifier won't work, and I seem to have to put it in the MyWidget implementation. #Preview(as: .systemMedium) { MyWidget() } timeline: { SimpleEntry(date: .now, emoji: "😀") SimpleEntry(date: .now, emoji: "🤩") } Am I missing something?
1
0
146
1w
SwiftUI Popover clips in iOS18
When you try to present medium height popover from the bottom of iPhone view then popover is clipped in iOS18 but works in old devices Sample code Button("Show Popover") { showPopover.toggle() } .popover( isPresented: $showPopover, arrowDirection: arrowDirection ) { conent } Result
4
0
555
Jun ’24
.redacted(reason:) modifier ignores .minimumScaleFactor?
While working with the Emoji Rangers Sample Code, I noticed that .redacted(reason:) seems to ignore the minimumScaleFactor() modifier - I have reproduced this behaviour with Xcode 16 and Xcode 16.1 beta 2 on iOS and on the Mac: struct ContentView: View { @State private var isRedacted: Bool = false var body: some View { VStack { Image(systemName: "globe") .imageScale(.large) .foregroundStyle(.tint) Text("Hello, world!") .font(.largeTitle) Toggle("Redacted", isOn: $isRedacted) } .padding() .minimumScaleFactor(0.1) .redacted(reason: isRedacted ? .placeholder : .invalidated) } } As long as the minimumScaleFactor does not kick in, redacted seems to work as expected: But then it does not: I tried changing the order of both modifiers with no effect. Wonder if this is expected and there is a way to make it work so it preserves the scaled down layout or a bug? Filed just in case: FB15270541 (.redacted(reason:) modifier ignores .minimumScaleFactor)
0
0
96
1w
Auxiliary window control in Mac SwiftUI & SwiftData app
I've got a Mac Document App using SwiftUI and SwiftData. All is working well with the models editing, etc. There's a feature I need to implement, and can't seem to make it work. From the main window of the app, I need to be able to launch an auxilliary window containing a view-only representation of the model being edited. The required workflow is something like this: Open a document (SwiftData) Select a sub-model of the document Launch the aux window to display the view of the model data (must be in a separate window, because it will be on a different physical display) Continue making edits to the sub-model, as they are reflected in the other window So, below is the closest I've been able to come, and it's still not working at all. What happens with this code: Click on the "Present" button, the encounter-presentation Window opens, but never loads the data model or the view. It's just an empty window. This is the spot in the main view where the auxiliary window will be launched: @State var presenting: Presentation? = nil var presentingThisEncounter: Bool { presenting?.encounter.id == encounter.id } @Environment(\.openWindow) var openWindow ... if presentingThisEncounter { Button(action: { presenting = nil }) { Label("Stop", systemImage: "stop.fill") .padding(.horizontal, 4) } .preference(key: PresentationPreferenceKey.self, value: presenting) } else { Button(action: { presenting = Presentation(encounter: encounter, display: activeDisplay) openWindow(id: "encounter-presentation") }) { Label("Present", systemImage: "play.fill") .padding(.horizontal, 4) } .preference(key: PresentationPreferenceKey.self, value: nil) } Presentation is declared as: class Presentation: Observable, Equatable { Here's the contents of the App, where the DocumentGroup & model is instantiated, and the aux window is managed: @State var presentation: Presentation? var body: some Scene { DocumentGroup(editing: .encounterList, migrationPlan: EncounterListMigrationPlan.self) { ContentView() .onPreferenceChange(PresentationPreferenceKey.self) { self.presentation = $0 } } Window("Presentation", id: "encounter-presentation") { VStack { if let presentation = presentation { PresentingView(presentation: presentation) } } } } And the definition of PresentationPreferenceKey: struct PresentationPreferenceKey: PreferenceKey { static var defaultValue: Presentation? static func reduce(value: inout Presentation?, nextValue: () -> Presentation?) { value = nextValue() } }
1
0
115
1w
SwiftUI Form (Grouped) with Table
Hi everyone, I’m having an issue with a SwiftUI Table inside a Form in a macOS app. When the Form style is set to .grouped, the Table does not resize to the full width of the Form or Sheet. However, when I switch to a .plain style, it resizes correctly. Here’s a simplified version of my code: Section(header: Text("Header")) { Table(data) { TableColumn("Column 1", value: \.col1) TableColumn("Column 2", value: \.col2) // Add more columns as needed } .frame(height: 100) } } .formStyle(.grouped) // Issue occurs only with this style Has anyone else experienced this? Any workarounds or suggestions would be greatly appreciated! Thanks!
0
0
159
1w
Issues with List selection in Sequoia (SwiftUI)
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?
3
0
103
1w
Scale contextMenu preview size to containing content
Hi! I have a multi-line string I'd like to display as text in a long-press preview (using .contextMenu). However, text after 3rd or 4th linebreak (\n) gets clipped. The intended effect is to have the minimum preview size that can fit all of the text. Tried .frame(maxWidth: .infinity, maxHeight: .infinity) on Text() but it didn't have any effect. The only modifier that somewhat works is .containerRelativeFrame([.horizontal, .vertical]) but this gives the maximum preview size, instead of minimum. Any suggestions? TIA. struct RedditView: View { @State private var text = "AAAAAAAAAAAAAAAAAAAAAA?\n\nBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\nCCCCCCCCCCCCCCCCCCCCCCCCCC" var body: some View { Text("Long press this") .frame(width: 300, height: 100) .contentShape(.rect) .border(Color.blue) .contextMenu(menuItems: { Button { // do something } label: { Label { Text("Edit") } icon: { Image(systemName: "pencil") } } }, preview: { Text(text) // .frame(maxWidth: .infinity, maxHeight: .infinity) .multilineTextAlignment(.center) .padding() //.containerRelativeFrame([.horizontal, .vertical]) } ) } }
0
0
115
1w
Glitchy page transitions with TabView on watchOS
We're trying to implement transitions between TabView pages similar to what the Fitness app does on watchOS. As the user swipes or uses the Digital Crown to move between pages, the large rings gauge in the center transitions smoothly to a toolbar item. The code to implement this transition is described in two places in Apple's documentation: https://developer.apple.com/documentation/watchos-apps/creating-an-intuitive-and-effective-ui-in-watchos-10 (See the section “Provide continuity with persistent elements”) The WWDC23 session "Design and build apps for watchOS 10", around 9:30 However, copying the code from Apple's documentation doesn't give animation as reliable as what we're seeing in the Fitness app. Any slight reversal of motion causes the transition animation to jump back to the starting state. Has anyone else figured out how to replicate what the Fitness app is doing on watchOS? I've included our View implementation below. Debug prints show what's going wrong: the page variable decrements immediately the user moves backward by any amount. But somehow, the Fitness app gets around this problem. How? struct ContentView: View { @Namespace var namespace @State var page = 0 var body: some View { NavigationStack { TabView(selection: $page) { globeView .containerBackground(Color.blue.gradient, for: .tabView) .navigationTitle("One") .matchedGeometryEffect( id: "globe", in: namespace, properties: .frame, isSource: page == 0) .tag(0) Text("Page two") .containerBackground(Color.green.gradient, for: .tabView) .navigationTitle("Two") .tag(1) } .tabViewStyle(.verticalPage) .toolbar { ToolbarItem(placement: .topBarLeading) { globeView .matchedGeometryEffect( id: "globe", in: namespace, properties: .frame, isSource: page == 1) } } } } @ViewBuilder var globeView: some View { Image(systemName: "globe") .resizable() .scaledToFit() } } Thanks for any help! —Chris
0
0
118
1w
SwiftUI: AlignmentGuide in Overlay not working when in if block
Scenario A SwiftUI view has an overlay with alignment: .top, the content uses .alignmentGuide(.top) {} to adjust the placement. Issue When the content of the overlay is in an if-block, the alignment guide is not adjusted. Example code The example shows 2 views. Not working example, where the content is an if-block. Working example, where the content is not in an if-block Screenshot: https://github.com/simonnickel/FB15248296-SwiftUIAlignmentGuideInOverlayConditional/blob/main/screenshot.png Tested on - Xcode Version 16.0 RC (16A242) on iOS 18.0 Code // Not working .overlay(alignment: .top) { if true { // This line causes .alignmentGuide() to fail Text("Test") .alignmentGuide(.top, computeValue: { dimension in dimension[.bottom] }) } } // Working .overlay(alignment: .top) { Text("Test") .alignmentGuide(.top, computeValue: { dimension in dimension[.bottom] }) } Also created a Feedback: FB15248296 Example Project is here: https://github.com/simonnickel/FB15248296-SwiftUIAlignmentGuideInOverlayConditional/tree/main
0
0
78
1w
SwiftUI Table multiple section bug in iPadOS 18 and mac Catalyst
Hi all, Before updating to iPadOS 18, the Table component in SwiftUI worked as expected, allowing multiple selections using the Shift key and mouse clicks. However, after the update, this functionality no longer works on iPadOS 18 and macOS 15 (running with Catalyst). Here’s a simplified version of the code: @State var selections: Set<String> = [] var body: some View { Table(devices, selection: $selections) { // ... } } Is there any workaround for this issue, or has anyone else encountered the same problem? Thanks!
2
0
116
1w
iOS 18 SwiftUI sheet resizing from page to form presentation sizing
I'm presenting a UIKit view controller from SwiftUI in a sheet using UIViewControllerRepresentable. The size of the sheet is being set to PagePresentationSizing using the new iOS 18 presentationSizing method. When Split View is used and the size class changes from regular to compact, the sheet resizes as expected to fit in the smaller window. When the app returns to full screen and the size class changes back to regular, the sheet is now displayed using FormPresentationSizing instead of PagePresentationSizing. This all worked as expected in iOS 17 with the view controller modalPresentationStyle being specified in the UIViewControllerRepresentable implementation, but the behaviour has now changed with iOS 18. How do I preserve the desired presentation sizing of the sheet? Thanks for any help.
2
0
272
1w
SwiftUI Buttons and onMoveCommand Missing Presses
In tvOS 18 the onMoveCommand is missing the first press after a view is loaded and every time the direction is changed. It also misses the first press on a button after a focus change. This appears to only impact the newer silver remote and not the older black remote or IR remotes. With the code bellow press any direction 3 times and it will only log twice. struct ButtonTest: View { var body: some View { VStack { Button { debugPrint("button 1") } label: { Text("Button 1") } Button { debugPrint("button 2") } label: { Text("Button 2") } Button { debugPrint("button 3") } label: { Text("Button 3") } } .onMoveCommand(perform: { direction in debugPrint("move \(direction)") }) .padding() } }
4
1
160
1w
SwiftUI StateObject crash: “failed to demangle witness for associated type 'Property’”
Hello, we have weird crash in our app that mostly seems to happen right after launch. It is quite rare and so far I haven’t been able to reproduce it (the info below comes from Crashlytics). The main error message I have is this: failed to demangle witness for associated type 'Property' in conformance 'SwiftUI.StateObject<AppBlock.QuickBlockActivityViewModel>.(unknown context at $18f34e5b8).Box: DynamicPropertyBox' from mangled name ' � ��yxG' - subject type x does not conform to protocol ObservableObject And here is the stack trace: Crashed: com.apple.main-thread 0 libsystem_kernel.dylib 0x7200 __pthread_kill + 8 1 libsystem_pthread.dylib 0x71ac pthread_kill + 268 2 libsystem_c.dylib 0x20ca0 abort + 180 3 libswiftCore.dylib 0x3d7304 swift::fatalError(unsigned int, char const*, ...) + 134 4 libswiftCore.dylib 0x3d7324 swift::warningv(unsigned int, char const*, char*) + 30 5 libswiftCore.dylib 0x3ee678 swift_getAssociatedConformanceWitnessSlowImpl(swift::TargetWitnessTable<swift::InProcess>*, swift::TargetMetadata<swift::InProcess> const*, swift::TargetMetadata<swift::InProcess> const*, swift::TargetProtocolRequirement<swift::InProcess> const*, swift::TargetProtocolRequirement<swift::InProcess> const*) + 2078 6 libswiftCore.dylib 0x3ecb9c swift_getAssociatedTypeWitness + 236 7 SwiftUI 0x5b838 OUTLINED_FUNCTION_49 + 640 8 SwiftUI 0xa8d68 OUTLINED_FUNCTION_513 + 16260 9 SwiftUI 0x58244 OUTLINED_FUNCTION_177 + 10892 10 SwiftUI 0x95524 OUTLINED_FUNCTION_1160 + 6632 We are using the view model (QuickBlockActivityViewModel) in a SwiftUI view that is part of collection view using the new UIHostingConfiguration from iOS 16. Our view model is a subclass of view model for older iOS versions that conforms to ObservableObject and is marked as @MainActor. And the view model is used like this: @StateObject private var viewModel = QuickBlockActivityViewModel() Internally the view model uses Combine to monitor a couple of states from other parts of the app to modify its properties.
5
2
1.8k
Jan ’23
Live Activity activityBackgroundTint not using dark mode colour variant
I have defined a colour in the asset catalog of my widget extension. I am using this widget extension for my live activity. This colour has both an ‘Any’ and ‘Dark’ appearance. I am using this colour in the activityBackgroundTint modifier for my main live activity view (the ActivityPreviewViewKind is content, visible on the Lock Screen). In light mode, this works as expected, but in dark mode, the background colour is still the light mode variant. The content within the view changes according to whether the system is in light or dark mode, but the background does not. I want to avoid using just the background modifier instead of activityBackgroundTint, as this does not colour the ‘Allow Live Activities from …’ and ‘Clear’ sections, which is undesirable. I have also tried reading colorScheme from the environment and choosing the light or dark mode colour variant accordingly, but this workaround also doesn’t completely work. If you keep changing from light and dark mode (via the Settings app, not the control centre, for whatever reason), the background colour actually becomes the opposite of the expected value in this case. Is there a workaround that can help me achieve what I want, or am I simply doing something wrong? I have filed a bug report under FB15148099
1
1
126
1w