Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/39.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone 调用setCollectionViewLayout:animated不会重新加载UICollectionView_Iphone_Objective C_Uicollectionview - Fatal编程技术网

Iphone 调用setCollectionViewLayout:animated不会重新加载UICollectionView

Iphone 调用setCollectionViewLayout:animated不会重新加载UICollectionView,iphone,objective-c,uicollectionview,Iphone,Objective C,Uicollectionview,我将UICollectionView与两个自定义布局一起使用,它们是从UICollectionViewFlowLayout 首次加载视图时,我使用以下命令将其设置为默认视图: [self.collectionView setCollectionViewLayout:self.tableViewLayout]; 这将调用:cellForItemAtIndexPath——因此没有问题。这在视图中将出现方法中 然后我使用UIButton将布局从当前视图更改为下一个布局,如下所示: -(void)ch

我将UICollectionView与两个自定义布局一起使用,它们是从
UICollectionViewFlowLayout

首次加载视图时,我使用以下命令将其设置为默认视图:

[self.collectionView setCollectionViewLayout:self.tableViewLayout];
这将调用:
cellForItemAtIndexPath
——因此没有问题。这在
视图中将出现
方法中

然后我使用UIButton将布局从当前视图更改为下一个布局,如下所示:

-(void)changeViewLayoutButtonPressed
{
    self.changeLayout = !self.changeLayout;


    if (self.changeLayout){

        [self.tradeFeedCollectionView setCollectionViewLayout:self.grideLayout animated:YES];

    }

    else {


        [self.tradeFeedCollectionView setCollectionViewLayout:self.tableViewLayout animated:YES];

    }
}
@property (strong, nonatomic) BBTradeFeedTableViewLayout *tableViewLayout;
@property (strong, nonatomic) BBTradeFeedGridViewLayout *grideLayout;
在此调用之后,将调用
numberOfItemsInSection
。我已在调试器中检查返回帐户是否不为零

在该调用之后,不会调用任何其他内容,my UICollectionView会更改布局,但由于未调用
cellForItemAtIndexPath
,因此单元格设置不正确

如果我将
[self.collectionView roloadData]
放在
numberOfItemsInSection
中,则调用
cellForItemAtIndexPath
并设置单元格

我不需要手动调用来重新加载
numberOfItemsInSection
中的数据。有人能告诉我发生了什么事吗

编辑

我忘了提到我正在为两个不同的单元格使用两个不同的UINIB,因为它们需要应用稍微不同的布局。这会是一个问题吗? 谢谢

编辑2

对,所以我让它几乎像我想要的那样工作。下面是用于集合视图的所有代码,以及我如何更改其布局

自定义布局

这些是从
UICollectionViewFlowLayout
子类化的-我之所以子类化是因为我的
UICollectionView
的外观和行为需要非常接近苹果预先制作的布局。不过,细胞大小不同

TableViewLayout -头文件中没有代码。 -BBTradeFeedTableViewLayout.m

@implementation BBTradeFeedTableViewLayout

-(id)init
{
    self = [super init];

    if (self){

        self.itemSize = CGSizeMake(320, 80);
        self.minimumLineSpacing = 0.1f;
    }

    return self;
}
@end
   @implementation BBTradeFeedGridViewLayout

-(id)init
{
    self = [super init];

    if (self){

        self.itemSize = CGSizeMake(159, 200);
        self.minimumInteritemSpacing = 0.1f;
        self.minimumLineSpacing = 0.1f;
    }
    return self; 
}
@end
网格布局 -头文件中没有代码。 -BBTradeFeedGridViewLayout.m

@implementation BBTradeFeedTableViewLayout

-(id)init
{
    self = [super init];

    if (self){

        self.itemSize = CGSizeMake(320, 80);
        self.minimumLineSpacing = 0.1f;
    }

    return self;
}
@end
   @implementation BBTradeFeedGridViewLayout

