【问题标题】:How to make multiple UITableViewCells communicate/interact with each other?如何使多个 UITableViewCells 相互通信/交互?
【发布时间】:2012-03-04 05:19:04
【问题描述】:

UITableview 中有几个单元格,每个单元格都有自己的 UIScrollView。当用户在其中一个单元格中滚动时,我希望所有其他单元格都跟随。有没有办法通过将contentOffset 传递给其他单元格来创建这种交互?

我正在考虑委派,但到目前为止我无法让它发挥作用。有什么想法吗?

【问题讨论】:

    标签: iphone ios uitableview delegates uiscrollview


    【解决方案1】:

    这其实很简单。只需在 viewController 中实现 UIScrollViewDelegate 方法 scrollViewDidScroll: 并在那里设置所有其他单元格的 contentOffset。让你的 viewController 成为每个单元格中滚动视图的代表,你就完成了。

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        static NSString *CellIdentifier = @"MyFancyCell";
        MyFancyCell *cell = (MyFancyCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
        cell.scrollView.delegate = self; // actually you would do this in the storyboard or inside (cell == nil) if you don't use storyboard
        // configure cell    
        return cell;
    }
    
    - (void)scrollViewDidScroll:(UIScrollView *)scrollView 
    {
        if (scrollView == self.tableView) {
            // each tableView is a UIScrollView too. 
            // they will call this method which will lead to strange results if you change your cells scrollView.
            // just ignore the scroll events of the tableView
            return;
        }
        CGPoint contentOffset = scrollView.contentOffset;
        for (MyFancyCell *cell in [self.tableView visibleCells]) {
            cell.scrollView.contentOffset = contentOffset;
        }
    }
    

    编辑: 您可以将委托调用转发回单元格,如下所示:

    for (MyFancyCell *cell in [self.tableView visibleCells]) {
        cell.scrollView.contentOffset = contentOffset;
        [cell scrollViewDidScroll:cell.scrollView];
    }
    

    或恕我直言更好的方式。使 viewController 成为单元格的委托,并在单元格内的 scrollViewDidScoll 方法中告诉委托 (viewController) contentOffset 已更改,以便视图控制器更新单元格。

    // MyFancyCell.h
    @protocol MyFancyCellDelegate 
    - (void)fancyCell:(MyFancyCell *)cell didChangeContentOffset:(CGPoint)offset;
    @end
    @property (weak, nonatomic) id <MyFancyCellDelegate> delegate;
    
    // MyFancyCell.m
    
    - (void)scrollViewDidScroll:(UIScrollView *)scrollView {
         // do your work here
         [self.delegate fancyCell:self didChangeContentOffset:scrollView.contentOffset];
    }
    
    // ViewController.m
    
    - (void)fancyCell:(MyFancyCell *)cell didChangeContentOffset:(CGPoint)offset {
        for (MyFancyCell *cell in [self.tableView visibleCells]) {
            cell.scrollView.contentOffset = offset;
        }
    }
    
    
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        static NSString *CellIdentifier = @"MyFancyCell";
        MyFancyCell *cell = (MyFancyCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
        cell.delegate = self;
        // configure
    }
    

    【讨论】:

    • 这行得通,唯一的问题是我需要让 UITableViewCell 成为滚动视图的代表。我知道一个对象不能有 2 个委托,所以您是否建议通过我的 viewController 在每个 cell 上再次调用委托方法?
    • 我进行了编辑以显示两种可能的方式。第二种方式可能更简洁,因为您不必将所有委托方法转发到单元格。
    【解决方案2】:

    您可以在cellForRowAtIndexPath 委托方法中的单元格之间进行同步。对于一个单元格的任何变化,你可以调用tableView的reloadData,或者调用reloadRowsAtIndexPath方法只重新加载选中的单元格。

    【讨论】:

      【解决方案3】:

      代表团将是完美的。您可以将内容偏移量传递给每个表格视图,并让它们都成为彼此的代表(请记住,.h 中的 #importing 有时会创建无限循环,因此只需在 .m 文件中创建类别并执行 #importing那里)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-03-22
        • 2011-06-21
        相关资源
        最近更新 更多