IPhone/iOS: как реализовать Drag and Drop для подзаголовков Scrollview?

У меня есть горизонтальное прокрутка в UIViewController, где у меня много изображений небольшого размера. Я сохраняю изображения в scrollview, потому что изображения больше, поэтому пользователь может прокручивать по горизонтали и выбирать изображения. Но проблема в том, что я должен выбрать изображение и перетащить его в это представление UIViewController. Но поскольку изображения находятся в режиме прокрутки, перетаскивание изображений в UIViewController не работает, не обнаруживая также события касания. Пожалуйста, ПРИМЕЧАНИЕ. Если у меня нет прокрутки, но просто сохраняйте изображения в режиме просмотра UIViewController, перетащите изображения на один и тот же экран, работает очень хорошо.

Как я могу это решить, когда мне нужно иметь прокрутку и перетаскивание изображений, любые советы/помощь, пожалуйста?

Ответ 1

Привет Гетси,

Я не собираюсь предоставлять вам код напрямую, но дайте представление, как управлять этим.

Вы можете управлять этим путем. Когда вы нажимаете на свой объект в scrollView в это время или когда вы перемещаете этот объект, запустив в это время прокрутку прокрутки на myScroll.scrollEnabled = NO;

Затем, когда на endTouch вы можете включить Scroll от myScroll.scrollEnabled = YES; Таким образом, вы можете управлять тем, что вы перемещаете объект, надеясь, что у вас есть логика.

Вот демонстрационный код: Перетаскивание с помощью ScrollView. который имеет ту же логику Disabling прокрутки на touchesMoved: и Enabling прокрутки на touchesEnded:.

Ответ 2

Я реализовал это поведение раньше, чем без подкласса.

Я использовал canCancelContentTouches = NO для UIScrollView, чтобы убедиться, что обработчики subviews касаются друг друга. Если было затронуто subview (в вашем случае изображение), я переместил представление из прокрутки в супервизор и начал отслеживать его перетаскивание. (Вы должны вычислить правильные координаты в новом супервизии, чтобы он оставался на месте).

После завершения перетаскивания я проверил, была ли достигнута целевая область, иначе я переместил ее обратно в scrollview. Если бы это было недостаточно подробно, я мог бы опубликовать некоторый код.

Ну вот мой пример кода: Github: JDDroppableView

Ответ 3

Getsy,

Попробуйте код для перетаскивания объектов:

-(void)dragAndDropWithGesture {

UILongPressGestureRecognizer *downwardGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(dragGestureChanged:)];
[scrollViewAlfabeto addGestureRecognizer:downwardGesture];
    for (UIGestureRecognizer *gestureRecognizer in myscrollView.gestureRecognizers)
    {
       [gestureRecognizer requireGestureRecognizerToFail:downwardGesture];
    }
}

- (void) dragGestureChanged:(UIPanGestureRecognizer*)gesture
{
CGPoint point = [gesture locationInView:scrollViewAlfabeto];

if (gesture.state == UIGestureRecognizerStateBegan) 
{

    [imageViewToMove removeFromSuperview];
    [self.view addSubview:imageViewToMove];

    UIView *draggedView = [myscrollView hitTest:point withEvent:nil];
    if ([draggedView isKindOfClass:[UIImageView class]])
    {
        imageViewToMove = (UIImageView*)draggedView;
    }
}
else if (gesture.state == UIGestureRecognizerStateChanged)
{
    imageToMove.center = point;
}
else if (gesture.state == UIGestureRecognizerStateEnded     ||
         gesture.state == UIGestureRecognizerStateCancelled ||
         gesture.state == UIGestureRecognizerStateFailed)
{
    // Determine if dragged view is in an OK drop zone
    // If so, then do the drop action, if not, return it to original location

    NSLog(@"point.x final:%f", point.x);
    NSLog(@"point.y final:%f", point.y);

    if (CGRectContainsPoint(goal.frame, point)){
        imageToMove.frame = CGRectMake(167, 159, 100, 100);
    }

    else{

        [imageToMove removeFromSuperview];
        [myscrollView addSubview:imageToMove];
        [imageToMove setFrame:CGRectMake(12, 38, 100, 100)];
        imageToMove = nil;



    }
}

}

Пусть этот код поможет вам.

Ответ 4

Для аналогичной проблемы я сделал подкласс UIScrollView следующим образом: PoliteScrollView передает сенсорные сообщения в него, когда он определяет, что они перетаскиваются.

@interface PoliteScrollView : UIScrollView

// number of pixels perpendicular to the scroll views orientation to make a drag start counting as a subview drag
// defaults to 1/10 of the scroll view width or height, whichever is smaller
@property(nonatomic,assign) CGFloat subviewDraggingThreshold;
// yes when a subview is being dragged
@property(nonatomic,assign) BOOL isDraggingSubview;
// the subview being dragged
@property(nonatomic,strong) UIView *draggingSubview;

@end

@protocol PoliteScrollViewDelegate <NSObject>
@optional
- (void)scrollView:(PoliteScrollView *)scrollView subviewTouchesBegan:(NSSet *)touches;
- (void)scrollView:(PoliteScrollView *)scrollView subviewTouchesMoved:(NSSet *)touches;
- (void)scrollView:(PoliteScrollView *)scrollView subviewTouchesEnded:(NSSet *)touches;
@end

Основная идея дизайна заключается в том, что перетаскивание в виде прокрутки неоднозначно. Просматривает ли пользователь или перетаскивает подвью? Представление PoliteScroll обрабатывает это, предоставляя две вещи: (1) понятие ориентации (горизонтальное, если оно длиннее ширины, вертикальное в противном случае) и (2) пороговое расстояние для того, что составляет сопротивление в направлении, перпендикулярном к нему. (по умолчанию - 1/10 ширины или высоты).

Я вставил это и несколько других файлов в вставить bin, содержащий следующее:

  • PoliteScrollView.h и .m
  • DraggableImageView.h и .m - который изменяет его положение, когда он получает сообщения касания.
  • ViewController.m - который демонстрирует двойную комбинацию.

Чтобы объединить их в проекте, вставьте вставку bin в файлы с соответствующим именем, добавьте раскадровку с помощью PoliteScrollView (обязательно установите ее делегировать), добавьте некоторые изображения (ViewController пытается добавить puppy0.jpeg на щенок4. JPEG.

Ответ 5

Я создал пример, который иллюстрирует, как перетаскивать между двумя или несколькими видами: http://www.ancientprogramming.com/2012/04/05/drag-and-drop-between-multiple-uiviews-in-ios/

Мне показалось, что неплохо зарегистрировать распознаватель жестов в другом представлении, чем перетаскиваемые фактические представления. Это позволит убедиться, что жест продолжается, даже если перетаскиваемый вид изменяет свое "родительское" представление.

Возможно, это может дать некоторое вдохновение