-(id)init
{
    self = [super init];

    if (self){

        self.itemSize = CGSizeMake(159, 200);
        self.minimumInteritemSpacing = 0.1f;
        self.minimumLineSpacing = 0.1f;
    }
    return self; 
}
@end
然后在包含我的
UICollectionView
ViewController
中,我声明如下两个自定义布局:

-(void)changeViewLayoutButtonPressed
{
    self.changeLayout = !self.changeLayout;


    if (self.changeLayout){

        [self.tradeFeedCollectionView setCollectionViewLayout:self.grideLayout animated:YES];

    }

    else {


        [self.tradeFeedCollectionView setCollectionViewLayout:self.tableViewLayout animated:YES];

    }
}
@property (strong, nonatomic) BBTradeFeedTableViewLayout *tableViewLayout;
@property (strong, nonatomic) BBTradeFeedGridViewLayout *grideLayout;
然后为collectionView注册两个.xib文件:

  [self.tradeFeedCollectionView registerNib:[UINib nibWithNibName:@"BBItemTableViewCell" bundle:nil] forCellWithReuseIdentifier:@"TableItemCell"];
        [self.tradeFeedCollectionView registerNib:[UINib nibWithNibName:@"BBItemGridViewCell" bundle:nil] forCellWithReuseIdentifier:@"GridItemCell"];
[self.collectionView removeFromSuperview]; //First remove the Collection View

//Relocate the view with layouts
UICollectionViewFlowLayout *layout=[[UICollectionViewFlowLayout alloc] init];
layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
layout.minimumInteritemSpacing = 10;
layout.minimumLineSpacing = 10;

 self.collectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.width,100) collectionViewLayout:layout];
[self.collectionView setDataSource:self];
[self.collectionView setDelegate:self];
[self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"cellIdentifier"];
[self.collectionView reloadData];

[self.view addSubview:self.collectionView];
然后,我有一个更改布局的UIButton:

    -(void)changeViewLayoutButtonPressed
{

    if (!self.gridLayoutActive){

        self.gridLayoutActive = YES;
        [self.tradeFeedCollectionView setCollectionViewLayout:self.grideLayout animated:YES];
        self.lastLayoutUsed = @"GridLayout";

    }

    else {

        self.gridLayoutActive = NO;

        [self.tradeFeedCollectionView setCollectionViewLayout:self.tableViewLayout animated:YES];
        self.lastLayoutUsed = @"TableLayOut";
    }
    [self.tradeFeedCollectionView reloadItemsAtIndexPaths:[self.tradeFeedCollectionView indexPathsForVisibleItems]];

}
最后,当web服务调用完成时,它调用
[self.tradeFeedCollectionView reloadData]

