Xamarin ios map circle overlay click - xamarin

I'm following the maps example https://developer.xamarin.com/samples/xamarin-forms/customrenderers/map/circle/ to create custom renderer to overlay circles. It seems to be working fine for all 3 platforms except I am unable to find any click event for iOS.
I am building a xamarin forms app and able to find out the click event on both Android and UWP but iOS seems to be far fetched.
Is there any way to do it?

iOS doesn't provide the API which detects the click event.
As a alternative workaround, we can add UITapGestureRecognizer on the mapview and judge if the tap point locates inside the circle.
Solution
//xxx
nativeMap.AddOverlay(circleOverlay);
nativeMap.AddGestureRecognizer(new UITapGestureRecognizer(TapHandle));
void TapHandle(UITapGestureRecognizer tap)
{
MKMapView mapView = tap.View as MKMapView;
CGPoint tapPoint = tap.LocationInView(mapView);
CLLocationCoordinate2D tapCoordinate = mapView.ConvertPoint(tapPoint, tap.View);
MKMapPoint point = MKMapPoint.FromCoordinate(tapCoordinate);
foreach(IMKOverlay overlay in mapView.Overlays)
{
MKCircleRenderer render = GetOverlayRenderer(mapView, overlay) as MKCircleRenderer;
CGPoint datPoint = render.PointForMapPoint(point);
render.InvalidatePath();
if (render.Path.ContainsPoint(datPoint,false))
{
break;
}
}
}

Related

Xamarin Forms: Native Embedding Android and iOS Video Player

I've been working on this Xamarin Forms mobile application and I've been loving it but it's a media player application and the native embedding for the platform specific video player doesn't work. After much debugging I was able to get the audio playing but no video would show up. I think this has to do with the views just not being swapped out appropriately. Unfortunately there isn't much material on how to effectively switch from a Xamarin Forms view to a native view (to see the video) through Xamarin Forms. Any help is appreciated thank you !
I was able to get iOS videos working by using the Xamarin Forms messaging service to Appdelegate class and built the AVPlayer class there. Works great.
playVideo.Clicked += (sender, e) =>
MessagingCenter.Send(this, "ShowVideoPlayer", new
ShowVideoPlayerArguments(videoUrl));
Appdelegate.cs
MessagingCenter.Subscribe<VideoDetailPage,
ShowVideoPlayerArguments>(this, "ShowVideoPlayer",
HandleShowVideoPlayerMessage);
//messaging center class
private void HandleShowVideoPlayerMessage(Page page,
ShowVideoPlayerArguments arguments)
{
var presentingViewController = GetMostPresentedViewController();
var url = NSUrl.FromString(arguments.Url);
var avp = new AVPlayer(url);
var avpvc = new AVPlayerViewController();
avpvc.Player = avp;
avp.Play();
presentingViewController.PresentViewController(avpvc, animated: true,
completionHandler: null);
}
private UIViewController GetMostPresentedViewController()
{
var viewController =
UIApplication.SharedApplication.KeyWindow.RootViewController;
while (viewController.PresentedViewController != null){
viewController = viewController.PresentedViewController;
}
return viewController;
}
However.. Getting this to work with Android is a whole different animal since I have to have deal with .axml layouts I believe.. Any help with this would be greatly appreciate.. Thanks so much guys.
So I figured out an implementation using Native Views, an alternative to Custom Renderers. Such a more stream lined process.

Disable ScrollView bounce NativeScript

Looking for a way to disable the ScrollView bounce or overflow that happens when scrolling reaches the top or bottom of the scroll view.
here how to set the settings in android.
Android scrollview remove blue light
Here is a code snippet that might do the trick for you:
if (this.content.ios instanceof UIScrollView) {
this.content.ios.alwaysBounceVertical = false;
}
Of course you need to get an instance of the <ScrollView> component from NativeScript and then the native iOS instance.
I have a small utility library that has this function and some other handy functions baked into it.
https://github.com/TheOriginalJosh/nativescript-swiss-army-knife
import {SwissArmyKnife} from 'nativescript-swiss-army-knife/nativescript-swiss-army-knife';
...
let scrollView = page.getViewById('myScrollView');
SwissArmyKnife.disableScrollBounce(scrollView);
Here is how to do it on iOS and Android.
let scrollView = page.getViewById('myScrollView');
if (app.android) {
scrollView.android.setOverScrollMode(2);
}
else if (app.ios) {
scrollView.ios.bounces = false;
}

Pinch Zoom into UIImageView inside a UITableViewCell

