如何创建自定义 UICollectionViewCell
Posted
技术标签:
【中文标题】如何创建自定义 UICollectionViewCell【英文标题】:how to create custom UICollectionViewCell 【发布时间】:2016-11-16 13:39:44 【问题描述】:我有一个UICollectionView
,我试图在collectionViewCell
中设置一个label
和一个image
。不幸的是,我似乎无法显示任何标签或其他任何东西。
这是我的代码:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"cellIdentifier" forIndexPath:indexPath];
UILabel *issue = [[UILabel alloc] initWithFrame:CGRectMake(0,10,cell.bounds.size.width,40)];
if(indexPath.item %2 == 0)
cell.backgroundColor=[UIColor blueColor];
issue.text = @"Some Text";
issue.textColor = [UIColor greenColor];
issue.textAlignment = NSTextAlignmentCenter;
else
cell.backgroundColor=[UIColor redColor];
issue.text = @"Some Text";
issue.textColor = [UIColor greenColor];
issue.textAlignment = NSTextAlignmentCenter;
很遗憾,没有显示标签,标签中的文本也没有显示。
更新:我已经添加了这个类文件中的其余代码。
#import "ContainerListController.h"
#import "ContainerController.h"
#import "ContainerList.h"
@implementation ContainerListController
//Deallocate temp variables
- (void)dealloc
[[NSNotificationCenter defaultCenter] removeObserver:self];
//Initiate objects
- (id)init
if (self = [super initWithTitle:LocStr(@"CONTAINER_LIST_TITLE") navBarHidden:NO])
m_paths = [ContainerList shared].paths;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(onContainerListDidChange)
name:kSDKLauncherContainerListDidChange object:nil];
return self;
//Load all the views.
- (void)loadView
//Allocate a UI view
self.view = [[UIView alloc] init];
//Create flow layout
UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
//Force Horizontal Scroll
[layout setScrollDirection:UICollectionViewScrollDirectionHorizontal];
layout.minimumInteritemSpacing =[[UIScreen mainScreen] bounds].size.width;
layout.minimumLineSpacing=0.0;
//Create Collection
UICollectionView *coll =[[UICollectionView alloc] initWithFrame:self.view.frame collectionViewLayout:layout];
//Allocations
m_coll = coll;
coll.dataSource =self;
coll.delegate =self;
coll.pagingEnabled = YES;
coll.collectionViewLayout = layout;
//Customize Cells
[coll registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"cellIdentifier"];
[coll setBackgroundColor:[UIColor orangeColor]];
[layout invalidateLayout];
//Create the subview
[self.view addSubview:coll];
//set minimum spacing
/*if(UIDeviceOrientationIsLandscape([UIDevice currentDevice].orientation))
NSLog(@"Changed to landscape Spacing");
layout.minimumLineSpacing = 100.0f;
layout.minimumInteritemSpacing = 100.0f;
else
layout.minimumLineSpacing = 40.0f;
layout.minimumInteritemSpacing = 40.0f;
*/
//Old Layout
//UITableView *table = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain];
//m_table = table;
//table.dataSource = self;
//table.delegate = self;
//[self.view addSubview:table];
- (void)onContainerListDidChange
m_paths = [ContainerList shared].paths;
[m_table reloadData];
[m_coll reloadData];
//Debugging components function
/*-(void)printComps:(NSArray* ) components
for (NSInteger i =0; i<16; i++)
NSString * item;
item=components[i];
*/
//old tableview cell
- (UITableViewCell *)
tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:nil];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
NSString *path = [m_paths objectAtIndex:indexPath.row];
NSArray *components = path.pathComponents;
cell.textLabel.text = (components == nil || components.count == 0) ?
@"" : components.lastObject;
return cell;
//Old tableView
- (void)
tableView:(UITableView *)tableView
didSelectRowAtIndexPath:(NSIndexPath *)indexPath
[tableView deselectRowAtIndexPath:indexPath animated:YES];
NSString *path = [m_paths objectAtIndex:indexPath.row];
ContainerController *c = [[ContainerController alloc] initWithPath:path];
if (c != nil)
[self.navigationController pushViewController:c animated:YES];
NSLog(@"Selected an item");
//old TableView count for epubs
- (NSInteger)
tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section
return m_paths.count;
- (void)viewDidLayoutSubviews
//m_table.frame = self.view.bounds;
m_coll.frame = self.view.bounds;
//Collection View Cell Data Allocation
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView
cellForItemAtIndexPath:(NSIndexPath *)indexPath
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"cellIdentifier" forIndexPath:indexPath];
UILabel *issue = [[UILabel alloc] initWithFrame:CGRectMake(0,10,cell.bounds.size.width,40)];
//UICollectionViewCell *content = [[UICollectionViewCell alloc] init];
if(indexPath.item %2 == 0)
cell.backgroundColor=[UIColor blueColor];
issue.text = @"Some Text";
issue.textColor = [UIColor greenColor];
issue.textAlignment = NSTextAlignmentCenter;
else
cell.backgroundColor=[UIColor redColor];
issue.text = @"Some Text";
issue.textColor = [UIColor greenColor];
issue.textAlignment = NSTextAlignmentCenter;
NSString *path = [m_paths objectAtIndex:indexPath.row];
NSArray *components = path.pathComponents;
NSString *Title = components.lastObject;
NSLog(@"Title: %@",Title);
NSString *Titletest = components.lastObject;
NSInteger comp1 = components.count;
NSString *comps = @"components";
NSLog(@"There are: %ld %@", (long)comp1,comps);
NSLog(@"Title: %@",Titletest);
for (NSInteger i =0; i<15; i++)
NSString * item;
item=components[i];
NSLog(@"Component:%ld %@",(long)i,components[i]);
return cell;
//Collection View Cell Data De-Allocation
- (void)
collectionView:(UICollectionView *)collectionView
numberofItemsInSection:(NSIndexPath *)indexPath
[collectionView deselectItemAtIndexPath:indexPath animated:YES];
NSString *path = [m_paths objectAtIndex:indexPath.row];
ContainerController *c = [[ContainerController alloc] initWithPath:path];
if(c !=nil)
[self.navigationController pushViewController:c animated:YES];
//Collection
-(NSInteger)
collectionView:(UICollectionView *)collectionView
numberOfItemsInSection:(NSInteger)section
return m_paths.count;
//Set Collection View Cell Size
-(CGSize)
collectionView:(UICollectionView *) collectionView
layout:(UICollectionViewLayout*)collectionViewLayout
sizeForItemAtIndexPath:(NSIndexPath *)indexPath
//Set Landscape size of cells
/*if(UIDeviceOrientationIsLandscape([UIDevice currentDevice].orientation))
CGFloat cellWidth = [[UIScreen mainScreen] bounds].size.width-360;
CGFloat cellHeigt = [[UIScreen mainScreen] bounds].size.height-60;
NSLog(@"Is Landscape");
return CGSizeMake(cellWidth, cellHeigt);
//Set Potrait size of cells
else
CGFloat cellWidth = [[UIScreen mainScreen] bounds].size.width-60;
CGFloat cellHeigt = [[UIScreen mainScreen] bounds].size.height-160;
NSLog(@"Is Portrait");
return CGSizeMake(cellWidth, cellHeigt);
*/
return CGSizeMake(collectionView.bounds.size.width, collectionView.bounds.size.height);
//Collection View Cell Position
- (UIEdgeInsets)collectionView:
(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section
if(UIDeviceOrientationIsPortrait([UIDevice currentDevice].orientation))
return UIEdgeInsetsMake(150.0,0.0,150.0,0.0); // top, left, bottom, right
else
return UIEdgeInsetsMake(20.0,0.0,0.0,0.0); // top, left, bottom, right
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
[m_coll performBatchUpdates:nil completion:nil];
-(void)viewWillTransitionToSize:withTransitionCoordinator
[m_coll performBatchUpdates:nil completion:nil];
/*-(CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)
collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section
CGFloat cellSpacing = ((UICollectionViewFlowLayout *) collectionViewLayout).minimumLineSpacing;
CGFloat cellWidth = ((UICollectionViewFlowLayout *) collectionViewLayout).itemSize.width;
NSInteger cellCount = [collectionView numberOfItemsInSection:section];
CGFloat inset = (collectionView.bounds.size.width - ((cellCount-1) * (cellWidth + cellSpacing))) * 0.5;
inset = MAX(inset, 0.0);
if(UIDeviceOrientationIsLandscape([UIDevice currentDevice].orientation))
NSLog(@"Changed to landscape Spacing");
return inset;
else
return inset;
*/
@end
【问题讨论】:
您需要创建自定义类并使用而不是UICollectionViewCell
。
所以UICollectionViewCell
自定义类包含标签详细信息和任何其他对象?
通过创建自定义类,您可以通过引用 cell.yourLabel.text = @"some value"
和其他预先声明的对象来维护 ui 组件。
所以你知道我是个白痴。这是怎么做的吗?UICollectionViewCell *content = [[UICollectionViewCell alloc] init];
然后我只是引用 CollectionViewCell 中的内容
好的,您现在需要更多关于您的问题的帮助示例吗?
【参考方案1】:
使用自定义collectionViewCell
的清晰示例。
创建UICollectionViewCell
的单独类子类见以下代码:
.h 文件:
#import <UIKit/UIKit.h>
@interface CollectionViewCell : UICollectionViewCell
@property (weak, nonatomic) IBOutlet UILabel *customLabel;
@end
.m 文件:
#import "CollectionViewCell.h"
@implementation CollectionViewCell
@end
现在使用storyboard
将collectionView
拖放到viewController
中,然后为其选择单元设置自定义类并连接其标签IBOutlet
,见下图。
设置自定义类:
连接标签的出口: 如果从情节提要中添加标签和其他 ui 组件
注意:在连接其IBOutlet
之前,将uilabel
拖入单元格内。
现在在 viewController
类中配置单元格。并通过连接delegate
、dataSuorce
和IBOutlet
来正确配置collectionView
。
#import "ViewController.h"
#import "CollectionViewCell.h"
@interface ViewController ()
// instance variable deceleration part
NSMutableArray *yourArray;
@end
@implementation ViewController
- (void)viewDidLoad
[super viewDidLoad];
_yourCollView.delegate = self;
_yourCollView.dataSource = self;
yourArray = [[NSMutableArray alloc] initWithObjects:@"1st cell",@"2nd cell",@"3rd cell",@"4th cell", nil];
// Do any additional setup after loading the view, typically from a nib.
// collection view delegate methods
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
return [yourArray count];
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
CollectionViewCell *cell = (CollectionViewCell *)[collectionView dequeueReusableCellWithReuseIdentifier:@"MyCustomCell" forIndexPath:indexPath];
// configuring cell
// cell.customLabel.text = [yourArray objectAtIndex:indexPath.row]; // comment this line if you do not want add label from storyboard
// if you need to add label and other ui component programmatically
UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, cell.bounds.size.width, cell.bounds.size.height)];
label.tag = 200;
label.text = [yourArray objectAtIndex:indexPath.row];
// this adds the label inside cell
[cell.contentView addSubview:label];
return cell;
//Note: Above two "numberOfItemsInSection" & "cellForItemAtIndexPath" methods are required.
// this method overrides the changes you have made to inc or dec the size of cell using storyboard.
- (CGSize)collectionView:(UICollectionView *)collectionView layout: (UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
return CGSizeMake(100, 100);
// class ends
设置单元格标识符(通过选择一个单元格)MyCustomCell
您在使用前在cellForItemAtIndexPath
方法中给出,请参见下图:
注意:之前将uilabel
的文字颜色改为白色,因为collectionView
默认显示为黑色。
希望你能理解。
【讨论】:
当我尝试创建一个新的UICollectionViewCell
时,我得到一个重复错误。我也无法将UILabel
添加到我的 .h 文件中
让我给几个小时。我会尽快更新答案。
谢谢你
@ZaydBhyat 现在努力并尊重我的时间,谢谢。
好的,我想我明白了,我必须为 UICollectionViewCell 创建一个带有 .h 和 .m 的单独类文件,并且该类可以包含所有需要成为单元格一部分的对象。对吗?【参考方案2】:
-
创建
UICollectionViewCell
的子类。例如TestCollectionViewCell
。
在Storyboard
中将label
拖动到单元格中,并使用您创建的类为此UICollectionViewCell
设置"Custom class"
。设置Reusable identifier
,如果您在UIViewController
中的收藏视图不要忘记为collectionView
设置DataSource
和Delegate
。
在您的 Cell 子类中连接 IBOutlet
。
在 numberOfItemsInSection
方法中设置至少 1 个值。
然后在cellForItemAt
中使用您的单元格子类并尝试为标签设置文本。
【讨论】:
由于收集数据的第三方框架的性质,我需要以编程方式创建它。所以我不能使用故事板 做同样的事情,但在 awakeFromNib 中没有 IBOutlets 和 init 视图【参考方案3】:你错过了:
[cell.contentView addSubview:issue];
【讨论】:
以上是关于如何创建自定义 UICollectionViewCell的主要内容,如果未能解决你的问题,请参考以下文章
如何创建自定义 MKAnnotationView 和自定义注释标题和副标题
如何创建一个自定义的Authentication Provider