【问题标题】:Xamarin.forms Pinch and ZoomXamarin.forms 捏合和缩放
【发布时间】:2014-10-23 23:53:28
【问题描述】:

有没有一种方法可以让我使用 ONLY Xamarin.Forms 控件进行捏合和缩放。

我想在 xamarin.forms(WebView 或 Image 或任何其他)的任何控件中显示图像,并能够从应用程序中进行缩放。

【问题讨论】:

    标签: ios xamarin.forms


    【解决方案1】:

    截至本文发布时,还没有一种方法可以使用纯内置表单控件进行捏合/缩放。有一种方法可以实现这一点,但您必须为此实现本机渲染器。

    我通过创建一个继承自 Xamarin.Forms.ContentView - PanGestureContainer 的类在我正在编写的应用程序中实现了这一点,该类具有诸如最小/最大接触点数和要侦听的事件之类的属性。

    在 iOS 项目中,我为我的视图制作了一个自定义渲染器,渲染器从视图中获取属性并连接触摸事件侦听器。

    此外,我创建了一个可附加属性(也称为行为),它可以应用于其他视图,并且在应用时,它从其父视图中获取视图,将其包装在 PanGestureRecognizer 中,另一个附加属性以相同的方式充当事件侦听器包装器。

    这是一个完整的 hack,但在 Xamarin 干净地实现它之前涵盖了缺失的功能


    更新:现在有了示例代码,严重精简,因为它会发布太多,它应该让您知道如何实现这一点,而不是复制/粘贴解决方案。如果它看起来可能太多了,我相信有更好的方法,但它可以解决这个问题,直到这个功能被烘焙。

      public abstract class BaseInteractiveGestureRecognizer : BindableObject, IInteractiveGestureRecognizer
        {
            public static readonly BindableProperty CommandProperty = BindableProperty.Create<BaseInteractiveGestureRecognizer, ICommand> ((b) => b.Command, null, BindingMode.OneWay, null, null, null, null);
    
            public ICommand Command {
                get {
                    return (ICommand)base.GetValue (BaseInteractiveGestureRecognizer.CommandProperty);
                }
                set {
                    base.SetValue (BaseInteractiveGestureRecognizer.CommandProperty, value);
                }
            }
    
            public object CommandParameter {get;set;} // make bindable as above
    
            public GestureState State { get;set;} // make bindable as above
    
            public View SourceView{ get; set; } 
    
            public void Send ()
            { 
                if (Command != null && Command.CanExecute (this)) {
                    Command.Execute (this);
                }
            }
        }
    
    public class PanGesture : BaseInteractiveGestureRecognizer
    {
        public uint MinTouches { get;set; } // make bindable
        public uint MaxTouches { get;set; } // make bindable
        // add whatever other properties you need here - starting point, end point, touch count, current touch points etc.
    }
    

    然后在iOS项目中:

    public abstract class BaseInteractiveGestureRenderer : BindableObject,IGestureCreator<UIView>
        {
            public abstract object Create (IInteractiveGestureRecognizer gesture, Element formsView, UIView nativeView);
    
            public static GestureState FromUIGestureState (UIGestureRecognizerState state)
            {
                switch (state) {
                case UIGestureRecognizerState.Possible:
                    return GestureState.Possible;
                case UIGestureRecognizerState.Began:
                    return GestureState.Began;
                case UIGestureRecognizerState.Changed:
                    return GestureState.Update;
                case UIGestureRecognizerState.Ended:
                    return GestureState.Ended;
                case UIGestureRecognizerState.Cancelled:
                    return GestureState.Cancelled;
                case UIGestureRecognizerState.Failed:
                    return GestureState.Failed; 
                default:
                    return GestureState.Failed;
                }    
            }
        }
    
    
    using StatementsHere;
    [assembly: ExportGesture (typeof(PanGesture), typeof(PanGestureRenderer))]
    namespace YourNamespaceHere.iOS
    {
    public class PanGestureRenderer : BaseInteractiveGestureRenderer
    {
        public PanGestureRenderer () : base ()
        {   
        }
    
        #region IGestureCreator implementation
    
        public override object Create (IInteractiveGestureRecognizer gesture, Element formsView, UIView nativeView)
        {   
            PanGesture panGesture = gesture as PanGesture; 
            nativeView.UserInteractionEnabled = true; 
    
            UIPanGestureRecognizer panGestureRecognizer = null;
            panGestureRecognizer = new UIPanGestureRecognizer (() => panGesture.Send());
        }
    }
    

    【讨论】:

    • Sten Petrov 您的回答可能会有所帮助,但我只能使用 Xamarin.Forms。
    • @Amete this is Xamarin.Forms,渲染器是其中的一部分
    【解决方案2】:

    我最终使用元视口进行缩放,如下所示。 这可能不是每个人的解决方案,但它对我有用。

    把图片十六进制-64放到下面的图片标签里面,然后把整个html放到WebView里面。

    this.WebView.Source = new HtmlWebViewSource { BaseUrl = URL, Html = html };
    
    The html will be defined here.
    <!DOCTYPE html>
    <html lang="en-us">
    <head>
        <meta name="viewport" content="width=device-width, initial-scale=0.25, maximum-scale=3.0 user-scalable=1">
        <title></title>
        <style>
            body {
                margin: 0 20px 0 0;
                font-family: HelveticaNeue-Light, HelveticaNeue-UltraLight, Helvetica, Consolas, 'Courier New';
            }
    
            table {
                width: 100%;
                border: 1px outset;
                border-color: #3c4142;
            }
    
            td {
                font-size: 8px;
            }
        </style>
    </head>
    <body>
        <img src="data:image/png;base64,YourBase64imagestringhere" style="width:100%" />
    </body>
    </html>
    

    【讨论】:

    • 我想要这样的东西,但我无法理解这个 src="data:image/png;base64,YourBase64imagestringhere" ,我怎样才能在这里添加我的静态图像?我的图片路径是“myproject.Images.test.jpg”
    • 首先您需要将图像更改为 base 64 字符串,请参阅下面的链接以了解如何做到这一点stackoverflow.com/questions/21325661/…。然后注入 base 64 结果(这是一个非常大的字符串)并将其放在占位符中,即 YourBase64imagestringhere 在我的代码中。您必须有一种将数据传递给 html 的方法。就我而言,我使用的是来自 nancy fx 的 Razor 视图。
    【解决方案3】:

    使用来自 Nuget 的 Mr.Gestures 包:https://www.nuget.org/packages/MR.Gestures/

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-07-11
      • 1970-01-01
      • 2012-07-25
      • 2011-11-26
      • 1970-01-01
      • 2017-09-23
      • 2014-11-26
      相关资源
      最近更新 更多