I am creating a tableview where I will have an UIImageViewinside a UITableViewCell that I would like to allow the user to zoom into. I have been able to create this effect inside a UIScrollView but have struggled to get it right for zooming into a single UITableViewCell.
At the bottom I have included the code that has worked for me for the UIScrollView. The challenge starts with what to return for the viewForZoomingInScrollView. If I try to give this method the UIImageView from the cell It throws an errors as it appears the viewForZoomingInScrollView is called before the table is loaded thus it can not find the cell I am referencing. If I pass the entire view itself self.view I can scroll but the entire tableview is zoomed (where I would like to zoom just the UIImageView inside the cell) and when I release the zoom I get an error Terminating app due to uncaught exception 'CALayerInvalidGeometry', reason: 'CALayer bounds contains NaN: [nan nan; 375 667] which is clearly not the correct path to take.
Any help or guidance here would be appreciated.
- (UIView*)viewForZoomingInScrollView:(UIScrollView *)scrollView {
return self.imageView;
}
- (void)scrollViewDidZoom:(UIScrollView *)scrollView {
[self centerScrollViewContents];
}
- (void)centerScrollViewContents {
CGSize boundsSize = zoomTable.bounds.size;
CGRect contentsFrame = self.imageView.frame;
if (contentsFrame.size.width < boundsSize.width) {
contentsFrame.origin.x = (boundsSize.width - contentsFrame.size.width) / 2.0f;
} else {
contentsFrame.origin.x = 0.0f;
}
if (contentsFrame.size.height < boundsSize.height) {
contentsFrame.origin.y = (boundsSize.height - contentsFrame.size.height) / 2.0f;
} else {
contentsFrame.origin.y = 0.0f;
}
self.imageView.frame = contentsFrame;
}
It sounds to me as though you want something like what Facebook or Twitter have, where you tap on an image and it zooms to fit the screen.
What you need to do is to consider that as a navigational step -- i.e. conceptually similar to what happens if you select a row in a standard table view and it pushes a new view controller onto the navigation controller stack, except that you probably want to present modally using a custom transition.
In the simple case, this would mean adding a tap gesture recogniser to the cell's image view; for the full effect you would add a pinch gesture recogniser to make an interactive transition.
I'd recommend watching the following WWDC videos:
2013 Session 218 "Custom Transitions Using View Controllers"
2014 Session 214 "View Controller Advancements in iOS 8"
2014 Session 228 "A Look Inside Presentation Controllers"
From your question What I understand is that you wanted to implement the functionality of Zoom in and Zoom out for ImageView. You first implemented that in a sample where you had a ScrollView Inside a ViewController and then ImageView inside that ScrollView. Things worked for you as expected. But then when you wanted the same functionality inside the TableViewCell, things didn't work for you.
So, I am suggesting you to use a View inside ScrollView as a ZoomView, and that ZoomView should have the ImageView as subview. And return that ZoomView in the method:
- (UIView*)viewForZoomingInScrollView:(UIScrollView *)scrollView { return self.ZoomView; }

QLPreviewController issue in Xamarin iOS 8

I am having an issue with QLPreviewcontroller presentation in iOS 8. When it is pushed, the UINavigationBar gets transparent and the UI of the app gets disturbed (though it is working fine on iOS 7), I am developing in Xamarin.
if (UIDevice.CurrentDevice.CheckSystemVersion (8, 0))
{
DocPreviewViewController docPreivewVC = new DocPreviewViewController (this.Title, downloadedTime, fullFilePath); //DocPreviewViewController is subclass of UIViewController
this.NavigationController.PushViewController (docPreivewVC, true);
}
Here is the Output in iOS 8:
And if I try to Present it by wrapping into a UINavigationContorller , the document gets hide under the QLPreviewControllers toolbar and user has to tap the screen to hide the navigation bar and see the upper portion of document. Is there a way to hide this tool and show only my own UINavigationBar? Is this a known behaviour that the QLPreviewController’s navigation bar always overlaps the document and user has to tap it to reveal the full document?
Here is the code that I have tried:
if (UIDevice.CurrentDevice.CheckSystemVersion (8, 0))
{
DocPreviewViewController docPreivewVC = new DocPreviewViewController (this.Title, downloadedTime, fullFilePath);
UINavigationController nav = new UINavigationController (docPreivewVC);
nav.HidesBarsOnTap = false;
nav.HidesBarsOnSwipe = false;
this.PresentViewController (nav, true, null);
}
iOS 8: Screen shot when used
Kindly give me suggestion how can I achieve the appearance of document as of iOS 7 i.e: Hiding the top toolbar of QLPreviewController and showing only NavigationController's navigation bar like this:
Thanks

Capture touch events in Xamarin.Forms for Android

I am creating an app that allows the user to drag and drop to put one image on top of another using Xamarin.Forms.
On iOS I managed to hack together a workable gesture recognizer renderer by creating a custom ContentView and a custom renderer for it, which then attaches native gesture recognizers to itself based on the GestureRecognizers elements. To do that I disable the default EventTracker and implement my own, with overridden GetNativeRecognizer method
in the custom renderer:
public InteractiveContentViewRenderer () : base ()
{
AutoTrack = false;
events = new InteractiveEventTracker (this);
}
in the custom event tracker:
public InteractiveEventTracker (IVisualElementRenderer renderer) : base (renderer)
{
this.Renderer = renderer;
}
protected override MonoTouch.UIKit.UIGestureRecognizer GetNativeRecognizer (Xamarin.Forms.IGestureRecognizer recognizer)
{
var gestureRecognizer = base.GetNativeRecognizer (recognizer);
if (gestureRecognizer == null) {
// here I find my own native recognizer and return it
}
}
On Android, however, so far I haven't figured out how to achieve the same thing. There's no EventTracker in Android, I think I'll have to implement some Android View for this to work but I haven't figured it out so far.
Has anyone managed to hack together touch events in Xamarin.Forms for Android? I'd like to know at least the basic structure of the hack?
Read this: http://blog.twintechs.com/cross-platform-compositional-gesture-advanced-xamarin-forms-techniques-for-flexible-and-performant-cross-platform-apps-part-4
There's a lot about custom gestures in Xamarin.Forms
The source is here: https://github.com/twintechs/TwinTechsFormsLib/tree/master/TwinTechsForms/TwinTechsForms.Droid/TwinTechs/Gestures

Resources