【问题标题】:scrollViewDidScroll method not giving reference to all scrollviews from table viewscrollViewDidScroll 方法未引用表视图中的所有滚动视图
【发布时间】:2013-12-29 12:44:39
【问题描述】:

我已经使用包含图像视图和滚动视图的自定义单元格创建了 tableView。所有滚动视图都包含比屏幕边界更宽的标签,因此当我向左/向右滚动时,我希望所有滚动视图都向同一方向滚动。问题是我不知道如何在 scrollViewDidScroll 方法中获取对每个 scrollView 的引用。

我的 viewController 类:

#import "EPGViewController.h"

@interface EPGViewController (){
    NSArray *EPGList;
    int scrollPositionX;
}

@end

@implementation EPGViewController


- (void)viewDidLoad
{
    [super viewDidLoad];
    self.navigationController.navigationBarHidden = false;

    EPGList = [NSMutableArray arrayWithObjects:@"1",@"2",@"3",@"4",@"5",@"6",@"7",@"8",@"9",@"10",@"11",@"12", nil];
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    return EPGList.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *hlCellID = @"EPGCell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:hlCellID];
    if(cell == nil) {
        cell =  [[UITableViewCell alloc]
               initWithStyle:UITableViewCellStyleDefault reuseIdentifier:hlCellID];
        cell.accessoryType = UITableViewCellAccessoryNone;
        cell.selectionStyle = UITableViewCellSelectionStyleNone;
    }
    UILabel *label = (UILabel *)[cell viewWithTag:15];
    label.text = EPGList[indexPath.row];

    UIScrollView *scrolView = (UIScrollView *)[cell viewWithTag:16];
    scrolView.backgroundColor = [UIColor colorWithRed:1.0 green:0.0 blue:0.0 alpha:1.0];
    scrolView.delegate = self;
    scrolView.tag = indexPath.row+101;
    scrolView.scrollEnabled = YES;
    scrolView.contentSize = CGSizeMake(scrolView.frame.size.width,scrolView.frame.size.height);
    [scrolView setShowsHorizontalScrollIndicator:NO];
    [scrolView setShowsVerticalScrollIndicator:NO];

    int i=0;
    for(i=0;i<15;i++){
        UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0+i*100, 0, 100, 100)];
        label.text = @"HELLO";
        label.textColor = [UIColor blackColor];
        label.backgroundColor = [UIColor clearColor];
        label.textAlignment = NSTextAlignmentCenter;
        label.font = [UIFont fontWithName:@"ArialMT" size:18];
        [scrolView addSubview:label];
        scrolView.contentSize =    CGSizeMake(scrolView.frame.size.width+i*label.frame.size.width,scrolView.frame.size.height);
    }
    [cell addSubview:scrolView];
    return cell;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
    return 80.0;
}

- (void)scrollViewDidScroll:(UIScrollView *)callerScrollView {
    scrollPositionX = callerScrollView.contentOffset.x;

    //if this is called with table view exit
    if (callerScrollView == self.tableView) return;

    int indexPath = callerScrollView.tag-101;
    NSLog(@"TAG: %d",indexPath);

    for (UITableViewCell *cell in self.tableView.visibleCells) {
        //TODO: Don’t use tags.
        UIScrollView *cellScrollView = (UIScrollView *)[cell viewWithTag:16];
        if (callerScrollView == cellScrollView) continue;

        cellScrollView.contentOffset = CGPointMake(scrollPositionX, 0);
    }
}


@end

编辑:

我设法通过删除向表格视图中的滚动视图添加不同标签的行来解决我的问题。现在我只是将偏移量设置为带有标签 16 的滚动视图。

【问题讨论】:

  • 你在哪个类中定义scrollViewDidScroll?
  • 在控制表格视图的 viewController 中。 UIScrollViewDelegate 包含在 .h 文件中。

标签: ios iphone ipad uitableview uiscrollview


【解决方案1】:

你应该使用 [tableView visibleCells];以获取此时可见的所有单元格。

