Передача прикосновений от UIView к базовому UIScrollView для правильной прокрутки - PullRequest
6 голосов
/ 04 марта 2011

У меня есть ситуация, похожая на эти два поста ( 1907297 И 689684 ), и чтобы описать мою ситуацию максимально кратко, я представляю этот текст / графический макет (аналогично тому, что высм. в IB точки, используемые для обеспечения уровней отступа)

UIView (MainView: 320x460)
..UIScrollView (ScrollView: 320x460)
..UIView (OverlayView: 320x40)
.,,.UIButton (ArbitraryButton1)
.,,.UILabel (ArbitraryLabel1)
.,,.UILabel (ArbitraryLabel2)

Здесь цель состоит в том, чтобы OverlayView служил в качестве единого прозрачного контейнера для позиционирования и отображения некоторых произвольных кнопок / надписей поверх ScrollView.Эти кнопки / надписи должны оставаться неподвижными, пока содержимое в ScrollView внизу перемещается с помощью пользовательских движений.Кнопки / метки иногда могут быть скрыты / не скрыты / масштабированы в унисон (с анимацией), что делает их удобными для группировки их в единый OverlayView.

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

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event

в OverlayView, однако я пока не нашел способа правильно передать их в ScrollView таким образом, чтобы он прокручивался.Очевидно, что метод touchesMoved - это не то, что UIScrollView использует для обнаружения / интерпретации свайпов?

Все другие подобные посты, которые я исследовал, либо нашли другое решение, которое не сработало бы в моем случае, либо просто не решены.Я также видел упоминание об использовании touchShouldBegin / touchesShouldCancel, хотя я не понимаю, как это будет реализовано.В любом случае, мы все еще надеемся, что сообщество получит некоторую информацию, которая позволит мне найти элегантное решение для этого - любой пример кода будет фантастическим.

Заранее спасибо, Джоэл.

PS - Я должен также упомянуть, что мне нужно сделать это совместимым с iOS 3.0, так что я думаю, что попытка использовать UIGestureRecognizer закончилась.

Ответы [ 4 ]

1 голос
/ 15 июля 2013

Вот более простые решения, которые хорошо сработали для меня:

В OverlayView (вид сверху UIScrollView) задайте для ширины и высоты значение 0 (чтобы представление больше не находилось на вершине прокрутки), и установите clipsToBounds = NO (чтобы содержимое OverlayView до сих пор появляются в верхней части прокрутки). Это сработало как обаяние для меня.

 self.OverlayView.clipsToBounds = NO;
 CGRect frame = self.OverlayView.frame;
 self.OverlayView.frame = CGRectMake(frame.origin.x, frame.origin.y, 0, 0);

Обратите внимание, что если OverlayView содержит интерактивные элементы управления (как кнопка выше), то они больше не будут работать. Вам нужно переместить его в собственное представление над UIScrollView.

0 голосов
/ 22 октября 2013

Мне нужно было нечто подобное, и после некоторых исследований и прочтения документации Apple я создал эту действительно простую и безопасную библиотеку с открытым исходным кодом, которая решит вашу проблему (MobileJoel). Демонстрационный проект использует scrollview, поэтому он напрямую связан с:
https://github.com/natrosoft/NATouchThroughView

Итак, ваша иерархия представлений будет выглядеть так:

UIView (MainView: 320x460)    
. .UIScrollView (ScrollView: 320x460)
. .UIView (OverlayView: 320x40)  --> change this view to class NARootTouchThroughView in I.B.
. . . .UIView (transparent UIView that you change to class NATouchThroughView in I.B.)
. . . .UIButton (ArbitraryButton1)
. . . .UILabel (ArbitraryLabel1)
. . . .UILabel (ArbitraryLabel2)

Таким образом, в основном ваш оверлейный вид будет пересылать свои штрихи под ним, которые затем будут получены UIScrollview. Если ваши UILabels огромны и перехватывают касания, поместите поверх них еще один NATouchThroughView, чтобы конечный результат выглядел следующим образом:

UIView (MainView: 320x460)    
. .UIScrollView (ScrollView: 320x460)
. .NARootTouchThroughView (OverlayView: 320x40)
. . . .NATouchThroughView (transparent)
. . . .UIButton (ArbitraryButton1)
. . . .UILabel (ArbitraryLabel1)
. . . .UILabel (ArbitraryLabel2)
. . . .NATouchThroughView (transparent and covers the labels but not the UIButton)
0 голосов
/ 10 января 2013

Вы должны создать подкласс UIScrollView и переопределить touchesShouldCancelInContentView: метод

-(BOOL)touchesShouldCancelInContentView:(UIView *)view
{

    if ([view isKindOfClass:[UIButton class]]) {//or whatever class you want to be able to scroll in
        return YES;
    }

    if ([view isKindOfClass:[UIControl class]]) {
        return NO;
    }

    return YES;
}
0 голосов
/ 13 марта 2011

Как насчет того, чтобы во время выполнения в viewDidLoad вы вынимали кнопки из представления контейнера и помещали их в представление как подпредставления напрямую (и избавлялись от представления контейнера)? Тогда нет представления контейнера для перехвата свайпов, но вы все равно можете использовать представление для группировки вещей в IB.

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

Также, если содержащее представление является визуальным контейнером, и вам нужно его увидеть, вы можете вместо этого использовать CALayer, который был помещен в суперпредставление поверх CALayer, для рендеринга представления прокрутки, поскольку CALayers не имеет ничего общего с вводом и не каждый прикасается.

...