Подтвердить что ты не робот

Вложенные UIScrollViews и маршрутизация событий

У меня есть 2 вида прокрутки, оба из которых должны прокручиваться по вертикали. Внешний вид прокрутки (красный) содержит панель поиска и внутренний вид прокрутки (синий). Предполагается, что внутренняя прокрутка прокручивается бесконечно (она содержит изображения/элементы и имеет бесконечную реализацию прокрутки).

Способ, которым я хочу, чтобы этот контроллер работал, выглядит следующим образом:

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

Если я просто вложил их в IB без каких-либо изменений, внутренний просмотр прокрутки поймает все события прокрутки, и он работает наоборот.

Пожалуйста, имейте в виду, что я использую внутренний вид прокрутки в качестве упрощающей метафоры здесь. В моем приложении у меня есть элемент управления, в котором есть вид прокрутки с вложенными представлениями таблицы (просмотр прокрутки позволяет мне горизонтально, представления в таблице позволяют мне прокручивать по вертикали).

enter image description here

4b9b3361

Ответ 1

Если вы в состоянии, установите общий UIScrollViewDelegate на 2 представления прокрутки и выполните следующее:

- (void) scrollViewDidScroll: (UIScrollView*) scrollView
{
  if (scrollView == self.mainScrollView)
  {
    /* Handle instances when the main scroll view is already at the bottom */
    if (   scrollView.contentOffset.y
        == scrollView.contentSize.height - scrollView.bounds.size.height)
    {
      /* Stop scrolling the main scroll view and start scrolling the
       * inner scroll view
       */
      self.innerScrollView.scrollEnabled = YES;
      self.mainScrollView.scrollEnabled = NO;
    }
    else
    {
      /* Start scrolling the main scroll view and stop scrolling the
       * inner scroll view
       */
      self.innerScrollView.scrollEnabled = NO;
      self.mainScrollView.scrollEnabled = YES;
    }
  }
  else if (scrollView == self.innerScrollView)
  {
    /* Handle instances when the inner scroll view is already at the top */
    if (self.innerScrollView.contentOffset.y == 0)
    {
      /* Stop scrolling the inner scroll view and start scrolling the
       * main scroll view
       */
      self.innerScrollView.scrollEnabled = NO;
      self.mainScrollView.scrollEnabled = YES;
    }
    else
    {
      /* Start scrolling the inner scroll view and stop scrolling the
       * main scroll view
       */
      self.innerScrollView.scrollEnabled = YES;
      self.mainScrollView.scrollEnabled = NO;
    }
  }
}

Обратите внимание, что я не тестировал это, но логика может быть примерно такой (либо вы включили прокрутку, либо отключили взаимодействие с пользователем, или что-то еще). Скорее всего, этого будет недостаточно, как вам хотелось бы, но я уверен, что общий UIScrollViewDelegate - это решение вашей проблемы.

Ответ 2

Я привел пример для одного прокрутки, что вам нужно создать onemore scrollview и добавить на основе динамической высоты и размера содержимого, которые будут работать.

//.h файл

@property (nonatomic, strong) UIScrollView *scrlSearch;

//.m Файл //ViewDidLoad

scrlSearch = [[UIScrollView alloc] init];

// For first scroll screen height was ((total screen height / 100 )* 10% )
// For Second scroll screen height was ((total screen height / 100 )* 90% )
scrlSearch.frame = CGRectMake(0, 0, (YourScreenWidth), (YourScreenHeight));

// YourVIEW = add any view to scrollbar
[scrlSearch addSubview:YourVIEW];

CGSize contentSize = scrlSearch.frame.size;
// YourContentHeight = dynamic content or static content height
contentSize.height = YourContentHeight;

// set the ContentHeight for scrolling
[scrlSearch setContentSize:contentSize];
// add the scrollview into delegate
[scrlSearch setDelegate:self];

Ответ 3

Используйте только один scrollView и настройте contentInset/contentOffset для панели поиска. Что-то по этой линии:

  UIEdgeInsets oldEdgeInset = [[self scrollView] contentInset];
  CGRect f = [[self searchBar] frame];
  UIEdgeInsets newEdgeInset = UIEdgeInsetsMake(CGRectGetMaxY(f), 0, 0, 0);
  CGPoint offset = [[self scrollView] contentOffset];
  offset.y += oldEdgeInset.top - newEdgeInset.top;
  [[self scrollView] setContentOffset:offset];
  [[self scrollView] setContentInset:newEdgeInset];
  [[self searchBar] setFrame:f];

Ответ 4

Я не уверен в структуре, которую вы имеете и хотите реализовать.

Я сделал тестовый проект, чтобы найти здесь

Но проект определенно поможет вам управлять различными списками прокрутки вместе.

Приложение может быть не совсем идеальным, но даст вам некоторую идею для решения.

Надеюсь, что это поможет.

Приветствия

Ответ 5

Вы должны добавить внутренний scrollview на внешнем scrollview, но внутренняя позиция прокрутки 'y' должна содержать контент внешнего scrollview, например...

innerScrollView.frame = CGRectMake(10, outerScrollView.contentSize.height, 300, 440);

После этого вы можете добавить любое представление в этот innerScrollView, вы можете установить contentOffset и т.д. для innerScrollView.

Наконец, вы должны увеличить contentSize для внешнего scrollview.

outerScrollView.contentSize = CGSizeMake(320, innerScrollView.frame.size.height+actualContentSizeOfOuterScroolView);

Я думаю, это помогает вам!

Ответ 6

Создайте признак распознавания жестов в вашем самом верхнем виде (прежде всего просмотры прокрутки, на вашем представлении контроллера) и узнайте UISwipeGestureRecognizerDirectionUp.

Затем вам нужно уведомить своего контроллера, когда прокручивается внешний вид прокрутки. После прокрутки вниз добавьте распознаватель жестов. Когда он снова попадает в верхнюю часть (outerScrollView.contentOffset == (0,0)), удалите распознаватель жестов.

Жест должен "съедать" все события прокрутки во время его присутствия, заставляя ваши внутренние прокрутки просматривать не получать события касания и, следовательно, не будет прокручивать