因此,我的
UICollectionView
被重新加载,最后一个方法是:

 -(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath

{   static NSString *tableCellIdentifier = @"TableItemCell";
    static NSString *gridCellIdentifier = @"GridItemCell";

    if (indexPath.item < [self.tradeSearchArray count]){

    if (self.gridLayoutActive == NO){

        BBItemTableViewCell *tableItemCell = [collectionView dequeueReusableCellWithReuseIdentifier:tableCellIdentifier forIndexPath:indexPath];

    if ([self.tradeSearchArray count] > 0){

        self.toolBarButtomItem.title = [NSString stringWithFormat:@"%d Results", self.searchResult.searchResults];

        tableItemCell.gridView = NO;
        tableItemCell.backgroundColor = [UIColor whiteColor];
        tableItemCell.item = self.tradeSearchArray[indexPath.row];

    }
        return tableItemCell;
}else

    {

        BBItemTableViewCell *gridItemCell= [collectionView dequeueReusableCellWithReuseIdentifier:gridCellIdentifier forIndexPath:indexPath];

    if ([self.tradeSearchArray count] > 0){

        self.toolBarButtomItem.title = [NSString stringWithFormat:@"%d Results", self.searchResult.searchResults];


        gridItemCell.gridView = YES;
        gridItemCell.backgroundColor = [UIColor whiteColor];
        gridItemCell.item = self.tradeSearchArray[indexPath.row];

    }

    return gridItemCell;
    }
-(UICollectionViewCell*)collectionView:(UICollectionView*)collectionView cellForItemAtIndexPath:(NSIndexPath*)indexPath
{静态NSString*tableCellIdentifier=@“TableItemCell”;
静态NSString*gridCellIdentifier=@“GridItemCell”;
if(indexath.item<[self.tradeSearchArray count]){
if(self.gridLayoutActive==否){
BBItemTableViewCell*tableItemCell=[collectionView dequeueReusableCellWithReuseIdentifier:tableCellIdentifier for indexPath:indexPath];
如果([self.tradeSearchArray count]>0){
self.toolbarbuttonmitem.title=[NSString stringWithFormat:@“%d个结果”,self.searchResult.searchResults];
tableItemCell.gridView=否;
tableItemCell.backgroundColor=[UIColor whiteColor];
tableItemCell.item=self.tradeSearchArray[indexath.row];
}
返回表项单元格;
}否则
{
BBItemTableViewCell*gridItemCell=[collectionView dequeueReusableCellWithReuseIdentifier:gridCellIdentifier forIndexPath:indexPath];
如果([self.tradeSearchArray count]>0){
self.toolbarbuttonmitem.title=[NSString stringWithFormat:@“%d个结果”,self.searchResult.searchResults];
gridItemCell.gridView=是;
gridItemCell.backgroundColor=[UIColor whiteColor];
gridItemCell.item=self.tradeSearchArray[indexath.row];
}
返回gridItemCell;
}
上述代码的问题

上面的代码确实有效。但是,单元格的动画效果不好,看起来很奇怪,几乎就像发生了刷新。这是由于调用:

[self.tradeFeedCollectionView重载itemsatindexpaths:[self.tradeFeedCollectionView indexPathsForVisibleItems]];


但这是我能让它接近我想要的东西的唯一方法。

你应该在之前调用
[self.tradeFeedCollectionView invalidateLayout];

if (self.changeLayout){
    [self.tradeFeedCollectionView setCollectionViewLayout:self.grideLayout animated:YES];
}
else {
    [self.tradeFeedCollectionView setCollectionViewLayout:self.tableViewLayout animated:YES];
}

-setCollectionViewLayout:
-setCollectionViewLayout:animated:
不会导致您的
UICollectionView
重新加载其数据

  • 如果要更改单元格样式或更新数据,请调用
    [self.collectionView reloadData]
    并调用
    UICollectionViewDataSource
    协议方法

  • 如果要将
    UICollectionView
    布局更改为其他布局,请调用
    -setCollectionViewLayout:
    。或者如果要更新
    UICollectionView
    布局,只需调用
    [self.collectionView.collectionViewLayout invalidateLayout]

单元格布局和数据在
UICollectionView
中是两个不同的东西

更新
您应该丢弃所有过时的数据,可能是通过
-reloadData
,并为UICollectionViewLayout子类中的每个单元格计算新的帧。重写
-(UICollectionViewLayoutAttribute*)LayoutAttribute ForItemAtIndexPath:(NSIndexPath*)indexPath
(NSArray*)LayoutAttribute ForElementsRect:(cRect)rect

您可以决定新的
contentOffset
。例如,您可以保留某个可见单元格的indexPath,并决定在布局更改后滚动到该
indexPath
setContentOffset:
框架。新单元格的原点在同一
indexPath

  • 我发现我可以给你帮助
  • 还可以查看精彩的视频

您应该只需要将其称为m
[self.collectionView reloadData]; 
    [self.collectionView performBatchUpdates:^{
        [self.collectionView.collectionViewLayout invalidateLayout];
        [self.collectionView setCollectionViewLayout:self.grideLayout animated:YES];
    } completion:^(BOOL finished) {

    }];
}
[self.collectionView reloadSections:[NSIndexSet indexSetWithIndex:0]];
[self.collectionView setCollectionViewLayout:newLayout animated:animated];