Did not get the Map Scroll End event in SwiftUI - ios

We are using the Map functionality with annotations.
Functionality:- We have 2000 records in the array but we need to filter 150 records according to the region changed in the Map in SwiftUI. But there is no scroll end event of the Map in SwiftUI.
We used the below code
Map(coordinateRegion: self.$viewModel.region, interactionModes: [.all], annotationItems: self.viewModel.mapLocations), annotationContent: { pin in
}
We got the latest updated region in .onChange(of: viewModel.region) }. But we did not get the map scroll end event. We put the code in onChange(of) but it's lagging while scrolling. So, It's not worked for us.
Also. We tried Drag-Gesture but won't worked.
.gesture(DragGesture()
.onEnded { value in
//Did not getting this event while map scroll end
})

SwiftUI does not usually work as expected when trying to override gestures for built-in views especially with Map
Combine with .debounce is usually a better solution when it comes to filtering based on rapid changing #Published like a region

Related

How to add compass or rotation to MapKit Map with SwiftUI

I need to add Compass or rotation with Map. This is my code. I am using Custom marker. I know we can add compass with MKMapView. But I have added many features to the Map using Map class like custom View Markers, longPress pin drop etc. Therefore, moving to MKMapView would be like redoing everything from scratch again.
Map(coordinateRegion: $mapRegion , annotationItems: viewModel.locations) { location in
MapAnnotation(coordinate: location.coordinate) {
MarkerView(location: location)
}
}
Anybody can tell me how I can do compass rotation with Map.
Thanks
You may be able to set these properties on the underlying view via the Introspect framework. It does not handle Map() out of the box, so you would have to follow the section on implementing your own selector. As the project's Read Me states, there are some caveats:
Please note that this introspection method might break in future SwiftUI releases. Future implementations might not use the same hierarchy, or might not use UIKit elements that are being looked for. Though the library is unlikely to crash, the .introspect() method will not be called in those cases.
I have also found that you need to really be careful and heavily test which property you set (or update) when and where.

Get frame/dimensions from SwiftUI view(s)

Let's assume, to present a specific piece of information I have two different kinds of custom SwiftUI views. For the sake of an example my data is two Strings and the options to display them is either in a
HStack { Text() Spacer() Text() }
or
VStack {
Text()
Text()
}
style. In order to select the best fitting one, I would need to render them and make a choice based on resulting dimensions. For instance, if one of the text views in the first style would approach 50% of the window size, I would rather go with the second style.
How would I go about this without the user seeing the temporary views?
I know about GeometryReader, but I don't know how I could render my "candidate views" off screen, determine sizes and then make a selection for my actual view hierarchy.
Any hints?
I don't know how to work properly with SwiftUI. However, the following is an approach for what you want using UIKit and Labels for text:
let max_width = UIScreen.main.bounds.width/2
if label.intrinsicContentSize.width > max_width{
//The text would occupy more than 50% of the screen in width
}else{
//The text won't occupy more than 50% of the screen in width
}
You would have to run the previous function on each Label and there you can decide.
I know this is not a complete answer because you are working with SwiftUI, but someone may know how to apply the previous code on there.

Direct interaction (when VoiceOver is active) inside "allowsDirectInteraction" marked View does not work

Edit: Just noticed, that sometimes, it works, and sometimes not. And I do not know why.
I am making an App made mostly for blind, VoiceOver will probably be active. In one view I need to make my interactions and gestures myself. In there I am trying to make a zone that is directly interactable, so that the functionallity behind it works like there is no Voiceover active, even when it is. But when I do this, instead of printing text on double tap, VoiceOver always tells: "Zone direct interaction", or something similar (The testdevice is not set to english).
Does anyone has an idea what the problem could be?
This is my View:
struct MyView: View {
var body: some View {
TestView()
.accessibilityAddTraits(.allowsDirectInteraction)
}
}
And that is the TestView:
struct TestView: View {
var body: some View {
Rectangle()
.onTapGesture(count: 2) { print("A View was tapped") }
.onAppear { print("A View was created") }
}
}
When having a view that uses up all the space it cannot be made directly interactable as default as it seems. The user needs to do this himself using the rotor or the settings:
Settings App/Accessibility/VoiceOver/Rotor Actions/Direct Touch Apps/
When the App is checked in that setting the view marked with the trait .allowDirectInteraction does work as if VoiceOver is not active, though this should only be used for elements that are accessible on their own, and not as easy way to avoid making the app accessible for those parts!

SwiftUI LazyVGrid animating change of "page"

I’m trying to treat an entire LazyVGrid as pages, and animate when switching forward or back. A simple slide animation would be fine.
I currently have something along the lines of
LazyVGrid(
columns: [array of column info],
alignment: .center,
spacing: 4
) {
ForEach(cells) { cell in
CellView(cell: cell)
}
}
I have pages of cells that get set on the state when you hit the fwd or back buttons, and they are immediately re-rendered. However, it would be cool to set a forward/back slide when the buttons are hit. I haven’t been able to figure this out easily with transition and animation.
If there’s an entirely different library doing this, I’d be open to trying it.
Thanks so much!

Position update in SwiftUI with MKMapKit

I'm using for a way to update an annotation programmatically. I'm playing with SwiftUI and UIViewRepresentable. The map is shown. It is also not a problem to display an annotation on the map.
What I need now is this: I'm having a location provider, which delivers CLLocation2D coordinates. I would like to display the changing position on a map, but can't figure out how.
The location update is provided via an ObservableObject. That works. If I display the updates in Text element, I can see them:
#ObservedObject var pushedPoseClient = PushedPosesClient()
...
Text(String(format: "%.10f %.10f", self.pushedPoseClient.position.latitude ?? 0, self.pushedPoseClient.position.longitude ?? 0))
The same mechanism doesn't work for a map. I thought I could see updateUIView calls with every position update, but there are no.
How can an ObservedObject, which changes its coordinates, be displayed on a map?
The key is to have a CLLocation2D as observed object. Then it works.

Resources