UIButtons动态添加到UIScrollView不接收触摸

时间:2012-07-10 19:33:25

标签: ios uiscrollview uibutton

在我的应用程序中,我的功能允许用户打开包含所有应用程序页面缩略图的菜单,然后点击一个菜单,从而点击特定页面。它基本上是UIScrollView,我在其中添加UIButton以及每页的缩略图。

如果您在应用程序中间的某个页面上打开缩略图菜单,则效果非常好。但是,在许多情况下,打开缩略图菜单后,90%的scrollview按钮都不会接收到触摸。它通常发生在用户手动到达应用程序末尾,然后打开缩略图菜单时。

以下是代码:

@interface BookmarkManager : UIView{
    UIScrollView *thumbnailScrollView;
}
@property (strong) UIScrollView *thumbnailScrollView;


@implementation BookmarkManager

@synthesize thumbnailScrollView;

-(id)init{
    self = [super initWithFrame:CGRectMake(0, 0, 1024, 768)];
    if(self){
        [self setBackgroundColor:[UIColor clearColor]];

        thumbnailScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 1024, 120)];
        [thumbnailScrollView setBackgroundColor:[UIColor clearColor]];

        UIImageView *background = [[UIImageView alloc] initWithImage:[UIImage imageWithContentsOfFile:[NSString stringWithFormat:@"%@/thumbnail_background.png", [[NSBundle mainBundle] resourcePath] ]]];
        [self addSubview:background];

        for(int i = 0; i < totalPages; i++){

            UIButton *pageThumbnail = [UIButton buttonWithType:UIButtonTypeCustom];
            [pageThumbnail setFrame:CGRectMake(0, 0, 125, 95)];
            [pageThumbnail setImage:[UIImage imageWithContentsOfFile:[NSString stringWithFormat:@"%@/p%d_thumb.png", [[NSBundle mainBundle] resourcePath], i]] forState:UIControlStateNormal];

            pageThumbnail.titleLabel.text = [NSString stringWithFormat:@"%d",i];

            pageThumbnail.center = CGPointMake(20 + (i * pageThumbnail.frame.size.width) + (i * 20) +(pageThumbnail.frame.size.width/2), 60);

            [thumbnailScrollView addSubview:pageThumbnail];
            [pageThumbnail addTarget:self action:@selector(thumbnailTapped:) forControlEvents:UIControlEventTouchDown];

        }

        [self addSubview:thumbnailScrollView];
        [thumbnailScrollView setContentSize:CGSizeMake(totalPages * 125 + (20*(totalPages+1)), 120)];

    }

    return self;
}


-(void)thumbnailTapped:(id)sender{

    UIButton *thumbnailButton = sender;
    int pageNumber = [thumbnailButton.titleLabel.text intValue];

    NSLog(@"tapped thumbnail for page: %d", pageNumber);
    [bookmarkManagerDelegate jumpToPage:pageNumber];

}

我已尝试将userInteractionEnabled = YES设置为pageThumbnail,尝试thumbnailScrollView bringSubviewToFront:pageThumbnail,但这不起作用...按钮总是很好地显示,问题是有很多时候他们没有接触到触摸(即NSLog从不打印)......为什么会这样?

编辑: 我实现了UIScrollView's scrollViewDidEndDecelerating,它在模拟器上调用但从未在设备上调用。可能是我的按钮的图像太大了吗?

3 个答案:

答案 0 :(得分:1)

我在我的应用中做同样的事情。尝试使用setBackgroundImage而不是setImage:。这对我有用

答案 1 :(得分:1)

我过去做过类似的事情,唯一的区别是你将框架设置为按钮的方式。也许这就是问题

-(void)makeIconsView:(UIScrollView*)full :(NSArray*)images{
    int row=0;
    int column=0;
    for(int i = 0; i < images.count; ++i) {

        UIImage *thumb = [images objectAtIndex:i];
        UIButton * button = [UIButton buttonWithType:UIButtonTypeCustom];

        button.frame = CGRectMake(column*100+14, row*90+10, 84, 80);
        [button setImage:thumb forState:UIControlStateNormal];
        [button addTarget:self 
                   action:@selector(clickImage:) 
         forControlEvents:UIControlEventTouchUpInside];
        button.tag = i;
        button.layer.shadowColor = [UIColor colorWithWhite: 0.15 alpha: 0.55].CGColor;
        button.layer.zPosition = -8;
        button.layer.shadowOffset = CGSizeMake(0, 5);
        button.layer.shadowOpacity = 1;
        button.layer.shadowRadius = 2.0;
        button.clipsToBounds = NO;
        [full addSubview:button];

        if (column == 2) {
            column = 0;
            row++;
        } else {
            column++;
        }

    }

    [full setContentSize:CGSizeMake(320, (row+1) * 90 + 10)];   
}

答案 2 :(得分:0)

当我注意到scrollview的滚动动画在模拟器中非常流畅但在设备上很慢(iPad 3)时,我尝试实现UIScrollViewDelegate

在模拟器上,正在调用scrollViewWillBeginDeceleratingscrollViewDidEndDecelerating。在设备上,scrollViewWillBeginDecelerating被调用,但scrollViewDidEndDecelerating从未被调用过。

原因可能是,在设备上,滚动视图的处理过多,并且永远不会计算其内容的最终位置。因此,它会在完成动画和重新定位内容之前解除触摸。但是当内容很重时,这需要很长时间。

所以我的解决方案是在滚动视图开始减速时立即终止动画。我只是实现了这个:

-(void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView{
    CGPoint offset = scrollView.contentOffset;
    [scrollView setContentOffset:offset animated:NO];
}

this other StackOverflow answer提供。