I have filed two feedback items for the following issues: FB9184508 and FB9132675.
On my SwiftUI app, two things happen which make the app completely unusable and I believe they are due to a SwiftUI bug:
On iPadOS, if you use the Magic Keyboard and the iPadOS pointer, buttons stop responding to trackpad clicks but work when you use your finger.
On macOS, where my app runs as a Catalyst app, simple buttons in my app completely stop responding to clicks, even though they show hover states and are simple, logic-less buttons. My code is also identical on iPadOS and macOS.
The app is called DetailsPro.
Has this happened to anybody else? Has anyone else filed feedback for this and heard back?
Post
Replies
Boosts
Views
Activity
I’m seeing this issue where a Form / NavigationLink set up seems to stop passing through the data on changes.
Expected behavior: Checkmarks should update when you pick a different food.
Observed behavior: You can see the favorite food changing outside the NavigationLink Destination, but not inside.
This setup mirrors a dynamic application where a ForEach is used to display various NavigationLinks in the Form based on parent data. Weirdly enough, this works if you replace Form with VStack, so I’m curious why this isn’t updating.
I have attached two minimum-setup example projects that replicate this issue where the destination of a NavigationLink is not receiving an update when data is changing. One with Binding, one with simpler passed properties.
You can download both sample projects at this stackoverflow link - https://stackoverflow.com/posts/65246008/edit.
Sample Code #1 w/ Bindings - https://developer.apple.com/forums/content/attachment/21b3be52-a885-467d-bc94-324e8d70fa7b
Sample Code #2 w/o Bindings
//
//	ContentView.swift
//	Form Updating Example
//
//	Created by Sahand Nayebaziz on 12/10/20.
//
import SwiftUI
struct ContentView: View {
		@State var isPresentingMainView = false
		@State var favoriteFood: FoodType = .bagel
		var body: some View {
				VStack {
						Button(action: { isPresentingMainView = true }, label: {
								Text("Present Main View")
						})
				}
				.fullScreenCover(isPresented: $isPresentingMainView) {
						MainView(currentFavoriteFood: favoriteFood, onUpdateFavoriteFood: { favoriteFood = $0 })
				}
		}
}
struct MainView: View {
		let currentFavoriteFood: FoodType
		let onUpdateFavoriteFood: (FoodType) -> Void
		var body: some View {
				NavigationView {
						HStack {
								Spacer()
								Text(currentFavoriteFood.emoji)
										.font(.title)
										.foregroundColor(.secondary)
								Spacer()
								NavigationView {
										Form {
												List {
														ForEach(["SomethingRepresentingShowingFood"], id: \.self) { _ in
																NavigationLink(
																		destination: makeDetail(),
																		label: {
																				Text("Food Randomizer")
																		})
														}
												}
										}
								}
								.navigationViewStyle(StackNavigationViewStyle())
								.frame(maxWidth: 350)
						}
						.navigationTitle("Main")
						.navigationBarTitleDisplayMode(.inline)
				}
				.navigationViewStyle(StackNavigationViewStyle())
		}
		func makeDetail() -> some View {
				Form {
						ForEach(FoodType.allCases) { foodType in
								Button(action: { onUpdateFavoriteFood(foodType) }, label: {
										HStack {
												Text(foodType.emoji)
												Spacer()
												if currentFavoriteFood == foodType {
														Image(systemName: "checkmark")
												}
										}
								})
						}
				}
		}
}
enum FoodType: String, Identifiable, CaseIterable {
		case bagel, pizza, broccoli
		var id: String { rawValue }
		var emoji: String {
				switch self {
				case .bagel: return "🥯"
				case .pizza: return "🍕"
				case .broccoli: return "🥦"
				}
		}
}
struct ContentView_Previews: PreviewProvider {
		static var previews: some View {
				Group {
						ContentView()
						MainView(currentFavoriteFood: .bagel, onUpdateFavoriteFood: { _ in })
						MainView(currentFavoriteFood: .bagel, onUpdateFavoriteFood: { _ in })
								.makeDetail()
				}
		}
}
Hello! Is there a best practice for passing properties down a view hierarchy that is composed as a View that has a UIKit view that then has a View?
The properties easily go from the first View struct to the representable Struct in the update method. Is there a recommended way to, on each update, pass those properties from the UIKit view representable struct to its subview, which is itself a UIHostingView+View?