Есть ли способ, чтобы убедиться, что только один экземпляр scrollView имеет scrollsToTop == YES?

Приложение, в котором я сейчас работаю, имеет несколько экземпляров UITableView / UIScrollView одновременно в нескольких разных сценах.

Когда несколько экземпляров имеют scrollsToTop == YES , только один экземпляр фактически прокручивается вверх, когда scrollsToTop == YES строка состояния.

Я ищу простое решение, чтобы убедиться, что только один экземпляр (последний) прокрутки имеет scrollsToTop == YES .

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

Вот мое решение:

  1. Создать метод добавления категорий UIScrollView mySetScroolsToTop:

     -(void)mySetScrollsToTop:(BOOL)scrollsToTop{ [self mySetScrollsToTop:scrollsToTop]; if(scrollsToTop){ [[NSNotificationCenter defaultCenter] postNotificationName:SetScrollsToTopNotification object:self]; } } -(void)scrollsToTopIsSet:(NSNotification *)notification{ if(notification.object != self){ [self mySetScrollsToTop:NO]; } } 
  2. Создайте категорию UIViewController со следующими методами

     -(void)myViewDidLoad{ self findScrollViewAndObserveScrollToTopNotification:self.view]; [self myViewDidLoad]; } -(void)findScrollViewAndObserveScrollToTopNotification:(UIView *)view{ for(UIView* v in view.subviews){ if([v isKindOfClass:[UIScrollView class]]){ [[NSNotificationCenter defaultCenter] addObserver:v selector:@selector(scrollsToTopIsSet:) name:kSetScrollsToTopNotification object:nil]; } [self findScrollViewAndObserveScrollToTopNotification:v]; } } -(void)myDealloc{ [[NSNotificationCenter defaultCenter] removeObserver:self]; [self myDealloc]; } 
  3. swap mySetScrollsToTop , myViewDidLoad и myDealloc с оригинальными, используя метод swizzling .

Редактировать:

Извините, если мой вопрос не ясен.

Каждый viewcontroller имеет несколько tableViews и они переключаются пользователем, например, с сегментированным tableViews управления. Когда tableView / scrollView , я хочу установить его scrollToTop = YES и хочу, чтобы все остальные scrollView scrollsToTop установлены в NO.

Приложение, над которым я работаю, покинуло панель меню, например приложение Facebook, в котором есть UITableView внутри, а также панель вкладок, каждая вкладка которой содержит UITableView которая отображается в меню UITableView . На правой панели также есть UITableView s, который можно выбрать и переключить с помощью сегментированного контроллера. Я хочу убедиться, что только один вид таблицы активен для scrollsToTop .

Edit2:

Я распечатал subview окна и не содержал мои взгляды:

 2013-05-16 10:44:01.416 UIView 2013-05-16 10:44:01.417 UILayoutContainerView 2013-05-16 10:44:01.417 UINavigationTransitionView 2013-05-16 10:44:01.417 UIView 2013-05-16 10:44:01.417 UILayoutContainerView 2013-05-16 10:44:01.417 UINavigationTransitionView 2013-05-16 10:44:01.417 UINavigationBar 2013-05-16 10:44:01.417 _UINavigationBarBackground 2013-05-16 10:44:01.417 UIImageView 2013-05-16 10:44:01.418 UIButton 2013-05-16 10:44:01.418 UIImageView 2013-05-16 10:44:01.418 UIImageView 

Edit3: Я реализовал swizzling, и он работает. Тем не менее, я все еще принимаю любое лучшее решение. Благодаря!

scrollsToTop умолчанию имеет значение YES для всех видов прокрутки.

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

 - (BOOL)scrollViewShouldScrollToTop:(UIScrollView *)scrollView { return (scrollView == <the only scroll view you want to scroll to the top>); } 

Когда верхняя панель будет scrollViewShouldScrollToTop: , scrollViewShouldScrollToTop: и вы должны вернуть YES для прокрутки, которую вы хотите прокрутить.

Изменить для обновленного вопроса:

Это сделает то, о чем вы просите.

 // Set `scrollsToTop` to false for every scroll view of every view controller for (UIViewController *controller in self.navigationController.viewControllers) for (id obj in controller.view.subviews) if ([obj isKindOfClass:[UIScrollView class]]) ((UIScrollView*)obj).scrollsToTop = NO; // Set `scrollsToTop` to true for whichever scroll view is currently visible activeScrollView.scrollsToTop = YES; 

Вы можете использовать следующие методы:

 - (void) disableScrollToTopExceptScrollView:(UIScrollView*) scrollView { [self internalDisableScrollViewsExceptScrollView:scrollView rootView:self.window]; } - (void) internalDisableScrollViewsExceptScrollView:(UIScrollView*) scrollView rootView:(UIView*) root { NSArray* subviews = root.subviews; for(UIView* view in subviews) { if([view isKindOfClass:[UIScrollView class]]) { if(view==scrollView) { [(UIScrollView*)view setScrollsToTop:YES]; } else { [(UIScrollView*)view setScrollsToTop:NO]; } } [self internalDisableScrollViewsExceptScrollView:scrollView rootView:view]; } } 

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

Давайте будем гением компьютера.