2017-04-17 96 views
0

我有一個xamarin表單圖像,當用戶點擊圖像時,我想獲取用戶點擊的x,y座標。不是視圖本身的x,y座標,而是圖像中的座標。我在下面的Android上工作。 iOS自定義渲染器會是什麼樣子?iOS上的自定義圖像渲染器以獲取點擊位置的x,y座標

創建觸摸事件接口:

public interface IFloorplanImageController 
{ 
    void SendTouched(); 
} 

創建圖像的自定義控制:

public class FloorplanImage : Image, IFloorplanImageController 
{ 
    public event EventHandler Touched; 

public void SendTouched() 
{ 
    Touched?.Invoke(this, EventArgs.Empty); 
} 

public Tuple<float, float> TouchedCoordinate 
{ 
    get { return (Tuple<float, float>)GetValue(TouchedCoordinateProperty); } 
    set { SetValue(TouchedCoordinateProperty, value); } 
} 

public static readonly BindableProperty TouchedCoordinateProperty = 
    BindableProperty.Create(
     propertyName: "TouchedCoordinate", 
     returnType: typeof(Tuple<float, float>), 
     declaringType: typeof(FloorplanImage), 
     defaultValue: new Tuple<float, float>(0, 0), 
     propertyChanged: OnPropertyChanged); 

public static void OnPropertyChanged(BindableObject bindable, object oldValue, object newValue) 
    { 
    } 
} 

實現自定義渲染:

[assembly: ExportRenderer(typeof(FloorplanImage), typeof(FloorplanImageRenderer))] 

namespace EmployeeApp.Droid.Platform 
{ 
public class FloorplanImageRenderer : ImageRenderer 
{ 
    protected override void OnElementChanged(ElementChangedEventArgs<Image> e) 
    { 
     base.OnElementChanged(e); 

     if (e.NewElement != null) 
     { 
      if (Control != null) 
      { 
       Control.Clickable = true; 
       Control.SetOnTouchListener(ImageTouchListener.Instance.Value); 
       Control.SetTag(Control.Id, new JavaObjectWrapper<FloorplanImage> { Obj = Element as FloorplanImage }); 
      } 
     } 
    } 

    protected override void Dispose(bool disposing) 
    { 
     if (disposing) 
     { 
      if (Control != null) 
      { 
       Control.SetOnTouchListener(null); 
      } 
     } 

     base.Dispose(disposing); 
    } 

    private class ImageTouchListener : Java.Lang.Object, Android.Views.View.IOnTouchListener 
    { 
     public static readonly Lazy<ImageTouchListener> Instance = new Lazy<ImageTouchListener>(
      () => new ImageTouchListener()); 

     public bool OnTouch(Android.Views.View v, MotionEvent e) 
     { 
      var obj = v.GetTag(v.Id) as JavaObjectWrapper<FloorplanImage>; 
      var element = obj.Obj; 
      var controller = element as IFloorplanImageController; 
      if (e.Action == Android.Views.MotionEventActions.Down) 
      { 
       var x = e.GetX(); 
       var y = e.GetY(); 
       element.TouchedCoordinate = new Tuple<float, float>(x, y); 
       controller?.SendTouched(); 
      } 
      else if (e.Action == Android.Views.MotionEventActions.Up) 
      { 
      } 
      return false; 
     } 
    } 
} 

public class JavaObjectWrapper<T> : Java.Lang.Object 
{ 
    public T Obj { get; set; } 
} 
} 

使用這種控制是這樣的:

<local:FloorplanImage HeightRequest="300" x:Name="image" WidthRequest="300" 
        Aspect="AspectFit" Touched="image_Touched" /> 

後面的代碼:

private void image_Touched(object sender, EventArgs e) 
{ 
    var cor = image.TouchedCoordinate; 
} 
+0

在iOS上出了什麼問題? –

+0

我不知道如何實現自定義渲染器 – stepheaw

+1

但我看到你已經有了代碼,對於Android它正在工作,對不對?那麼是什麼阻止你在iOS上實現它? –

回答

0

我在GitHub上所做的正是這一發現這個Customer success example

[assembly: ExportRenderer(typeof(CustomImage), typeof(CustomImageRenderer))] 
namespace FormsImageTapGesture.iOS 
{ 
    public class CustomImageRenderer : ImageRenderer 
    { 
     #region properties & fields 
     // --------------------------------------------------------------------------- 
     // 
     // PROPERTIES & FIELDS 
     // 
     // --------------------------------------------------------------------------- 
     private UIImageView nativeElement; 
     private CustomImage formsElement; 
     #endregion 

     #region methods 
     // --------------------------------------------------------------------------- 
     // 
     // METHODS 
     // 
     // --------------------------------------------------------------------------- 

     // 
     // Set up the custom renderer. In this case, that means set up the gesture 
     // recognizer. 
     // 
     protected override void OnElementChanged(ElementChangedEventArgs<Image> e) { 
      base.OnElementChanged (e); 
      if (e.NewElement != null) { 
       // Grab the Xamarin.Forms control (not native) 
       formsElement = e.NewElement as CustomImage; 
       // Grab the native representation of the Xamarin.Forms control 
       nativeElement = Control as UIImageView; 
       // Set up a tap gesture recognizer on the native control 
       nativeElement.UserInteractionEnabled = true; 
       UITapGestureRecognizer tgr = new UITapGestureRecognizer (TapHandler); 
       nativeElement.AddGestureRecognizer (tgr); 
      } 
     } 

     // 
     // Respond to taps. 
     // 
     public void TapHandler(UITapGestureRecognizer tgr) { 
      CGPoint touchPoint = tgr.LocationInView (nativeElement); 
      formsElement.OnTapEvent ((int)touchPoint.X, (int)touchPoint.Y); 
     } 
     #endregion 
    } 
} 
相關問題