Реализация перетаскивания UIImageView с использованием UILongPressGestureRecognizer - PullRequest
0 голосов
/ 15 марта 2012

Я реализую UILongPressGestureRecognizer, который позволит пользователю долго нажимать на ImageView, а затем перетаскивать изображение в другое место. Как только начинается длительное нажатие, я масштабирую вид, чтобы указать, что перетаскивание готово, и пользователь затем может перетаскивать. Это достигается путем обновления кадра ImageViews каждый раз, когда селектор вызывается с состоянием изменения. Это прекрасно работает, но я хотел бы создать копию представления и добавить ее в родительское представление в начальном состоянии, а затем продолжить обновление фрейма копии в родительском представлении. Я хочу сделать это, чтобы устранить любые проблемы с перетаскиванием из прокрутки. Я не могу получить правильную логику в методе HandleChangeState, хотя. Копия просто не перетаскивается правильно.

Есть идеи?

Часть кода просто есть, потому что я пытаюсь сделать более универсальный UILongPressGestureRecognizer для UILabel и UIImageView, но это не относится к этой проблеме.

public class LearningViewLongPressGestureRecognizer : UILongPressGestureRecognizer
    {
        private UIImageView draggedImageView;
        private UILabel draggedLabel;
        private RectangleF originalFrame;       
        private UIView parentView;
        private DRAG_CONTENT_TYPE contentType;

        public enum DRAG_CONTENT_TYPE
        {
            UIIMAGEVIEW,
            UILabel
        }

        public static Selector LongPressSelector
        {
            get
            {
                return new Selector ("HandleLongPress");
            }
        }

        public LearningViewLongPressGestureRecognizer (UIView parent, DRAG_CONTENT_TYPE contentType)
        {
            this.contentType = contentType;
            this.AddTarget(this, LongPressSelector);
            this.Delegate = new LongPressRecognizerDelegate();
            this.parentView = parent;
        }

        [Export("HandleLongPress")]
        public void HandleLongPress(UILongPressGestureRecognizer recognizer)
        {
            Console.WriteLine ("HandleLongPress Called.");
            switch (recognizer.State)
            {
            case UIGestureRecognizerState.Began:
                Console.WriteLine ("HandleLongPress Began.");
                HandleBeginState(recognizer);
                break;
            case UIGestureRecognizerState.Changed:
                Console.WriteLine ("HandleLongPress Changed.");
                HandleChangedState(recognizer);
                break;
            case UIGestureRecognizerState.Cancelled:
                Console.WriteLine ("HandleLongPress Canceled.");
                break;
            case UIGestureRecognizerState.Ended:
                Console.WriteLine ("HandleLongPress Ended.");
                break;
            default:
                Console.WriteLine ("HandleLongPress Default.");
                break;
            }
        }

        private void HandleBeginState(UILongPressGestureRecognizer recognizer)
        {
            this.originalFrame = this.View.Frame;                       

            if (contentType == DRAG_CONTENT_TYPE.UIIMAGEVIEW)
            {
                draggedImageView = new UIImageView();
                draggedImageView.Image = ((UIImageView)this.View).Image;    
                draggedImageView.Frame = this.View.Frame;

                //Change the view scale to indicate to the user that the view is selected and ready for dragging.
                draggedImageView.Transform *= CGAffineTransform.MakeScale(1.1f, 1.1f);

                parentView.AddSubview(draggedImageView);
                parentView.BringSubviewToFront(draggedImageView);                   
            }                               
        }

        private void HandleChangedState(UILongPressGestureRecognizer recognizer)
        {           
            PointF currentLocationOfTouchInParentView = recognizer.LocationInView(draggedImageView);//recognizer.TranslationInView(this.View);
            PointF deltaFromOriginal = new PointF(currentLocationOfTouchInParentView.X - originalFrame.X, currentLocationOfTouchInParentView.Y - originalFrame.Y);

            RectangleF newFrame = draggedImageView.Frame;
            newFrame.Offset(deltaFromOriginal.X, deltaFromOriginal.Y);
            draggedImageView.Frame = newFrame;
        }

        private void HandleCanceledState(UILongPressGestureRecognizer recognizer)
        {

        }

        private void HandleEndedState(UILongPressGestureRecognizer recognizer)
        {

        }

        protected class LongPressRecognizerDelegate : UIGestureRecognizerDelegate
        {
            public override bool ShouldReceiveTouch (UIGestureRecognizer recognizer, UITouch touch)
            {
                return true;
            }
        }
    }   

1 Ответ

0 голосов
/ 16 марта 2012

Решил мою проблему с расчетами.Мне нужно было взять дельту исходного местоположения касания, с которого начинался жест, и текущее местоположение касания в родительском представлении, а затем добавить это смещение к перетаскиваемой рамке представления.Ниже мое решение.

private void HandleBeginState(UILongPressGestureRecognizer recognizer)
        {
            this.originalFrame = this.View.Frame;                       
            this.originalTouchLocation = recognizer.LocationInView(parentView);

            if (contentType == DRAG_CONTENT_TYPE.UIIMAGEVIEW)
            {
                draggedImageView = new UIImageView();
                draggedImageView.Image = ((UIImageView)this.View).Image;    
                draggedImageView.Frame = new RectangleF(originalFrame.X, originalFrame.Y, originalFrame.Size.Width, originalFrame.Size.Height);

                parentView.AddSubview(draggedImageView);
                parentView.BringSubviewToFront(draggedImageView);   

                //Change the view scale to indicate to the user that the view is selected and ready for dragging.
                draggedImageView.Transform *= CGAffineTransform.MakeScale(1.1f, 1.1f);
            }                               
        }

        private void HandleChangedState(UILongPressGestureRecognizer recognizer)
        {           
            PointF currentLocationOfTouchInParentView = recognizer.LocationInView(parentView);
            PointF deltaFromOriginalTouch = new PointF(currentLocationOfTouchInParentView.X - originalTouchLocation.X, currentLocationOfTouchInParentView.Y - originalTouchLocation.Y);

            RectangleF newFrame = originalFrame;
            newFrame.Offset(deltaFromOriginalTouch.X, deltaFromOriginalTouch.Y);
            draggedImageView.Frame = newFrame;          
        }
...