-
Notifications
You must be signed in to change notification settings - Fork 49
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Share knowledge on maintaining SwiftUI frames #40
base: main
Are you sure you want to change the base?
Share knowledge on maintaining SwiftUI frames #40
Conversation
Wow! Your solutions works like a charm!
|
if #available(iOS 16.0, *) { | ||
anchorPoint = mapAnnotation.anchorPoint | ||
} else { | ||
// Fallback on earlier versions |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please, add fallback on earlier versions using centerOffset
if #available(iOS 16.0, *) { | ||
anchorPoint = mapAnnotation.anchorPoint | ||
} else { | ||
// Fallback on earlier versions |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please, add fallback on earlier versions using centerOffset
There are unfortunately a few issues that seem quite foundational to this solution. I would like to keep ViewMapAnnotation as a struct and would like to reduce the dependency between them (i.e. not have any references between them). With this implementation, we would lose both and have less type-safety and a less concise interface. Further, there seem to be a few UIKit "hacks" that might break in future or past OS versions. I will have a look in the next couple of days for a better solution. |
@pauljohanneskraft I get it, I just wanted to share so you could give the right solution more thought. I don't expect this PR to be merged. |
I'm definitely grateful for your and @iakov-kaiumov 's support - I see this as one of the main issues of this library at the moment, but haven't yet found the time to really dive into this. It would further need to work for iOS 13+ until 16 and beyond, which is why I'm hesitant to put possibly breaking code into it. However, I can also understand that it is frustrating that the current implementation is also not working as expected. |
I was just perusing the API and found the thing I had been looking for. I think this will remove the need for the circular reference AND the need for class. https://developer.apple.com/documentation/mapkit/mkmapview/1452512-view |
@pauljohanneskraft I've updated to use I don't really see a way to statically know the type of the annotation view in a way that doesn't require a conditional cast. But this approach eliminates the need for |
@iakov-kaiumov I will be checking on iOS 15 |
@iakov-kaiumov I've updated to use |
I'm facing some weird behaviour with your latest commit. Annotations change their locations when I move the map. Simulator.Screen.Recording.-.iPhone.14.Pro.Max.-.2023-03-13.at.22.08.02.mp4 |
@iakov-kaiumov That looks suspiciously like they're attempting to avoid the safe area. I'm not able to see that behavior on my little test rig though. You could try enabling the backgroundColor on the MKAnnotationView to see if the SwiftUI view contents are not aligned with the annotation view. I'd need a reproduction case to help investigate it. |
@allenhumphreys NavigationView {
ContentView()
.edgesIgnoringSafeArea(.all)
.navigationTitle("Title")
} |
@allenhumphreys |
@iakov-kaiumov i wonder if the safe area disabling thing from #25 would address the problem in navigation view. My primary use case disables safe area, so that's how I've been testing |
@pauljohanneskraft |
Unfortunately no, I have drafted a new MapAnnotation setup which would allow the updating part, but nothing to present yet. It involved not creating the MKAnnotation objects as property of the MapAnnotation, but rather creating and updating it on demand and storing it inside Map.Coordinator as part of another dictionary... This will be quite some work, so it will most definitely take some time to implement - please use the workaround of replacing annotations for now (or adapt the library to your own preference on your own branches ofc) Regarding the layout issue, I'm still confused why these complicated solutions are necessary, since they should not be so complicated, right? I will need to setup a UIKit-only project (and then introduce parts of this library) to check where the layout suddenly introduces these issues, since I cannot imagine that we would need to use dynamic objc features or delayed layouting... Is this a bug of UIHostingController or sth? Unfortunately, I do not have time to investigate so deep into this at the moment, sorry 🙈 If you happen to find a simpler solution or can help with some investigation work, I will be happy to assist though |
@pauljohanneskraft I suspect the SwiftUI frame's frames not moving is an artifact of how MKMapView moves the annotation view's frame around. Again it's a suspicion, but I believe the hosting view relies on a regular update about its parent's frame in its parent's parent's coordinate system. I think MKMapView is possibly bending the usual rules of UIKit frame updates/layouts in a manner that breaks SwiftUI hosting views. Inspecting the view hierarchy of MapKit's My changes are the result of a very very VERY intense investigation into making SwiftUI onTapGesture work correctly in a custom Map implementation. This set of changes does 2 things.
They can really be taken as separate entities. And when boiled down to the minimum, fixing the frame is actually just a little bit of code. It is worth noting, on the frame front. That MKAnnotationView's documentation explicitly says you MUST set the size of your MKAnnotationView or else it'll always be zero. Using constraints against the subview will do that, or setting |
@pauljohanneskraft |
@allenhumphreys |
Will this be merged? :) |
These changes achieve 2 main things:
MKMapAnnotationView
's frame around on the map. This fixes usingonTapGesture
directly on the SwiftUI view that represents the annotationcoordinateRegion
changes, the annotations will be re-calculated. This allows hosting views that have inputs.The result can be something like this:
Simulator.Screen.Recording.-.iPhone.14.Pro.-.2023-03-11.at.11.55.48.mov