Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/visual-studio/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 以编程方式创建浮动可拖动按钮,无需故事板(Xamarin)_C#_Visual Studio_Drag And Drop_Xamarin.ios_Uibutton - Fatal编程技术网

C# 以编程方式创建浮动可拖动按钮,无需故事板(Xamarin)

C# 以编程方式创建浮动可拖动按钮,无需故事板(Xamarin),c#,visual-studio,drag-and-drop,xamarin.ios,uibutton,C#,Visual Studio,Drag And Drop,Xamarin.ios,Uibutton,我有一个按程序创建的按钮 InfoBtn = _utilProvider.FloatingBtn("My Button"); //Returns Floating UIButton InfoBtn.Frame = new CGRect((ScreenWidth / 2) - 22.5, ScreenHeight - 65, 55, 55); View.Add(InfoBtn); 我想以编程的方式向它添加拖放功能。问题是,Xamarin连接的事件不允许我以这种方式使用自定义事件处理程序,例如U

我有一个按程序创建的按钮

InfoBtn = _utilProvider.FloatingBtn("My Button"); //Returns Floating UIButton
InfoBtn.Frame = new CGRect((ScreenWidth / 2) - 22.5, ScreenHeight - 65, 55, 55);
View.Add(InfoBtn);

我想以编程的方式向它添加拖放功能。问题是,Xamarin连接的事件不允许我以这种方式使用自定义事件处理程序,例如
UIEvent
(直接从iOS示例转换):

根据Xamarin在iOS中使用Touch的例子,他们使用故事板

将创建自定义
UIViewController

partial class TouchViewController : UIViewController
并通过设置自定义类指定给ViewController

<viewController id="18" sceneMemberID="viewController" customClass="TouchViewController">

partial class MyGestureRecognizer : UIGestureRecognizer
{
    public override void TouchesBegan(NSSet touches, UIEvent evt)
    {
        base.TouchesBegan(touches, evt);

        UITouch touch = touches.AnyObject as UITouch;
        if (touch != null)
        {
            // Touch started
        }
    }

    public override void TouchesCancelled(NSSet touches, UIEvent evt)
    {
        base.TouchesCancelled(touches, evt);
    }

    public override void TouchesEnded(NSSet touches, UIEvent evt)
    {
        base.TouchesEnded(touches, evt);
    }

    public override void TouchesMoved(NSSet touches, UIEvent evt)
    {
        base.TouchesMoved(touches, evt);
        UITouch touch = touches.AnyObject as UITouch;
        if (touch != null)
        {
            // move the shape
        }
    }
}
但它只会进入
touchesbreated
方法

在尝试了网上找到的所有教程之后,我现在很沮丧


任何帮助都将不胜感激

好的,我用

我对类做了一些修改,下面是工作代码:

ViewDidLoad()中

添加了与我的应用程序具有相同命名空间的类DragDropgestureRecognitor.cs:

using System;
using CGPoint = System.Drawing.PointF;
using Foundation;
using UIKit;

namespace myNS
{
    public class DragDropGestureRecognizer : UIGestureRecognizer
    {
        public DragDropGestureRecognizer()
        {
        }

        public event EventHandler<DragDropEventArgs> Held;
        protected void OnHeld(object sender, DragDropEventArgs e)
        {
            if (Held != null)
                Held(sender, e);
        }

        public event EventHandler<DragDropEventArgs> Dragging;
        protected void OnDragging(object sender, DragDropEventArgs e)
        {
            if (Dragging != null)
                Dragging(sender, e);
        }


        public event EventHandler<DragDropEventArgs> Dropped;
        protected void OnDropped(object sender, DragDropEventArgs e)
        {
            if (Dropped != null)
                Dropped(sender, e);
        }

        public bool DidDrag { get; private set; }
        public CGPoint DownAt { get; private set; }
        public CGPoint DragAt { get; private set; }
        public CGPoint ViewWasAt { get; private set; }
        public CGPoint Delta
        {
            get { return new CGPoint(DragAt.X - DownAt.X, DragAt.Y - DownAt.Y); }
        }
        public bool Active { get { return DidDrag; } }
        public override UIGestureRecognizerState State
        {
            get { return base.State; }
            set { base.State = value; }
        }
        private CGPoint TouchPoint { get { return (CGPoint)LocationInView(View.Superview); } }

        public override bool CanBePreventedByGestureRecognizer(UIGestureRecognizer preventingGestureRecognizer)
        {
            return false;
        }

        public override void TouchesBegan(NSSet touches, UIEvent evt)
        {
            base.TouchesBegan(touches, evt);

            if (NumberOfTouches > 1)
            {
                State = UIGestureRecognizerState.Failed;
                return;
            }

            OnHeld(this, new DragDropEventArgs(default(UIGestureRecognizerState), DragAt, Delta, ViewWasAt));

            DownAt = TouchPoint;
            ViewWasAt = (CGPoint)View.Center;
            State = UIGestureRecognizerState.Possible;
        }

