It seems the bug is related to updating the source of the foreach while scrolling.
The only workaround I have found so far is to pre-populate all of the possible pages before hand. But for an endless scroller that does not make much sense.
Post
Replies
Boosts
Views
Activity
I can't believe Xcode 15.3 shipped in this state.
This is probably the buggiest Xcode release yet.
Looks like the reason this happens is because the swift-format team created a COMMAND plugin. Instead of a BUILD plugin.
If you right click on your package.swift file you should see an option in Xcode to run swift-format.
I really want to use the official tooling with my projects. But time after time, it just seems like apple does not care about swift tooling.
swift-format just seems to be a pain to work with. I can't even get it working with build phases. My script hits the line of code to trigger swift-format, but then nothing happens.
Going to switch to SwiftLint
This isn't a built in feature, but I created an environment key called isSelected.
The Environment is how most of the built in view modifiers work under the hood.
struct SelectedEnvironmentKey: EnvironmentKey {
static var defaultValue: Bool = false
}
extension EnvironmentKeys {
var isSelected: Bool {
get { self[SelectedEnvironmentKey.self] }
set { self[SelectedEnvironmentKey.self] = newValue }
}
}
then in the ForEach you can do:
ForEach { myModel in
RowView(model: myModel)
.envrionment(\.isSelected, selection.contains(model))
}
Then in your RowView
struct RowView: View {
@Environment(\.isSelected) private var isSelected
var body: some View {
// My views
.background {
if isSelected {
return Color.blue
}
}
}
}
3:18 PM EST, seems to be fixed for me (the developer portal link), App Store still broken.
XcodesApp and Xcodes CLI still seems to be broken, but I think thats an issue on their end.
Not sure if this would work.
But you could try something like this:
struct LoadingPreferenceKey: PreferenceKey {
var defaultValue: Bool = false
static func reduce(value: inout Self.Value, nextValue: () -> Self.Value) {
value = nextValue()
}
}
struct RootView: View {
@State var loading: Bool = false
var body: some View {
ContentView()
.fullScreenCover(isPresented: $loading) {
MyLoadingView()
}
.onPreferenceChange(LoadingPreferenceKey.self) { isLoading in
loading = true
}
}
}
struct ContentView: View {
@State private var showingSheet = false
var body: some View {
Button("Sheet Open") { self.showingSheet.toggle() }
.sheet(isPresented: $showingSheet) {
SheetView()
}
}
}
struct SheetView: View {
@State var isLoading = false
var body: some View {
ZStack{
VStack{
Text("SheetView")
Button("Submit Data"){
isLoading = true
// Submitting now......
isLoading = false
}
}
if isLoading {
ZStack{
Color.white.opacity(0.5)
.ignoresSafeArea()
.frame(width: geometry.size.width, height: geometry.size.height)
ProgressView()
}
}
}
.preference(LoadingPreferenceKey.self, isLoading)
}
}
I found a somewhat hacky workaround for this.
You can "pre-render" the navigation bar customization so that it does not appear to pop in.
This is not ideal though. Hopefully someone at apple fixes it. As it pretty much makes programmatic navigation in a mixed codebase impossible.
let hostingController = UIHostingController(rootView: MyViewWithASearchBar())
hostingController.title = "My search page title"
// pre-render the search bar
let searchController = UISearchController()
if #available(iOS 16.0, *) {
hostingController.navigationItem.preferredSearchBarPlacement = .stacked
}
hostingController.navigationItem.searchController = searchController
hostingController.navigationItem.hidesSearchBarWhenScrolling = false
navigationController.pushViewController(hostingController, animated: true)
This is super frustrating.
Happens in iOS 17 beta as well.
simultaneousGesture is supposed to solve this issue.
Made a radar for it: FB12683243
Can confirm this is happening to me as well on Xcode 14.3
is there a more dynamic way of doing this? adding a new extension on user defaults every time you have a new key isn't very scalable.
I can confirm this is still the behaviour on iOS 16.
Its a shame because popover bubbles are very common on iOS for providing users with tutorials on how to use the app.
This should be fixed.
If you wanted to show a sheet instead of a popover on iPhone, you could easily just create a view modifier that does the existing behaviour.
This is because your observable object is being used by both a view that is hosting a navigation view, and one of the children being presented by a navigation view.
So when the child updates the observable object, it causes the parent to reload. Which in turn causes its navigation stack to be drawn from scratch as well.
the solution is to decouple the parent from the observable object. So it’s not reloading each time it changes.
A technique I use is to wrap an observable object inside another. What this does it it allows me to inject them via @EnvironmentObject, without causing the views to reload unnecessarily.
class Dependency<T: ObservableObject>: ObservableObject {
let observable: T
init(observable: T) {
self.observable = observable
}
}
I seem to have solved the issue.
Purged Xcode from my machine again. Including all caches.
Deleted the contents of the /Library/Developer folder
restarted my machine
installed command line tools with Xcode-select --install
redownloaded Xcode
I think the PrivateFrameworks folder inside of /Library/Developer/ was the culprit. Its last modified time was when I installed Xcode 14 beta, not the last time I reinstalled Xcode 13.4.1
I imagine some of the stuff the simulator runtime relies on was corrupted.
I figured out what was wrong with it:
this was what I was doing:
for await _ in NotificationCenter.default.notifications(named: UIDevice.orientationDidChangeNotification, object: self) {
print("orientation changed") // This would never fire
}
I changed it to:
for await _ in NotificationCenter.default.notifications(named: UIDevice.orientationDidChangeNotification) {
print("orientation changed") // This works
}
I guess I misunderstood what that object param was used for.
I honestly have not been able to get this to work either. It would be nice to see a demo of it in action.