繁体   English   中英

滚动UITableView和UICollectionView时数据不正确

[英]Incorrect data on scrolling UITableView and UICollectionView

我已经将示例项目与github附加在一起,并在下面提供了链接

我有一个表格视图,在该表格视图中,单元格由一个UICollectionView组成。 这意味着每个单元格都可以水平滚动到特定限制,例如5。

tableView单元格和collectionview单元格都具有自定义单元格类

tableview单元格还有一个UIPageControl,当我们水平滚动UICollectionViewCells时,它将发生变化

我设法完成了这部分工作,但是假设我已经将第二个表格单元格的collectionview滚动到了第3个位置,并且在第9个表格单元格上重复了一些。
第9个Tableview单元格也具有相同的数据。 但是我9号还没有设置任何东西。
因此,这意味着问题在于可重用性和滚动时数据不正确。

到目前为止,我的代码是

//ViewController.h
#import <UIKit/UIKit.h>

@interface ViewController : UIViewController<UITableViewDataSource,UITableViewDelegate,UICollectionViewDataSource,UICollectionViewDelegate,UICollectionViewDelegateFlowLayout>
@property (weak, nonatomic) IBOutlet UITableView *tableView;

@end

实现类

//ViewController.m
#import "ViewController.h"
#import "MyCollectionViewCell.h"
#import "MyTableViewCell.h"
@interface ViewController ()
{
    MyTableViewCell* tableViewCell;
}
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

}


#pragma mark TableView Delegates
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:    (NSInteger)section{
    return 10;
}

-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{

   tableViewCell=(MyTableViewCell*)[tableView dequeueReusableCellWithIdentifier:@"MyTableViewCell"];
    if(tableViewCell==nil)
    {
        tableViewCell=[[MyTableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"MyTableViewCell"];
    }

    UICollectionViewFlowLayout *flowLayout =   

 [[UICollectionViewFlowLayout alloc] init];
[flowLayout setScrollDirection:UICollectionViewScrollDirectionHorizontal];
    [flowLayout setMinimumInteritemSpacing:0.0f];
    [flowLayout setMinimumLineSpacing:0.0f];
    [tableViewCell.collectionView setPagingEnabled:YES];
    [tableViewCell.collectionView setCollectionViewLayout:flowLayout];
    [tableViewCell.collectionView setBackgroundColor:[UIColor whiteColor]];
    tableViewCell.pageControl.tag=indexPath.row;
    tableViewCell.collectionView.tag=indexPath.row;
    NSLog(@"Index path row %ld",indexPath.row);
    [tableViewCell setSelectionStyle:UITableViewCellSelectionStyleNone];
tableViewCell.path=indexPath;

    return tableViewCell;
}

#pragma mark CollectionView Delegates

-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{

    return 5;
}

-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
     MyCollectionViewCell* cell=(MyCollectionViewCell*)[collectionView dequeueReusableCellWithReuseIdentifier:@"MyCollectionViewCell" forIndexPath:indexPath];
    if(cell==nil)
    {
        cell=[[MyCollectionViewCell alloc]initWithFrame:CGRectMake(0, 0, collectionView.frame.size.width, collectionView.frame.size.height)];
    }
    [cell.myLabel setText:[NSString stringWithFormat:@"%ld",(long)indexPath.row]];
    return cell;
}

-(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
    return collectionView.frame.size;
}
-(UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout: (UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section{
    return UIEdgeInsetsMake(0, 0, 0, 0);
}

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{


    if ([scrollView isKindOfClass:[UICollectionView class]])
    {
        UICollectionView *mainCollection = (UICollectionView *) scrollView;

        NSIndexPath *myIP = [NSIndexPath indexPathForRow:mainCollection.tag inSection:0];

        MyTableViewCell *cell = (MyTableViewCell *)[self.tableView cellForRowAtIndexPath:myIP];

        CGRect visibleRect = (CGRect){.origin = mainCollection.contentOffset, .size = mainCollection.bounds.size};
        CGPoint visiblePoint = CGPointMake(CGRectGetMidX(visibleRect), CGRectGetMidY(visibleRect));
        NSIndexPath *visibleIndexPath = [mainCollection indexPathForItemAtPoint:visiblePoint];
        NSLog(@"visibleIndexPath %ld",(long)visibleIndexPath.row);


        [cell.pageControl setCurrentPage:visibleIndexPath.row];
    }

}



@end

细胞类

//MyTableViewCell.h

#import <UIKit/UIKit.h>

@interface MyTableViewCell : UITableViewCell
@property (weak, nonatomic) IBOutlet UICollectionView *collectionView;
@property (weak, nonatomic) IBOutlet UIPageControl *pageControl;
@property (strong, nonatomic) NSIndexPath * path;
@end

MyCollectionViewCell.h

 //MyCollectionViewCell.h
#import <UIKit/UIKit.h>

@interface MyCollectionViewCell : UICollectionViewCell
@property (weak, nonatomic) IBOutlet UILabel *myLabel;

@end

视图就像

在此处输入图片说明

我担心的是,每当我进行任何更改时,请在表viewcell的单元格1上说并滚动其中的集合以使它说第二个索引,那么每当我滚动整个表时都会重复此操作

注意:我将表的单元格数保持为10,以查看重复的影响。
我的示例项目的Github链接是https://github.com/RajanMaheshwari/TableAndCollection

首先:

[collectionView dequeueReusableCellWithReuseIdentifier:@"MyCollectionViewCell" forIndexPath:indexPath]

总是返回视图,因此您不需要:

if(cell==nil)
{
    cell=[[MyCollectionViewCell alloc]initWithFrame:CGRectMake(0, 0, collectionView.frame.size.width, collectionView.frame.size.height)];
}

因为那不会发生。

而且,真正的原因是所有UITableView都只有一个单元格...将tableCell保留为属性的想法从何而来?

    MyTableViewCell* tableViewCell;

您需要分别为每个indexPath创建一个单元实例,现在您有一个实例显示多次,这就是为什么更改其中一个的集合视图页面会影响其他行的原因-因为它是同一对象(视图)。

消除该问题之后,您需要记住元素将被重用-这意味着您的第一个行实例将在屏幕上消失后在第5行再次被重用,因此在使元素出队后,需要设置所有此行的变量。 您不能将变量保留在此行中,因为它将被重用,因此即使您有100行,您也将在整个表中重用5-6个实例(取决于行高)。

您需要在视图外部保留渲染每一行所需的重要变量,并根据这些变量配置视图。

在您的情况下,应为每行保留pageControl的页面索引-为此,请使用NSDictionary,并为UITableView中的每个indexPath保留一个NSNumber。 每当页面更改时,都更新此NSDictionary中的值(默认为零)。 当您创建具有集合视图的单元格时,请根据您在NSDictionary中为此indexPath所拥有的内容为pageControl设置适当的值

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM