如何创建自定义 UICollectionViewCell

how to create custom UICollectionViewCell

我有一个 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;
    }
}

很遗憾,没有标签显示,标签中的文本也没有显示。

已更新:我添加了此 class 文件中的其余代码。

#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
  1. 创建 UICollectionViewCell 的子class。例如TestCollectionViewCell.
  2. Storyboard 中将 label 拖到单元格中,然后使用您创建的 class 为此 UICollectionViewCell 设置 "Custom class"。设置 Reusable identifier,如果您在 UIViewController 中的 collection 视图,请不要忘记为 collectionView 设置 DataSourceDelegate
  3. 在您的 Cell subclass 中连接 IBOutlet
  4. numberOfItemsInSection 方法中设置至少 1 个值。
  5. 然后使用 cellForItemAt 中单元格的子 class 并尝试为标签设置文本。

清除示例以使用自定义 collectionViewCell

创建一个单独的 class subclass of UICollectionViewCell 见下面的代码:

.h 文件:

#import <UIKit/UIKit.h>

@interface CollectionViewCell : UICollectionViewCell
@property (weak, nonatomic) IBOutlet UILabel *customLabel;
@end

.m 文件:

#import "CollectionViewCell.h"

@implementation CollectionViewCell

@end

现在使用 storyboardcollectionView 拖放到 viewController 中,然后通过选择单元格为它设置自定义 class 并连接它的 IBOutlet 标签见下图。

设置自定义 class:

连接标签的出口: 如果从情节提要中添加标签和其他 ui 组件

注意:在连接 IBOutlet 之前将 uilabel 拖入单元格内。


现在在您的 viewController class 中配置单元格。并通过连接其 delegatedataSuorceIBOutlet 来正确配置 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显示为黑色。

这里希望你明白。

您缺少:

  [cell.contentView addSubview:issue];