问题:UIScrollview 弹跳使父 UIScrollview 弹跳

Posted

技术标签:

【中文标题】问题:UIScrollview 弹跳使父 UIScrollview 弹跳【英文标题】:Problem : UIScrollview bouncing makes Parent UIScrollview bouncing 【发布时间】:2010-10-27 12:58:36 【问题描述】:

我在全屏 UIScrollview(A) 中有一个全屏 UIScrollview(B)。

A 有一个 contentsize = 横向页数

B 有一个 contentsize = 垂直子页数

在 B 内部,我有一个小的 UIscrollview (C),它的滚动方向与 B 相同......也是垂直的。

当 C 疯狂滚动时,它会在到达 contentSize 的末尾时产生硬弹跳效果。

问题:它还会在 B 上产生弹跳效果!!!!有没有办法在不抑制双方反弹效应的情况下抑制这种对父母和孩子之间反弹效应的污染。

谢谢

【问题讨论】:

当它开始弹跳时,您的手指是否在 C 之外(即在 B 中)? 运动从 C 开始,是的,当手指开始弹跳时,手指在 C 之外。为什么? 【参考方案1】:

Apple 文档警告不要进行类似设计。来自the docs:

重要提示:您不应在 UIScrollView 对象中嵌入 UIWebView 或 UITableView 对象。如果这样做,可能会导致意外行为,因为这两个对象的触摸事件可能会混淆和错误处理。

出于您发现的原因,我会将此警告扩展到嵌套的 UIScrollViews。

您可以通过大致执行移动 Safari 浏览器的操作来将其从嵌套的 A/B/C UIScrollViews 中提取出来。用户处于“网页选择”模式(您的 A&B 视图)或“查看网页”模式(您的 C 视图)。 Safari 自定义 WebView 控制器中的一个按钮允许用户从“查看网页”模式跳到“网页选择”模式,这是一个带有当前活动页面缩略图的 UIScrollView。

因此,在您的情况下,这意味着将 C 从嵌套的 UIScrollViews 中拉出,向 C 视图控制器添加一个按钮以呈现 A&B 视图控制器,并可能创建另一个控制器类将它们粘合在一起。

我还主张将 A&B 合并到一个 UIScrollView 中。

【讨论】:

【参考方案2】:

现在根据Apple ios Scroll View Programming Guide..

要创建丰富的用户体验,您可能需要在应用程序中嵌套滚动视图。在 iOS 3.0 之前,即使不是不可能,也很难做到这一点。在 iOS 3.0 中,完全支持此功能并自动运行。

所以嵌套滚动视图非常好> iOS 3。为了回答您的问题,我将滚动视图 C 作为子视图添加到“容器”UIView - 在将该容器视图添加到滚动视图 B 之前。似乎停止反弹拉动父滚动向下查看,尽管我确实必须非常用力快速滑动才能使其在没有容器视图的情况下表现出您所描述的行为。

@interface TiledScrollView : UIScrollView @end

@implementation TiledScrollView

- (id)initWithFrame:(CGRect)frame

    self = [super initWithFrame:frame];
    if(self)
    
        self.layer.borderColor = [UIColor whiteColor].CGColor;
        self.layer.borderWidth = 10.f;
    
    return self;


- (void)setContentSize:(CGSize)contentSize

    [super setContentSize:contentSize];

    BOOL horizontal = contentSize.width > self.frame.size.width;

    if(horizontal)
    
        CGFloat col = self.contentSize.width / 10.f;
        for (int i = 0; i < 10; i++)
        
            UIView * view = [[UIView alloc] initWithFrame:CGRectMake(i * col, 0, col, self.contentSize.height)];
            view.backgroundColor = [UIColor colorWithHue:(arc4random() % 100) / 100.f saturation:1.f brightness:1.f alpha:1.f];
            [self addSubview:view];
        
    
    else
    
        CGFloat row = self.contentSize.height / 10.f;
        for (int i = 0; i < 10; i++)
        
            UIView * view = [[UIView alloc] initWithFrame:CGRectMake(0, i * row, self.contentSize.width, row)];
            view.backgroundColor = [UIColor colorWithHue:(arc4random() % 100) / 100.f saturation:1.f brightness:1.f alpha:1.f];
            [self addSubview:view];
        
    


@end

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad

    [super viewDidLoad];

    CGRect bounds = [UIScreen mainScreen].bounds;
    TiledScrollView * A = [[TiledScrollView alloc] initWithFrame:CGRectMake(0, 0, bounds.size.width, bounds.size.height)];
    TiledScrollView * B = [[TiledScrollView alloc] initWithFrame:CGRectMake(0, 0, bounds.size.width, bounds.size.height / 2.f)];
    TiledScrollView * C = [[TiledScrollView alloc] initWithFrame:CGRectMake(0, 0, bounds.size.width, bounds.size.height / 4.f)];

    [A setContentSize:CGSizeMake(bounds.size.width * 4, bounds.size.height)];
    [B setContentSize:CGSizeMake(bounds.size.width, bounds.size.height * 4)];
    [C setContentSize:CGSizeMake(bounds.size.width, bounds.size.height * 4)];

    UIView * container = [[UIView alloc] initWithFrame:CGRectMake(0, 0, bounds.size.width, bounds.size.height / 4.f)];

    [container addSubview:C];
    [B addSubview:container];
    [A addSubview:B];
    [self.view addSubview:A];


@end

【讨论】:

以上是关于问题:UIScrollview 弹跳使父 UIScrollview 弹跳的主要内容,如果未能解决你的问题,请参考以下文章

放大时只允许 UIScrollView 缩放弹跳,不能缩小

拖动后取消 UIScrollView 弹跳

UIScrollView :仅向左水平分页,向右弹跳

允许 UIScrollView 滚动过去的内容而不弹跳

UIScrollView 帮助

UIScrollView 内的可选 UITableViewCells