iphone — неожиданное поведение при пролистывании по диагонали UIScrollView

#iphone #objective-c #ios #xcode #uiscrollview

#iPhone #objective-c #iOS #xcode #uiscrollview

Вопрос:

Я разрабатываю приложение, в котором мне нужно перетащить UIImageView из UIScrollView. В нижней части моего основного UIView у меня есть UIScrollView с UIImageViews внутри. Я создал пользовательский UIScrollView, используя следующий фрагмент кода:

 @interface CustomScroll : UIScrollView {

}@end


@implementation CustomScroll


- (id)initWithFrame:(CGRect)frame {
return [super initWithFrame:frame];

}

- (void) touchesMoved: (NSSet *) touches withEvent: (UIEvent *) event { 
// If not dragging, send event to next responder
if (!self.dragging) {
    self.scrollEnabled=NO;
    [self.nextResponder touchesMoved:touches withEvent:event]; 

}
else{
    [super touchesMoved: touches withEvent: event];
}
  

}

 - (void) touchesEnded: (NSSet *) touches withEvent: (UIEvent *) event { 
// If not dragging, send event to next responder
if (!self.dragging)
    [self.nextResponder touchesEnded: touches withEvent:event]; 
else
    [super touchesEnded: touches withEvent: event];
}
@end
  

Отсюда я включил объект CustomScroll в свой PuzzleViewController и подключил его к scrollview в Interface builder:

 @interface PuzzleViewController : UIViewController <UIScrollViewDelegate> {
    IBOutlet CustomScroll *segmentScrollview;
  

}

Я добавил все UIImageViews программно.

Этот код работает так, как ожидалось. UIImageView обнаруживает касание, и я могу перетащить UIImageView из UIScrollView в UIView.

Но проблема возникает, когда я перетаскиваю UIImageView по диагонали.

В моем приложении, когда я перетаскиваю UIImageView вертикально из scrollview, я могу переместить свой UIImageView из UIScrollView в UIView. Но когда я перетаскиваю UIImageView по диагонали из scrollview, я не могу переместить UIImageView. Прокрутка по диагонали прокручивает UIScrollView [UIImageView остается нетронутым], что является неожиданным. Я хочу, чтобы UIImageView перетаскивался по диагонали из UIScrollView.

Любая помощь будет с благодарностью принята.

Заранее спасибо за любую помощь.

Ответ №1:

Это всего лишь thought…so попробуйте и расскажите мне, как это происходит. Если не сработает, я постараюсь помочь вам дальше. Попробуйте установить directionalLockEnabled значение НЕТ. Если для параметра установлено значение «ДА», то ваше перемещение будет ограничено только горизонтальным / вертикальным. Если для него установлено значение NO, вы должны иметь возможность перемещаться по диагонали. Попробуйте и дайте мне знать, как это происходит.

UIScrollView directionLockEnabled Docs

Если это свойство равно NO, прокрутка разрешена как в горизонтальном, так и в вертикальном направлениях. Если это свойство имеет значение YES и пользователь начинает перетаскивание в одном общем направлении (по горизонтали или вертикали), режим прокрутки отключает прокрутку в другом направлении.Если направление перетаскивания по диагонали, прокрутка не будет заблокирована, и пользователь может перетаскивать в любом направлении, пока перетаскивание не завершится. Значение по умолчанию — НЕТ

Комментарии:

1. Спасибо Сэму и PTBG за ваш ответ. Но directionalLockEnabled не работает. Проблема остается такой, какая она есть. Я не могу перетащить UIImageView по диагонали из scrollview.

Ответ №2:

я думаю, что вам нужно не [super touchesMoved: …], а скорее [self.superview touchesMoved: …] … предполагая, что у вас есть супервизор, содержащий как CustomScroll, так и другое представление, которое вы пытаетесь перетащить в настройки, чтобы справиться с этим.

Ответ №3:

Я знаю, что это более старый вопрос, но я только что столкнулся с этой проблемой. По сути, я хотел, чтобы просмотр прокрутки с поддержкой подкачки шел вверх, вниз, влево или вправо. Использование переменных pagingEnabled и directionalLockEnabled заставило его в основном работать, за исключением перетаскивания по диагонали. Мое решение приведено ниже.

     - (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    if (self.scrollView.contentOffset.x >= self.previousScrollOffset.x amp;amp;
        self.scrollView.contentOffset.y == self.scrollView.contentSize.height / 3){

        self.currentScrollDirection = SW_DIRECTION_LEFT;

    } else if (self.scrollView.contentOffset.x < self.previousScrollOffset.x amp;amp;
               self.scrollView.contentOffset.y == self.scrollView.contentSize.height / 3){

        self.currentScrollDirection = SW_DIRECTION_RIGHT;

    } else if (self.scrollView.contentOffset.x == self.scrollView.contentSize.width / 3 amp;amp;
         self.scrollView.contentOffset.y >= self.previousScrollOffset.y){

        self.currentScrollDirection = SW_DIRECTION_UP;

    } else if (self.scrollView.contentOffset.x == self.scrollView.contentSize.width / 3 amp;amp;
         self.scrollView.contentOffset.y <= self.previousScrollOffset.y){

        self.currentScrollDirection = SW_DIRECTION_DOWN;

    } else {

        self.currentScrollDirection = SW_DIRECTION_NONE;

    }

    //lock to either horizontal or vertical if we are dragging (prevent the diagonal drag)
    if (self.scrollView.isTracking amp;amp; self.currentScrollDirection == SW_DIRECTION_NONE){
        self.scrollView.contentOffset = CGPointMake(self.scrollView.contentOffset.x, self.scrollView.contentSize.height / 3);
    }

    self.previousScrollOffset = scrollView.contentOffset;
}
  

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

Чтобы это сработало, вам нужно будет объявить

 @property (readwrite, nonatomic) SW_SCROLL_DIRECTION currentScrollDirection;
@property (readwrite, nonatomic) CGPoint previousScrollOffset;
  

и

 typedef enum {
SW_DIRECTION_NONE,
SW_DIRECTION_LEFT,
SW_DIRECTION_RIGHT,
SW_DIRECTION_UP,
SW_DIRECTION_DOWN
  

} SW_SCROLL_DIRECTION;

Примечание. Это, вероятно, не будет работать из коробки, как вы видите, я жестко задаю значение в 3 страницы. Это потому, что у меня контент всегда центрирован, поэтому вы можете прокрутить одну страницу в любом направлении, затем она анимируется обратно в центр. Это не должно быть сложно изменить для работы с несколькими страницами.