Ios 如何在2个不同的UICollectionViewFlowLayout实例之间切换?
我已经为此工作了几天了。我正在尝试允许应用程序的客户在购物时在两种显示类型之间切换 现在我正在使用2个Ios 如何在2个不同的UICollectionViewFlowLayout实例之间切换?,ios,objective-c,cocoa-touch,uicollectionview,uicollectionviewcell,Ios,Objective C,Cocoa Touch,Uicollectionview,Uicollectionviewcell,我已经为此工作了几天了。我正在尝试允许应用程序的客户在购物时在两种显示类型之间切换 现在我正在使用2个UICollectionView,它们有自己的自定义UICollectionViewCell,在这两个视图之间切换很好,但我发现使用2个不同的UICollectionView,正在成为一种痛苦。我为主UICollectionView实现的某些东西在备选UICollectionView中无法正常工作 这就是显示的更改方式。我将UISegmentedControl与自定义方法一起使用: - (voi
UICollectionView
,它们有自己的自定义UICollectionViewCell
,在这两个视图之间切换很好,但我发现使用2个不同的UICollectionView
,正在成为一种痛苦。我为主UICollectionView
实现的某些东西在备选UICollectionView
中无法正常工作
这就是显示的更改方式。我将UISegmentedControl
与自定义方法一起使用:
- (void)displayTypeSegmentSelected
{
_selectedDisplayTypeIndex = [_displayTypeControl selectedSegmentIndex];
if (_selectedDisplayTypeIndex == 0) {
NSLog(@"Single file item view selected");
_fromCollectionView = _collectionView;
_toCollectionView = _collectionView2;
} else if (_selectedDisplayTypeIndex == 1) {
NSLog(@"Grid style view selected");
_fromCollectionView = _collectionView2;
_toCollectionView = _collectionView;
}
[_fromCollectionView removeFromSuperview];
[_toCollectionView setFrame:[_superView bounds]];
[_superView addSubview:_toCollectionView];
}
通过stackoverflow,我得到了两个不同的建议,关于如何更好地完成我想做的事情。
- (void)displayTypeSegmentSelected
{
_selectedDisplayTypeIndex = [_displayTypeControl selectedSegmentIndex];
if (_selectedDisplayTypeIndex == 0) {
NSLog(@"Single file item view selected");
[_collectionView setCollectionViewLayout:_flowLayout2 animated:YES];
[_collectionView reloadItemsAtIndexPaths:[_collectionView indexPathsForVisibleItems]];
} else if (_selectedDisplayTypeIndex == 1) {
NSLog(@"Grid style view selected");
[_collectionView setCollectionViewLayout:_flowLayout animated:YES];
[_collectionView reloadItemsAtIndexPaths:[_collectionView indexPathsForVisibleItems]];
}
}
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath object:(PFObject *)object
{
NSLog(@"collectionview 1 loaded");
static NSString *CellIdentifier = @"Cell";
VAGGarmentCell *cell = [_collectionView dequeueReusableCellWithReuseIdentifier: CellIdentifier forIndexPath:indexPath];
static NSString *CellIdentifier2 = @"Cell2";
VAGGarmentCell2 *cell2 = [_collectionView dequeueReusableCellWithReuseIdentifier:CellIdentifier2 forIndexPath:indexPath];
if ([[_collectionView collectionViewLayout] isEqual: _flowLayout]) {
[[cell activityIndicator] startAnimating];
PFFile *userImageFile = [object valueForKey:@"image"];
[[cell imageView] setFile: userImageFile];
[[cell imageView] loadInBackground];
[[cell activityIndicator] stopAnimating];
[[cell title] setText:[object valueForKey:@"title"]];
[[cell price] setText:[NSString stringWithFormat: @"£%@ GBP", [object valueForKey:@"price"]]];
return cell;
} else if ([[_collectionView collectionViewLayout] isEqual: _flowLayout2]) {
[[cell2 activityIndicator] startAnimating];
PFFile *userImageFile = [object valueForKey:@"image"];
[[cell2 imageView] setFile: userImageFile];
[[cell2 imageView] loadInBackground];
[[cell2 activityIndicator] stopAnimating];
[[cell2 title] setText:[object valueForKey:@"title"]];
[[cell2 price] setText:[NSString stringWithFormat: @"£%@ GBP", [object valueForKey:@"price"]]];
return cell2;
}
return 0;
//_addToFavouritesButton = [cell addFavouriteButton];
[_addToFavouritesButton addTarget:_thisController action:@selector(addToFavouritesButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
}
// Grab cell nib file and give a reuse identifier
[_collectionView registerNib:[UINib nibWithNibName:@"VAGGarmentCell2" bundle:nil] forCellWithReuseIdentifier:@"Cell2"];
UICollectionViewFlowLayout
,并在它们之间切换,而不是使用2UICollectionView
UICollectionViewCell
UICollectionViewFlowLayout
设置为IBOutlet,因为连接的UICollectionView
不是以编程方式创建的。然后我将以编程方式创建第二个UICollectionViewFlowLayout
在我的displayTypeSegmentSelected方法中,我将根据所选的段加载两个UICollectionViewFlowLayout
中的一个
单个文件显示如下所示:
- (void)displayTypeSegmentSelected
{
_selectedDisplayTypeIndex = [_displayTypeControl selectedSegmentIndex];
if (_selectedDisplayTypeIndex == 0) {
NSLog(@"Single file item view selected");
_fromCollectionView = _collectionView;
_toCollectionView = _collectionView2;
} else if (_selectedDisplayTypeIndex == 1) {
NSLog(@"Grid style view selected");
_fromCollectionView = _collectionView2;
_toCollectionView = _collectionView;
}
[_fromCollectionView removeFromSuperview];
[_toCollectionView setFrame:[_superView bounds]];
[_superView addSubview:_toCollectionView];
}
网格样式显示如下所示:
- (void)displayTypeSegmentSelected
{
_selectedDisplayTypeIndex = [_displayTypeControl selectedSegmentIndex];
if (_selectedDisplayTypeIndex == 0) {
NSLog(@"Single file item view selected");
_fromCollectionView = _collectionView;
_toCollectionView = _collectionView2;
} else if (_selectedDisplayTypeIndex == 1) {
NSLog(@"Grid style view selected");
_fromCollectionView = _collectionView2;
_toCollectionView = _collectionView;
}
[_fromCollectionView removeFromSuperview];
[_toCollectionView setFrame:[_superView bounds]];
[_superView addSubview:_toCollectionView];
}
问题:
- (void)displayTypeSegmentSelected
{
_selectedDisplayTypeIndex = [_displayTypeControl selectedSegmentIndex];
if (_selectedDisplayTypeIndex == 0) {
NSLog(@"Single file item view selected");
_fromCollectionView = _collectionView;
_toCollectionView = _collectionView2;
} else if (_selectedDisplayTypeIndex == 1) {
NSLog(@"Grid style view selected");
_fromCollectionView = _collectionView2;
_toCollectionView = _collectionView;
}
[_fromCollectionView removeFromSuperview];
[_toCollectionView setFrame:[_superView bounds]];
[_superView addSubview:_toCollectionView];
}
我想我有一个正确的想法,那就是如何按照我最初的问题去做,如何去做。不过,我会从经验丰富的开发人员那里介绍一个观点和示例。
你会如何做到这一点,你能给我一个清晰的例子,我可以去乱搞吗
亲切的问候这就是我最后做事情的方式 点击特定分段控件后,我更改布局并重新加载单元格。
- (void)displayTypeSegmentSelected
{
_selectedDisplayTypeIndex = [_displayTypeControl selectedSegmentIndex];
if (_selectedDisplayTypeIndex == 0) {
NSLog(@"Single file item view selected");
[_collectionView setCollectionViewLayout:_flowLayout2 animated:YES];
[_collectionView reloadItemsAtIndexPaths:[_collectionView indexPathsForVisibleItems]];
} else if (_selectedDisplayTypeIndex == 1) {
NSLog(@"Grid style view selected");
[_collectionView setCollectionViewLayout:_flowLayout animated:YES];
[_collectionView reloadItemsAtIndexPaths:[_collectionView indexPathsForVisibleItems]];
}
}
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath object:(PFObject *)object
{
NSLog(@"collectionview 1 loaded");
static NSString *CellIdentifier = @"Cell";
VAGGarmentCell *cell = [_collectionView dequeueReusableCellWithReuseIdentifier: CellIdentifier forIndexPath:indexPath];
static NSString *CellIdentifier2 = @"Cell2";
VAGGarmentCell2 *cell2 = [_collectionView dequeueReusableCellWithReuseIdentifier:CellIdentifier2 forIndexPath:indexPath];
if ([[_collectionView collectionViewLayout] isEqual: _flowLayout]) {
[[cell activityIndicator] startAnimating];
PFFile *userImageFile = [object valueForKey:@"image"];
[[cell imageView] setFile: userImageFile];
[[cell imageView] loadInBackground];
[[cell activityIndicator] stopAnimating];
[[cell title] setText:[object valueForKey:@"title"]];
[[cell price] setText:[NSString stringWithFormat: @"£%@ GBP", [object valueForKey:@"price"]]];
return cell;
} else if ([[_collectionView collectionViewLayout] isEqual: _flowLayout2]) {
[[cell2 activityIndicator] startAnimating];
PFFile *userImageFile = [object valueForKey:@"image"];
[[cell2 imageView] setFile: userImageFile];
[[cell2 imageView] loadInBackground];
[[cell2 activityIndicator] stopAnimating];
[[cell2 title] setText:[object valueForKey:@"title"]];
[[cell2 price] setText:[NSString stringWithFormat: @"£%@ GBP", [object valueForKey:@"price"]]];
return cell2;
}
return 0;
//_addToFavouritesButton = [cell addFavouriteButton];
[_addToFavouritesButton addTarget:_thisController action:@selector(addToFavouritesButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
}
// Grab cell nib file and give a reuse identifier
[_collectionView registerNib:[UINib nibWithNibName:@"VAGGarmentCell2" bundle:nil] forCellWithReuseIdentifier:@"Cell2"];
在我的单元格ForItemAtIndexPath
中,根据屏幕上显示的布局,我加载了具有正确设置的特定自定义单元格。
- (void)displayTypeSegmentSelected
{
_selectedDisplayTypeIndex = [_displayTypeControl selectedSegmentIndex];
if (_selectedDisplayTypeIndex == 0) {
NSLog(@"Single file item view selected");
[_collectionView setCollectionViewLayout:_flowLayout2 animated:YES];
[_collectionView reloadItemsAtIndexPaths:[_collectionView indexPathsForVisibleItems]];
} else if (_selectedDisplayTypeIndex == 1) {
NSLog(@"Grid style view selected");
[_collectionView setCollectionViewLayout:_flowLayout animated:YES];
[_collectionView reloadItemsAtIndexPaths:[_collectionView indexPathsForVisibleItems]];
}
}
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath object:(PFObject *)object
{
NSLog(@"collectionview 1 loaded");
static NSString *CellIdentifier = @"Cell";
VAGGarmentCell *cell = [_collectionView dequeueReusableCellWithReuseIdentifier: CellIdentifier forIndexPath:indexPath];
static NSString *CellIdentifier2 = @"Cell2";
VAGGarmentCell2 *cell2 = [_collectionView dequeueReusableCellWithReuseIdentifier:CellIdentifier2 forIndexPath:indexPath];
if ([[_collectionView collectionViewLayout] isEqual: _flowLayout]) {
[[cell activityIndicator] startAnimating];
PFFile *userImageFile = [object valueForKey:@"image"];
[[cell imageView] setFile: userImageFile];
[[cell imageView] loadInBackground];
[[cell activityIndicator] stopAnimating];
[[cell title] setText:[object valueForKey:@"title"]];
[[cell price] setText:[NSString stringWithFormat: @"£%@ GBP", [object valueForKey:@"price"]]];
return cell;
} else if ([[_collectionView collectionViewLayout] isEqual: _flowLayout2]) {
[[cell2 activityIndicator] startAnimating];
PFFile *userImageFile = [object valueForKey:@"image"];
[[cell2 imageView] setFile: userImageFile];
[[cell2 imageView] loadInBackground];
[[cell2 activityIndicator] stopAnimating];
[[cell2 title] setText:[object valueForKey:@"title"]];
[[cell2 price] setText:[NSString stringWithFormat: @"£%@ GBP", [object valueForKey:@"price"]]];
return cell2;
}
return 0;
//_addToFavouritesButton = [cell addFavouriteButton];
[_addToFavouritesButton addTarget:_thisController action:@selector(addToFavouritesButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
}
// Grab cell nib file and give a reuse identifier
[_collectionView registerNib:[UINib nibWithNibName:@"VAGGarmentCell2" bundle:nil] forCellWithReuseIdentifier:@"Cell2"];
在我的viewDidLoad中,这里是我为单个项目显示的自定义单元格引用nib文件的地方。
- (void)displayTypeSegmentSelected
{
_selectedDisplayTypeIndex = [_displayTypeControl selectedSegmentIndex];
if (_selectedDisplayTypeIndex == 0) {
NSLog(@"Single file item view selected");
[_collectionView setCollectionViewLayout:_flowLayout2 animated:YES];
[_collectionView reloadItemsAtIndexPaths:[_collectionView indexPathsForVisibleItems]];
} else if (_selectedDisplayTypeIndex == 1) {
NSLog(@"Grid style view selected");
[_collectionView setCollectionViewLayout:_flowLayout animated:YES];
[_collectionView reloadItemsAtIndexPaths:[_collectionView indexPathsForVisibleItems]];
}
}
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath object:(PFObject *)object
{
NSLog(@"collectionview 1 loaded");
static NSString *CellIdentifier = @"Cell";
VAGGarmentCell *cell = [_collectionView dequeueReusableCellWithReuseIdentifier: CellIdentifier forIndexPath:indexPath];
static NSString *CellIdentifier2 = @"Cell2";
VAGGarmentCell2 *cell2 = [_collectionView dequeueReusableCellWithReuseIdentifier:CellIdentifier2 forIndexPath:indexPath];
if ([[_collectionView collectionViewLayout] isEqual: _flowLayout]) {
[[cell activityIndicator] startAnimating];
PFFile *userImageFile = [object valueForKey:@"image"];
[[cell imageView] setFile: userImageFile];
[[cell imageView] loadInBackground];
[[cell activityIndicator] stopAnimating];
[[cell title] setText:[object valueForKey:@"title"]];
[[cell price] setText:[NSString stringWithFormat: @"£%@ GBP", [object valueForKey:@"price"]]];
return cell;
} else if ([[_collectionView collectionViewLayout] isEqual: _flowLayout2]) {
[[cell2 activityIndicator] startAnimating];
PFFile *userImageFile = [object valueForKey:@"image"];
[[cell2 imageView] setFile: userImageFile];
[[cell2 imageView] loadInBackground];
[[cell2 activityIndicator] stopAnimating];
[[cell2 title] setText:[object valueForKey:@"title"]];
[[cell2 price] setText:[NSString stringWithFormat: @"£%@ GBP", [object valueForKey:@"price"]]];
return cell2;
}
return 0;
//_addToFavouritesButton = [cell addFavouriteButton];
[_addToFavouritesButton addTarget:_thisController action:@selector(addToFavouritesButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
}
// Grab cell nib file and give a reuse identifier
[_collectionView registerNib:[UINib nibWithNibName:@"VAGGarmentCell2" bundle:nil] forCellWithReuseIdentifier:@"Cell2"];
虽然每次我在不同的布局之间切换时,我的内存都会不断增加,但我会遇到崩溃,但它们很难复制。我猜我需要删除一些旧代码。我明天会把它整理好,用仪器检查一下。然而,这已经完成,我可以继续前进
我可能需要在重复自己的地方重构代码。我在切换collectionView显示的动画时遇到一些问题。你的解决方案也帮助了我 这是我的结果 这就是解决办法 在ViewController中切换操作
if self.displayType == .grid {
self.displayType = .table
}else {
self.displayType = .grid
}
// Only update item size here
self.updateFlowLayout()
self.collectionView.performBatchUpdates({
self.collectionView.setCollectionViewLayout(self.flowLayout, animated: true)
}, completion: { (finished) in
})
我正在使用一个collectionViewCell。
覆盖单元的布局子视图
override func layoutSubviews() {
super.layoutSubviews()
if (self.bounds.width / self.bounds.height) > 1.4 {
if self.displayType != .table {
self.displayType = .table
}
}else {
if self.displayType != .grid {
self.displayType = .grid
}
}
}
和显示类型
var displayType : CastDisplayType = .grid {
didSet {
//Update constraints of subviews between cell
updateLayout()
}
}
希望它能对一些人有所帮助。此时,在github上发布一个精简/基本版本的代码可能是值得的,这样任何人都可以使用它。。。祝你好运。我同意你的决定,第一种方法是在布局之间切换。要做到这一点,没有多少事情要做。看起来您已经构建了这两个布局,只需在分段控件的操作方法中使用setCollectionViewLayout:animated:completion:在它们之间切换即可。试着去实现它,如果你遇到麻烦,再问一个更具体的基于代码的问题。@rdelmar,设置它确实花了5分钟,而且效果很好。这部动画片是一种奖励。我现在唯一的问题是切换到的布局使用了原始布局的单元,默认情况下,该单元比我为单视图布局创建的单元小得多。切换时,我获得了单文件视图,由于布局设置(项目插入300x500),单元格被放大,但由于使用了其他布局单元格,图像视图仍然很小。解决这个问题的最佳方法是什么?我想我可以检查cellForItemAtIndex中的当前布局,但事实证明这很困难。只需使用collectionView:layout:SizeForItemIndeXPath:。布局已为您传入,请检查它是哪一个,并返回该布局所需的大小。@rdelmar,这将调整单元格的大小,但不会调整包含项目图像的“我的图像”视图的大小。图像视图保持不变。最终崩溃与此无关。我真的很感谢你在这里所做的一切和你编写的代码。我正在做一些类似的事情,但是我的问题是动画看起来不太好,如果我在布局之间快速切换,所有的单元格都会消失。不太好。