有什么方法可以确保只有一个scrollView实例有scrollsToTop == YES?

时间:2013-05-15 23:32:12

标签: ios objective-c

我目前正在处理的应用在多个不同的场景中同时有多个UITableView / UIScrollView个实例。

当多个实例具有scrollsToTop == YES时,只有一个实例在点击状态栏时实际滚动到顶部。

我正在寻找最简单的解决方案,以确保只有一个实例(最近的一个)滚动视图具有scrollsToTop == YES

我想出了一个使用方法调整的解决方案,我不确定,如果它是最佳解决方案。我想知道解决这个问题的任何其他方法或任何建议。

这是我的解决方案:

  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. 使用方法调配mySetScrollsToTopmyViewDidLoadmyDealloc与原始版本交换。

  4. 修改

    很抱歉,如果我的问题不明确。

    每个viewcontroller都有多个tableViews,并且用户可以切换它们,例如使用分段控件。选择tableView / scrollView后,我想设置其scrollToTop = YES,并希望确保所有其他scrollView的{​​{1}}设置为NO。

    我正在处理的应用程序已离开菜单栏,如Facebook应用程序,其内部有scrollsToTop,还有一个标签栏,每个标签包含UITableView,显示在菜单UITableView上1}}。在右侧窗格中,还有UITableView个,可以使用分段控制器进行选择和切换。 我想确保UITableView只有一个表视图处于活动状态。

    EDIT2:

    我打印出窗口的子视图,但不包含我的观点:

    scrollsToTop

    EDIT3: 我实施了调配,它的工作原理。但是,我仍然接受任何更好的解决方案。 谢谢!

2 个答案:

答案 0 :(得分:3)

所有滚动视图的

scrollsToTop默认为YES

使您的视图控制器成为所有滚动视图的委托,然后实现:

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

点击顶栏时,将调用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;

答案 1 :(得分:1)

您可以使用以下方法:

- (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];
    }
}

E.g。在AppDelegate类中实现它们,并从应用程序中的任何位置进行调用 - 这将禁用应用程序视图层次结构中除所传递的视图之外的所有滚动视图。