        public override void TouchesEnded(NSSet touches, UIEvent evt)
        {
            base.TouchesEnded(touches, evt);

            if (DidDrag)
            {
                State = UIGestureRecognizerState.Recognized;
                OnDropped(this, new DragDropEventArgs(State, DragAt, Delta, ViewWasAt));
            }
            else
                State = UIGestureRecognizerState.Failed;
        }

        public override void TouchesCancelled(NSSet touches, UIEvent evt)
        {
            base.TouchesCancelled(touches, evt);
            State = UIGestureRecognizerState.Failed;
        }

        public override void TouchesMoved(NSSet touches, UIEvent evt)
        {
            base.TouchesMoved(touches, evt);
            if (State == UIGestureRecognizerState.Failed)
                return;

            DragAt = TouchPoint;
            if (Distance(DownAt, DragAt) > 30 || DidDrag) //Won't move until dragged further than 30px
            {
                DidDrag = true;
                OnDragging(this, new DragDropEventArgs(State, DragAt, Delta, ViewWasAt));
                State = UIGestureRecognizerState.Changed;
            }
        }

        public override void Reset()
        {
            base.Reset();

            State = UIGestureRecognizerState.Possible;
            DownAt = CGPoint.Empty;
            DragAt = CGPoint.Empty;
            DidDrag = false;
        }

        private float Distance(CGPoint point1, CGPoint point2)
        {
            var dx = point1.X - point2.X;
            var dy = point1.Y - point2.Y;
            return (float)Math.Sqrt(dx * dx + dy * dy);
        }
    }

    public class DragDropEventArgs : EventArgs
    {
        public DragDropEventArgs(UIGestureRecognizerState state, CGPoint point, CGPoint delta, CGPoint viewWasAt)
        {
            State = state;
            Point = point;
            Delta = delta;
            ViewWasAt = viewWasAt;
        }

        public UIGestureRecognizerState State { get; private set; }
        public CGPoint Point { get; private set; }
        public CGPoint Delta { get; private set; }
        public CGPoint ViewWasAt { get; private set; }
    }
}
partial class MyGestureRecognizer : UIGestureRecognizer
{
    public override void TouchesBegan(NSSet touches, UIEvent evt)
    {
        base.TouchesBegan(touches, evt);

        UITouch touch = touches.AnyObject as UITouch;
        if (touch != null)
        {
            // Touch started
        }
    }

    public override void TouchesCancelled(NSSet touches, UIEvent evt)
    {
        base.TouchesCancelled(touches, evt);
    }

    public override void TouchesEnded(NSSet touches, UIEvent evt)
    {
        base.TouchesEnded(touches, evt);
    }

    public override void TouchesMoved(NSSet touches, UIEvent evt)
    {
        base.TouchesMoved(touches, evt);
        UITouch touch = touches.AnyObject as UITouch;
        if (touch != null)
        {
            // move the shape
        }
    }
}
InfoBtn = _utilProvider.FloatingBtn("My Button"); //Returns Floating UIButton
var dd = new DragDropGestureRecognizer();
dd.Dragging += (object sender, DragDropEventArgs e) =>
{
    var view = ((DragDropGestureRecognizer)sender).View;

    // Reposition box.
    var x = e.ViewWasAt.X + e.Delta.X;
    var y = e.ViewWasAt.Y + e.Delta.Y;
    view.Center = new CGPoint(x, y);
};
InfoBtn.AddGestureRecognizer(dd);
InfoBtn.TouchUpInside += async (object sender, EventArgs e) =>
{
    //Button On Click
};
InfoBtn.Frame = new CGRect((ScreenWidth / 2) - 22.5, ScreenHeight - 65, 55, 55);
View.Add(InfoBtn);
using System;
using CGPoint = System.Drawing.PointF;
using Foundation;
using UIKit;

namespace myNS
{
    public class DragDropGestureRecognizer : UIGestureRecognizer
    {
        public DragDropGestureRecognizer()
        {
        }

        public event EventHandler<DragDropEventArgs> Held;
        protected void OnHeld(object sender, DragDropEventArgs e)
        {
            if (Held != null)
                Held(sender, e);
        }

        public event EventHandler<DragDropEventArgs> Dragging;
        protected void OnDragging(object sender, DragDropEventArgs e)
        {
            if (Dragging != null)
                Dragging(sender, e);
        }


        public event EventHandler<DragDropEventArgs> Dropped;
        protected void OnDropped(object sender, DragDropEventArgs e)
        {
            if (Dropped != null)
                Dropped(sender, e);
        }

