UIScrollView 实现委托

Posted

技术标签:

【中文标题】UIScrollView 实现委托【英文标题】:UIScrollView implementing a delegate 【发布时间】:2011-04-20 19:49:24 【问题描述】:

我有一个视图控制器,它具有三个滚动视图作为子视图。我想让子滚动视图在页面发生更改时通知父视图控制器。

我想我会通过设置委托模式来做到这一点。我的孩子(UIScrollView 的子类)在头文件中设置:

@interface TriptychScrollView : UIScrollView <UIScrollViewDelegate> 
    id delegate;


- (id)delegate;
- (void)setDelegate:(id)newDelegate;
@end

@protocol RCScrollDidChange
@optional
- (void)scrollView:(TriptychScrollView *)scrollView imageDidChange:(NSNumber *)index;
@end

源文件具有委托访问器方法:

- (id)delegate 
    return delegate;

- (void)setDelegate:(id)newDelegate 
    delegate = newDelegate;

不幸的是,这意味着我将代理设置为自我调用被忽略:

- (id)initWithFrame:(CGRect)frame 
    self = [super initWithFrame:frame];
    if (self) 
        [self setDelegate:self];
    
    return self;

.. 因此scrollViewDidScroll:scrollViewDidEndDecelerating: 这两个方法没有被调用!这意味着我实际上已经失去了对滚动视图的控制。

我做错了吗?或者有没有更好的方式让子子视图将消息发回给他们的父母?

【问题讨论】:

三个滚动视图都有自己的控制器实例吗?为什么将“自我”设置为代表?通常你会让父母创建孩子并将自己设置为委托。 【参考方案1】:

我可能不理解整个问题,但我看不出实现您自己的 UIScrollView 子类的原因,如果您坚持这样做,请不要隐藏它的 .delegate 属性或确保并调用 super。

我会通过以下方式来解决这个问题:

假设所有这些滚动视图都包含在其他视图中;

UIScrollView *a = ....
a.delegate = self;
a.tag = 1;

UIScrollView *b = ....
b.delegate = self;
b.tag = 2;

UIScrollView *c = ....
c.delegate = self;
c.tag = 3

- (void)scrollViewDidScroll:(UIScrollView *)scrollView 
   if (scrollView.tag == 1) 
     //handle a
   else if (scrollView.tag == 2)
     //handle b
   else if (scrollView.tag == 3)
     //handle c

【讨论】:

1) 为什么我要继承 UIScrollView? 这是一个相对复杂的类,只有三个 UIView 声明了在无限循环中显示许多图像。这一切都可以在视图控制器中完成,但这样我就不必多次说if (scrollView.tag == 1) else if (scrollView == 2) else .. 2) 是的,(现在)显而易见的答案是父视图控制器应该是委托,而不是子滚动视图。这使一切工作变得轻松。谢谢,也感谢 Jagostoni

以上是关于UIScrollView 实现委托的主要内容,如果未能解决你的问题,请参考以下文章

何时使用 UITouch 与 UIScroll

UIScrollView 实现委托

调整容器 uiscrollview 中所有 uiscrollview 的大小

滚动发生时嵌套 UIScrollViews 并获取信息

UIScroll 及其嵌套元素

带有 AutoLayout 的 UIScrollView 灵活布局