【讨论】:

  • 我试过了,但是 visibleCells 数组返回我为零。查看我的编辑。
  • [self.tableView visibleCells];返回零?你能把你的代码上传到git上吗?我对此有点好奇。
  • 我添加了整个 .m 文件以及 iMartin 给我的建议。
  • 不,滚动视图没有更新。
【解决方案2】:

您可以使用 UITableViewvisibleCells 方法来获取所有可见单元格并从那里获取您的滚动视图(您可以像您一样使用 viewwithTag做,但在所有单元格上)。

然后您必须记住在重用/重新创建单元格时调整滚动视图位置 - 可能将滚动偏移量保留为视图控制器的属性。

【讨论】:

  • 我根据您的建议编辑了我的帖子,但我仍然没有在其他单元格上移动。难道我又做错了什么?
【解决方案3】:

问题在于您使用的是 dequeueReusableCellWithIdentifier 而不是循环遍历已显示的单元格。

执行以下操作:

for (NSInteger j = 0; j < [tableView numberOfSections]; ++j)
{
    for (NSInteger i = 0; i < [tableView numberOfRowsInSection:j]; ++i)
    {
       if (!(indexPath.section == j && indexPath.row == i))
{
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:i inSection:j]]]; 
    UIScrollView *scrollView = (UIScrollView *)[cell viewWithTag:16]; 
    scrollView.contentOffset = CGPointMake(position_x, scrollView.frame.size.height);
}
    }
}

【讨论】:

  • 或者按照其他答案中的建议遍历从 [tableView visibleCells] 获得的数组。无论你做什么,都不要出队!
  • 我已经尝试过了,但是其他单元格没有更新。在你建议的这段代码之后,我刚刚添加了[self.tableView reloadData];
【解决方案4】:

您的代码中有多个错误的地方。这是更好的实现:

- (void)scrollViewDidScroll:(UIScrollView *)callerScrollView {
    scrollPositionX = callerScrollView.contentOffset.x;

    if (callerScrollView == self.tableView) return;

    for (UITableViewCell *cell in self.tableView.visibleCells) {

        //TODO: Don’t use tags.
        UIScrollView *cellScrollView = (UIScrollView *)[cell viewWithTag:16];
        if (callerScrollView == cellScrollView) continue;

        cellScrollView.contentOffset = CGPointMake(scrollPositionX, 0);
    }
}

一些补充说明:

  • 这个方法也会被表格视图调用,所以你必须检查一下。
  • 不要使用任何索引,只是简单的迭代。
  • 我使用了滚动视图检查,但基本上没有它就可以了。
  • 使用标签来识别子视图不是一个好主意。
  • 不要每次都给reloadData打电话!

【讨论】:

  • 例如,我在表格视图数组中有 10 个元素,所以我在表格单元格中为滚动视图添加了 10 个不同的标签。如何在没有标签的情况下访问这 10 个单元格?我必须仅在我没有拖动的单元格(其中 9 个)上更新 contentOffset。没有标签如何识别它们?
  • 所以你有 10 个单元格,每个单元格都有一个滚动视图?您可以更新所有 10 个滚动视图的 contentOffset,它对您拖动的那个没有影响。您可以将x 设置为x。然后通常,您将UITableViewCell 子类化并创建属性以访问内部视图。或者甚至更好,例如,您只创建方法 -updateXOffsetTo:
  • 我发现了我的错误!我不需要为每个滚动视图添加另一个标签,只需设置标签 16 就足够了,现在一切正常!
  • visibleCells 的问题是,当我向下滚动列表时,其他单元格不是我需要的那样,并且正确的单元格在滚动视图开始时被重置。有什么建议吗?
  • 您可能正在tableView:cellForRowAtIndexPath: 中重置它们。您应该熟悉单元格重用。在您的 tableView 中,任何时候只有很少的单元格处于活动状态,并且它们保持不变。如果你想影响所有个单元格,你需要影响可见单元格和在tableView:cellForRowAtIndexPath:中创建的那些。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-30
  • 1970-01-01
  • 2017-05-04
相关资源
最近更新 更多