        public bool DidDrag { get; private set; }
        public CGPoint DownAt { get; private set; }
        public CGPoint DragAt { get; private set; }
        public CGPoint ViewWasAt { get; private set; }
        public CGPoint Delta
        {
            get { return new CGPoint(DragAt.X - DownAt.X, DragAt.Y - DownAt.Y); }
        }
        public bool Active { get { return DidDrag; } }
        public override UIGestureRecognizerState State
        {
            get { return base.State; }
            set { base.State = value; }
        }
        private CGPoint TouchPoint { get { return (CGPoint)LocationInView(View.Superview); } }

        public override bool CanBePreventedByGestureRecognizer(UIGestureRecognizer preventingGestureRecognizer)
        {
            return false;
        }

        public override void TouchesBegan(NSSet touches, UIEvent evt)
        {
            base.TouchesBegan(touches, evt);

            if (NumberOfTouches > 1)
            {
                State = UIGestureRecognizerState.Failed;
                return;
            }

            OnHeld(this, new DragDropEventArgs(default(UIGestureRecognizerState), DragAt, Delta, ViewWasAt));

            DownAt = TouchPoint;
            ViewWasAt = (CGPoint)View.Center;
            State = UIGestureRecognizerState.Possible;
        }

        public override void TouchesEnded(NSSet touches, UIEvent evt)
        {
            base.TouchesEnded(touches, evt);

            if (DidDrag)
            {
                State = UIGestureRecognizerState.Recognized;
                OnDropped(this, new DragDropEventArgs(State, DragAt, Delta, ViewWasAt));
            }
            else
                State = UIGestureRecognizerState.Failed;
        }

        public override void TouchesCancelled(NSSet touches, UIEvent evt)
        {
            base.TouchesCancelled(touches, evt);
            State = UIGestureRecognizerState.Failed;
        }

        public override void TouchesMoved(NSSet touches, UIEvent evt)
        {
            base.TouchesMoved(touches, evt);
            if (State == UIGestureRecognizerState.Failed)
                return;

            DragAt = TouchPoint;
            if (Distance(DownAt, DragAt) > 30 || DidDrag) //Won't move until dragged further than 30px
            {
                DidDrag = true;
                OnDragging(this, new DragDropEventArgs(State, DragAt, Delta, ViewWasAt));
                State = UIGestureRecognizerState.Changed;
            }
        }

        public override void Reset()
        {
            base.Reset();

            State = UIGestureRecognizerState.Possible;
            DownAt = CGPoint.Empty;
            DragAt = CGPoint.Empty;
            DidDrag = false;
        }

        private float Distance(CGPoint point1, CGPoint point2)
        {
            var dx = point1.X - point2.X;
            var dy = point1.Y - point2.Y;
            return (float)Math.Sqrt(dx * dx + dy * dy);
        }
    }

    public class DragDropEventArgs : EventArgs
    {
        public DragDropEventArgs(UIGestureRecognizerState state, CGPoint point, CGPoint delta, CGPoint viewWasAt)
        {
            State = state;
            Point = point;
            Delta = delta;
            ViewWasAt = viewWasAt;
        }

        public UIGestureRecognizerState State { get; private set; }
        public CGPoint Point { get; private set; }
        public CGPoint Delta { get; private set; }
        public CGPoint ViewWasAt { get; private set; }
    }
}
private int _xPad, _yPad, _xDelta, _yDelta;
prviate bool _moved;

InfoBtn.Touch += (v, me) => //InfoBtn is a button within a frameLayout
{
    int X = (int)me.Event.RawX;
    int Y = (int)me.Event.RawY;
    switch (me.Event.Action & MotionEventActions.Mask)
    {
        case MotionEventActions.Down:
            _xPad = frameLayout.PaddingLeft;
            _yPad = frameLayout.PaddingTop;
            _xDelta = X;
            _yDelta = Y;
            _moved = false;
            break;
        case MotionEventActions.Up:
            if (!_moved)
            {
                //On Button Click
            }
            break;
        case MotionEventActions.PointerDown:
            break;
        case MotionEventActions.PointerUp:
            break;
        case MotionEventActions.Move:
            var _x = X - _xDelta;
            var _y = Y - _yDelta;
            _moved = _moved || Math.Abs(_x) > 100 || Math.Abs(_y) > 100; //100px
            if (_moved)
            {
                var padleft = _x - _xPad;
                padleft = padleft + InfoBtn.Width > Resources.DisplayMetrics.WidthPixels ? Resources.DisplayMetrics.WidthPixels - InfoBtn.Width : padleft;
                var padtop = _y - _yPad;
                padtop = padtop + InfoBtn.Height > Resources.DisplayMetrics.HeightPixels ? Resources.DisplayMetrics.HeightPixels - InfoBtn.Height : padtop;
                frameLayout.SetPadding(0, 0, padleft, padtop);
            }
            break;
    }
    frameLayout.Invalidate();
};