"the compiler is unable to type-check this expression in reasonable time; try breaking up the expression into distinct sub-expressions" ...... it killing me !!!!
SwiftUI
RSS for tagProvide views, controls, and layout structures for declaring your app's user interface using SwiftUI.
Post
Replies
Boosts
Views
Activity
I'm trying to achieve a specific UI design in SwiftUI where the bottom section of my List has a different background color than the top section. For example in the Medications portion of the Health app, the "Your Medications" Section has a different background than the top "Log" Section. How do I achieve this?:
Here some example code. I wonder if I am supposed to use two Lists instead. If I use two Lists though and nest it in a ScrollView, the height of the lists needs to be specified. I am working with dynamic content, though so I don't think that is ideal.
class ProtocolMedication {} // Example model
struct HomeView: View {
@Query private var protocolMedications: [ProtocolMedication]
var body: some View {
NavigationStack {
List {
// Upper sections with default background
Section {
Text("Content 1")
} header: {
Text("Log")
}
// Bottom section that needs different background
Section {
ForEach(protocolMedications) { medication in
Text(medication.name)
}
} header: {
Text("Your Medications")
}
}
.listStyle(.insetGrouped)
}
}
}
Suppose there are two buttons in VStack, the second button is unclickable. I'm running macOS 15.2 with Xcode 16.2.
import SwiftUI
struct ContentView: View {
var body: some View {
ScrollView(.horizontal) {
VStack {
Spacer()
// this button is clickable
Button("foo") {
print("foo")
}
// this button can't be clicked
Button("bar") {
print("bar")
}
}
}
}
}
If I change .horizontal -> .vertical and VStack -> HStack, the second button behave normally.
If I remove ScrollView, everything works fine.
it works fine before macOS 15.2.
Hello, and an early "Merry Christmas" to all,
I'm building a SwiftUI app, and one of my Views is a fullscreen UIViewRepresentable (SpriteView) beneath a SwiftUI interface.
Whenever the user interacts with any SwiftUI element, the UIView registers a hit in touchesBegan(). For example, my UIView has logic for pinching (not implemented via UIGestureRecognizer), so whenever the user holds down a SwiftUI element while touching the UIView, that counts as two touches to the UIView which invokes the pinching logic.
Things I've tried to block SwiftUI from passing the gesture down to the UIView:
Adding opaque elements beneath control elements
Adding gestures to the elements above
Adding gesture masks to the gestures above
Converting eligible elements to Buttons (since those seem immune)
Adding SpriteViews beneath those elements to absorb gestures
So far nothing has worked. As long as the UIView is beneath SwiftUI elements, any interactions with those elements will be registered as a hit.
The obvious solution is to track each SwiftUI element's size and coordinates with respect to the UIView's coordinate space, then use exclusion areas, but this is both a pain and expensive, and I find it hard to believe this is the best fix for such a seemingly basic problem.
I'm probably overlooking something basic, so any suggestions will be greatly appreciated
Hello everyone,
I've been having a bit of trouble with the .symbolRenderingMode(_:) modifier.
When trying to apply it to a single button in a toolbar, it does not work at all. The symbol is always rendered as monochrome.
However, I've realised that with this little hack I can achieve the expected results, but this is not ideal.
.toolbar {
HStack {
Button("", action: {}) // The hack
Button("Button", systemImage: "line.3.horizontal.decrease.circle.fill", action: {})
.symbolRenderingMode(.hierarchical)
.foregroundStyle(.blue)
}
}
I've submitted a bug report (FB16129223) but in the meantime, is this my only solution ?
Side note: the foregroundStyle(_:) modifier is ignored as well.
Hello. I am developing an application using Swift 6 and SwiftUI.
I have custom implemented a BottomSheet that animates from bottom to top, and I attempted to achieve this animation by changing the alignmentGuide like this.
ZStack(alignment: .bottom) {
dimView
.opacity(isVisible ? 1 : 0)
.transaction { transaction in
transaction.animation = .easeInOut(duration: 0.35)
}
bottomSheetView
.alignmentGuide(VerticalAlignment.bottom) { dimension in
// compile error occur because isVisible property is state of MainActor isolated View!
isVisible ? dimension[.bottom] : dimension[.top]
}
}
There were no issues in Swift 5, but now I am encountering compile errors because the computeValue closure of the alignmentGuide is not isolated to the MainActor, preventing me from calling view state values or functions.
So I am curious if there are any plans to isolate this closure to the MainActor. From my observation, this closure is always called on the main thread.
Thank you.
It happens on a brand new SwiftUI Xcode project with nothing in it but the default base code. When I build and run, I get "Error creating the CFMessagePort needed to communicate with PPT." After some Googling, I know it has something to do with Performance Tools. I don't know what's causing it.
I'm running 16.2 on a brand new M4 Mac mini.
I have an issue where a very specific configuration of .overlay, withAnimation, and a bindable state can freeze the app when the state changes.
I've isolated the problematic source code into a sample project can be found here that demonstrates the issue:
https://github.com/katagaki/IcyOverlay
Steps to Reproduce
To reproduce the issue, tap the 'Simulate Content Load' button.
Once the progress bar has completed, a switch is toggled to hide the progress view, which causes the overlay to disappear, and the app to freeze.
Any help and/or advice will be appreciated!
Development Environment
Xcode Version 16.2 (16C5032a), macOS 15.2(24C101)
iOS SDK: 18.2 (22C146), Simulator: 18.2 (22C150)
NavigationTitle does not change when the app language changes. It works well in iOS 17.5 but does not in iOS 18.x
Hi, I am having some troubles creating a "nested" RealityView content using MapKit attachment.
I am building a visionOS app that has horizontal MapKit map as an attachment to RealityView. I want to display 3D pins on that map, therefore I am using native map annotation and inside of these annotations, I create a new RealityView just for the 3D pin. This worked completely fine, unitil I wanted to have those RealityViews interact with each other.
By interaction of those RealityViews I mean that I wanted to group entities from the first "main" RealityViews content with the 3D pins using ModelSortGroupComponent.
Why I want this? I want to make the map circular, that is not a problem. Problem is that when I move the map with 3D pins, these pins have their own RealityView space and are only bounded by volumetric window dimensions. What happes is that these pins float next to the map (shown on attached image). So I came up with this solution: create a custom "toroid" like 3D entity model that occludes the pins that go outside the map region. In order to occlude only the pins, I need to use ModelSortGroupComponent to group the "toroid" entity with 3D pins entities (as described in another forum thread).
To summarize: need the content of the superior RealityView to interact with map attachment annotations RealityView content in order to group them. There might be of course another, better way to achieve my whole goal, so I would naturally appreciate any help or guidance.
Image below showing 3D pins on circular map. Since pins RealityView does no know anything about other RealityViews, it just overlows and hangs in space until is cropped by volumetric window boundary.
Simplified code:
var body: some View {
let modelSortGroup = ModelSortGroup(depthPass: .prePass)
RealityView { content, attachments in
var mainEntity = Entity()
// My other entities here...
if let mapAttachment = attachments.entity(for: "mapAttachment") {
// Edit map properties, position, horizontal layout etc.
mainEntity.addChild(mapAttachment)
}
// Create and add to content mask "toroid" entity mapMaskEntity. Use OcclusionMaterial() material.
mapMaskEntity.components.set(ModelSortGroupComponent(group: modelSortGroup, order: 0))
// For all pins, somehow also set the group
// 3DPinEntity.components.set(ModelSortGroupComponent(group: modelSortGroup, order: 1))
content.add(mainEntity)
} attachments: {
Attachment(id: "mapAttachment") {
Map {
ForEach(mapViewModel.clusters, id: \.id) { cluster in
Annotation("", coordinate: cluster.coordinate) {
MapPin3DView(cluster: cluster)
}
}
}
.clipShape(Circle())
}
}
}
// MapPin3DView is an map annotation view that includes a model of 3D pin and some details like image etc., uses RealityView.
struct MapPin3DView: View {
var body: some View {
RealityView { content in
// 3D pin entities...
}
}
}
Hello!
Is there a way to perform an action before alert (no matter which) appears and sheet (no matter which) opens? Perhaps, system event or something like this.
I have an app that I would like to implement sharing an Image from a Button within a .contextMenu as below. I’d like to share from the button in the same way as a ShareLink would.
I see other resources suggest the use of the UIActivityViewController although I was wondering if there is a SwiftUI approach that would not involve UIKit.
.contextMenu {
Button(action: {
debugPrint("Share")
}) {
Label("Share", systemImage: "square.and.arrow.up")
}
}
I want to get the availableInputs list in widgetextension, but it always returns only the phone's microphone. I have confirmed that I have connected additional Bluetooth devices. Why is this?
If I want to get the information I want, how should I do it?
We've seen an issue when using a LazyVGrid inside a List. The app crashes with:
Thread 1: Fatal error: <UpdateCoalescingCollectionView 0x600000ca0d20> is stuck in a recursive layout loop
When debugging the issue, we were able to narrow down the issue to a minimum reproducible example below:
struct ContentView: View {
let columns = [
GridItem(.adaptive(minimum: 43))
]
var body: some View {
List {
LazyVGrid(columns: columns) {
ForEach(0..<15) { value in
if value == 0 {
Text("a")
} else {
Color.clear
}
}
}
}
}
}
The issue can be reproduced on iPhone 15 Pro Max and iOS 18.x specifically.
In a production app we have a similar layout, but instead of GridItem(.adaptive) we use GridItem(.flexible).
Hi! I'm attempting to run the Quakes Sample App^1 from macOS. I am running breakpoints and confirming the mapCameraKeyframeAnimator is being called:
.mapCameraKeyframeAnimator(trigger: selectedId) { initialCamera in
let start = initialCamera.centerCoordinate
let end = quakes[selectedId]?.location.coordinate ?? start
let travelDistance = start.distance(to: end)
let duration = max(min(travelDistance / 30, 5), 1)
let finalAltitude = travelDistance > 20 ? 3_000_000 : min(initialCamera.distance, 3_000_000)
let middleAltitude = finalAltitude * max(min(travelDistance / 5, 1.5), 1)
KeyframeTrack(\MapCamera.centerCoordinate) {
CubicKeyframe(end, duration: duration)
}
KeyframeTrack(\MapCamera.distance) {
CubicKeyframe(middleAltitude, duration: duration / 2)
CubicKeyframe(finalAltitude, duration: duration / 2)
}
}
But I don't actually see any map animations taking place when that selection changes.
Running the application from iPhone simulator does show the animations.
I am building from Xcode Version 16.2 and macOS 15.2. Are there known issues with this API on macOS?
On a ScrollView+LazyVStack, the addition of .scrollTargetLayout causes many list items to be initialized, instead of the ordinary economical behavior of LazyVStack, where only the necessary items and views are initialized. Even worse, as the stack is scrolled down, all list items are reinitialized for every small scroll.
Without, .scrollTargetLayout, everything works fine.
I've tried every variation of locating modifiers, and different ways of identifying the list items, with no success.
Any ideas? Thanks.
@FetchRequest(
sortDescriptors: [NSSortDescriptor(keyPath: \Post.created, ascending: true)],
animation: .default)
private var posts: FetchedResults<Post>
var body: some View {
ZStack{
ScrollView{
LazyVStack(spacing:0) {
ForEach(posts, id: \.self) { post in
PostView(post: post)
}
.onDelete(perform: deletePosts)
}.scrollTargetLayout() // <---- causes multiple Posts re-instantiations for any small scroll, very slow
}
.scrollPosition(id: $scrolledID)
.scrollTargetBehavior(.paging)
Hello!
I want to programmatically set the editMode in SwiftUI for a view as soon as it appears. However, I have read a lot now but it only works via the EditButton - but not programmatically. I'm using the simulator for this example and Xcode Version 15.4.
struct EditTodos: View {
@State private var editMode = EditMode.inactive
@State var content = ["apple", "banana", "peanut"]
var body: some View {
NavigationStack {
List {
ForEach(content, id: \.self) { item in
Text(item)
}
.onDelete { _ in }
.onMove { _, _ in }
}
.onAppear {
editMode = .active // note: not working, why??
}
.navigationBarItems(
trailing: HStack(spacing: 20) {
EditButton()
}
)
}
}
}
#Preview {
EditTodos()
}
May I inquire about the differences between the two ways of view under the hood in SwiftUI?
class MyViewModel: ObservableObject {
@Published var state: Any
init(state: Any) {
self.state = state
}
}
struct MyView: View {
@StateObject var viewModel: MyViewModel
var body: some View {
// ...
}
}
struct CustomView: View {
let navigationPath: NavigationPath
@StateObject var viewModel: MyViewModel
var body: some View {
Button("Go to My View") {
navigationPath.append(makeMyView())
}
}
}
// Option 1: A viewModel is initialized outside view's initialization
func makeMyView(state: Any) -> some View {
let viewModel = MyViewModel(state: state)
MyView(viewModel: viewModel)
}
// Option 2: A viewModel is initialized inside view's initialization
func makeMyView(state: Any) -> some View {
MyView(viewModel: MyViewModel(state: state))
}
For option 1, the view model will be initialized whenever custom view is re-rendered by changes whereas the view model is only initialized once when the view is re-rendered for option 2.
So what happens here?
This is my code in ContentView:
import SwiftUI
import SceneKit
import PlaygroundSupport
struct ContentView: View {
var body: some View {
VStack {
Text("SceneKit with SwiftUI")
.font(.headline)
.padding()
SceneView(
scene: loadScene(),
options: [.autoenablesDefaultLighting, .allowsCameraControl]
)
.frame(width: 400, height: 400)
.border(Color.gray, width: 1)
}
}
}
func loadScene() -> SCNScene? {
if let fileURL = Bundle.main.url(forResource: "a", withExtension: "dae") {
do {
let scene = try SCNScene(url: fileURL, options: [
SCNSceneSource.LoadingOption.checkConsistency: true
])
print("Scene loaded successfully.")
return scene
} catch {
print("Error loading scene: \(error.localizedDescription)")
}
} else {
print("Error: Unable to locate a.dae in Resources.")
}
return nil
}
a.dae file exists in the Resources section of macOS Playground app. And a.dae can be viewed in Xcode.
Console shows: Error loading scene: The operation couldn’t be completed. (Foundation._GenericObjCError error 0.)
Any input is appreciated.
I'm adding Admob ads to my app, and Admob needs to know the width of the view, so I'm using GeometryReader for that. To prevent GeometryReader from grabbing screen space, I've wrapped the main view in GeometryReader { }. I then use geometry.size.width in my call to the adView.
This all works fine. I have two main screens where I show ads, and they both work, until I rotate the device. Then the app crashes!
If I comment out the GeometryReader code and pass a fixed value to the ad view, I can rotate the device with no fear of a crash.
My question is: Do I have to accept that GeometryReader will crash the app when it's rotated, or is there another, stable way to get view dimensions?