iOS: Custom Cell Properties with Code and IB do not appear together - ios

CustomCell.h
#interface CustomCell : UITableViewCell
//Properties created in Code, not via IB.
#property (nonatomic, strong) UILabel *labelUsername;
#property (nonatomic, strong) UIView *circle;
//Properties Created through IB by control+drag
#property (nonatomic, strong) UILabel *labelFirstName;
#property (nonatomic, strong) UILabel *labelLastName;
#end
CustomCell.m
#implementation CustomCell
-(id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
//Creating properties in code
self.circle = [[UIView alloc] initWithFrame:CGRectMake(10, 10, 40.0f, 40.0f)];
[self.circle setBackgroundColor:[UIColor brownColor];
self.labelUsername = [[UILabel alloc] initWithFrame:CGRectMake(15, 20, 200.0f, 50.0f)];
self.labelUsername.textColor = [UIColor blackColor];
[self.contentView addSubview:self.labelUsername];
[self.contentView addSubview:self.circle];
}
return self;
}
tableView.m
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *customCellIdentifier = #"CustomCell";
CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:customCellIdentifier];
if (cell == nil) {
cell = [[CustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:inviteCellIdentifier];
}
cell.labelFirstName.text = #"FirstName";
cell.labelLastName.text = #"LastName";
return cell;
}
The code above continued to show labelUsername and circle. However, the properties created using the IB (labelFirstName and labelLastName) did not appear.
So in tableView.m in viewDidLoad I registered the Nib with the following code:
- (void)viewDidLoad
{
[super viewDidLoad];
[self.tableView registerNib:[UINib nibWithNibName:#"CustomCell"
bundle:[NSBundle mainBundle]]
forCellReuseIdentifier:#"CustomCell"];
}
Now labelFirstName and labelLastName appear, but the properties created with code (labelUsername and circle) DO NOT appear.
How can I get all 4 properties to show?

Try this in CustomCell.m,
- (void)awakeFromNib
{
[super awakeFromNib];
self.circle = [[UIView alloc] initWithFrame:CGRectMake(10, 10, 40.0f, 40.0f)];
[self.circle setBackgroundColor:[UIColor brownColor];
self.labelUsername = [[UILabel alloc] initWithFrame:CGRectMake(15, 20, 200.0f, 50.0f)];
self.labelUsername.textColor = [UIColor blackColor];
[self.contentView addSubview:self.labelUsername];
[self.contentView addSubview:self.circle];
}

Try this after self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
NSArray *views = [[NSBundle mainBundle]loadNibNamed:#"yourNibName" owner:self options:NULL];
[self addSubview:[views lastObject]];

Related

How to indent only UITableViewCell content not the separator?

If I use this code to indent from left, everything is indented (separator + content)
table.contentInset = UIEdgeInsetsMake(0, 20, 0, 0);
Same if I use this:
cell.layoutMargins = UIEdgeInsetsMake(0, 20, 0, 0);
This doesn't help neither, because it doesn't move the image.
cell.indentationLevel = 10;
You can use a CustomTableCell to get what you want:
At first, in ViewController:
#import "ViewController.h"
#import "MyTableCell.h"
#interface ViewController ()
#property UITableView *tableView;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
_tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height)];
_tableView.separatorStyle = UITableViewCellSelectionStyleNone;
_tableView.backgroundColor = [UIColor grayColor];
_tableView.dataSource = self;
_tableView.delegate = self;
[self.view addSubview:_tableView];
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return 20;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
MyTableCell *cell = [tableView dequeueReusableCellWithIdentifier:#"MyCell"];
if (nil == cell) {
cell = [[MyTableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"MyCell"];
}
//Update data for cell
return cell;
}
#end
This is MyTableCell.h:
#import "MyTableCell.h"
#interface MyTableCell()
#property UIView *containerView;
#property UIView *separationLine;
#end
#implementation MyTableCell
-(id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
_containerView = [[UIView alloc] init];
_containerView.backgroundColor = [UIColor redColor];
[self addSubview:_containerView];
_separationLine = [[UIView alloc] init];
_separationLine.backgroundColor = [UIColor blackColor];
[self addSubview:_separationLine];
return self;
}
-(void)layoutSubviews{
_containerView.frame = CGRectMake(20, 0, self.frame.size.width-20, self.frame.size.height-1);
_separationLine.frame = CGRectMake(10, self.frame.size.height-1, self.frame.size.width-10, 1);
}
#end
And this is the screenshot for the code:
You can modify the code in "layoutSubviews" as your wish.
Hope it can help you.

How to insert a button on the bottom of every UITableView section?

I currently have a UITableView within my MatchCenterViewController, and I designed it to load up 10 rows for every section, but only show the first 4 by making the heightForRowAtIndexPath return a value of 0 for the rest. What I want to do is have a button on the bottom of every section that when pressed, will reload the data and show 10 instead of 4 for just that specific section.
I've started working on the framework for what happens when the button is pressed, I'm just having trouble with the syntax for rendering the button on the bottom and showing 10 rows for only that respective section. Here's how I have my UITableView laid out so far:
MatchCenterViewController.h:
#import <UIKit/UIKit.h>
#import <Parse/Parse.h>
#import "AsyncImageView.h"
#import "SearchViewController.h"
#import "WebViewController.h"
#import "SLExpandableTableView.h"
#interface MatchCenterViewController : UIViewController <UITableViewDataSource>
#property (strong, nonatomic) NSString *itemSearch;
#property (nonatomic, strong) NSArray *imageURLs;
#property (strong, nonatomic) NSString *matchingCategoryCondition;
#property (strong, nonatomic) NSString *matchingCategoryLocation;
#property (strong, nonatomic) NSNumber *matchingCategoryMaxPrice;
#property (strong, nonatomic) NSNumber *matchingCategoryMinPrice;
#property (strong, nonatomic) NSArray *matchCenterArray;
#property (strong, nonatomic) NSString *searchTerm;
#property (strong, nonatomic) NSString *itemURL;
#end
MatchCenterViewController.m:
#import "MatchCenterViewController.h"
#import <UIKit/UIKit.h>
#interface MatchCenterViewController () <UITableViewDataSource, UITableViewDelegate>
#property (nonatomic, strong) UITableView *matchCenter;
#property (nonatomic, assign) BOOL matchCenterDone;
#property (nonatomic, assign) BOOL hasPressedShowMoreButton;
#end
#implementation MatchCenterViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
_matchCenterDone = NO;
//self.matchCenter = [[SLExpandableTableView alloc] initWithFrame:self.view.bounds style:UITableViewCellStyleSubtitle];
self.matchCenter = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewCellStyleSubtitle];
self.matchCenter.frame = CGRectMake(0,50,320,self.view.frame.size.height-100);
_matchCenter.dataSource = self;
_matchCenter.delegate = self;
[self.view addSubview:self.matchCenter];
_matchCenterArray = [[NSArray alloc] init];
}
- (void)viewDidAppear:(BOOL)animated
{
self.matchCenterArray = [[NSArray alloc] init];
UIActivityIndicatorView *activityIndicator = [[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
activityIndicator.center = CGPointMake(self.view.frame.size.width / 2.0, self.view.frame.size.height / 2.0);
[self.view addSubview: activityIndicator];
[activityIndicator startAnimating];
_matchCenterDone = NO;
// Disable ability to scroll until table is MatchCenter table is done loading
self.matchCenter.scrollEnabled = NO;
[PFCloud callFunctionInBackground:#"MatchCenter2"
withParameters:#{}
block:^(NSArray *result, NSError *error) {
if (!error) {
_matchCenterArray = result;
[activityIndicator stopAnimating];
[_matchCenter reloadData];
_matchCenterDone = YES;
self.matchCenter.scrollEnabled = YES;
NSLog(#"Result: '%#'", result);
}
}];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return _matchCenterArray.count;
}
//the part where i setup sections and the deleting of said sections
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return 21.0f;
}
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
{
return 0.01f;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 21)];
headerView.backgroundColor = [UIColor lightGrayColor];
_searchTerm = [[[[_matchCenterArray objectAtIndex:section] objectForKey:#"Top 3"] objectAtIndex:0]objectForKey:#"Search Term"];
UILabel *headerLabel = [[UILabel alloc] initWithFrame:CGRectMake(8, 0, 250, 21)];
headerLabel.text = [NSString stringWithFormat:#"%#", _searchTerm];
headerLabel.font = [UIFont boldSystemFontOfSize:[UIFont systemFontSize]];
headerLabel.textColor = [UIColor whiteColor];
headerLabel.backgroundColor = [UIColor lightGrayColor];
[headerView addSubview:headerLabel];
UIButton *deleteButton = [UIButton buttonWithType:UIButtonTypeCustom];
deleteButton.tag = section;
deleteButton.frame = CGRectMake(300, 2, 17, 17);
[deleteButton setImage:[UIImage imageNamed:#"xbutton.png"] forState:UIControlStateNormal];
[deleteButton addTarget:self action:#selector(deleteButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
[headerView addSubview:deleteButton];
return headerView;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSDictionary *currentSectionDictionary = _matchCenterArray[section];
NSArray *top3ArrayForSection = currentSectionDictionary[#"Top 3"];
return top3ArrayForSection.count-1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// Initialize cell
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell) {
// if no cell could be dequeued create a new one
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
// No cell separators = clean design
tableView.separatorColor = [UIColor clearColor];
// title of the item
cell.textLabel.text = _matchCenterArray[indexPath.section][#"Top 3"][indexPath.row+1][#"Title"];
cell.textLabel.font = [UIFont boldSystemFontOfSize:14];
// price of the item
cell.detailTextLabel.text = [NSString stringWithFormat:#"$%#", _matchCenterArray[indexPath.section][#"Top 3"][indexPath.row+1][#"Price"]];
cell.detailTextLabel.textColor = [UIColor colorWithRed:0/255.0f green:127/255.0f blue:31/255.0f alpha:1.0f];
// image of the item
NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:_matchCenterArray[indexPath.section][#"Top 3"][indexPath.row+1][#"Image URL"]]];
[[cell imageView] setImage:[UIImage imageWithData:imageData]];
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row > 3 || self.hasPressedShowMoreButton){
return 0;
}
else{
return 65;
}
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (_matchCenterDone == YES) {
self.itemURL = _matchCenterArray[indexPath.section][#"Top 3"][indexPath.row][#"Item URL"];
[self performSegueWithIdentifier:#"WebViewSegue" sender:self];
}
}
-(IBAction)pressedShowMoreButton{
self.hasPressedShowMoreButton = YES;
[self.matchCenter reloadData];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
WebViewController *controller = (WebViewController *) segue.destinationViewController;
controller.itemURL = self.itemURL;
}
#end
for this functionality you can either use special UITableviewCell or a footerView of UITableView
You can use property tableFooterView.
Below is how I use in showing load more option
UIView *v = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 65)];
v.backgroundColor = [UIColor clearColor];
int mySiz = 0;
// keep counter how many times load more is pressed.. initial is 0 (this is like index)
mySiz = [startNumberLabel.text intValue]+1;
// i have 15 bcz my index size is 15.
if ([feeds count]>=(15*mySiz)) {
NSLog(#"showing button...");
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setFrame:CGRectMake(10, 10, 296, 45)];
[button setBackgroundImage:[UIImage imageNamed:localize(#"loadmore")] forState:UIControlStateNormal];
[button addTarget:self action:#selector(loadMoreData:) forControlEvents:UIControlEventTouchUpInside];
[v addSubview:button];
mainTableView.tableFooterView = v;
} else {
mainTableView.tableFooterView = nil;
}
[mainTableView reloadData];
Now adjust code as per your necessity...
Ended up doing it like this:
// Create "more" button
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section {
UIView *view = [[UIView alloc] initWithFrame:CGRectZero];
view.backgroundColor = [UIColor whiteColor];
self.moreButton = [UIButton buttonWithType:UIButtonTypeCustom];
self.moreButton.frame = CGRectMake(0, 0, 320, 44);
[self.moreButton setImage:[UIImage imageNamed:#"downarrow.png"] forState:UIControlStateNormal];
[self.moreButton addTarget:self action:#selector(moreButtonSelected:) forControlEvents:UIControlEventTouchUpInside];
[view addSubview:self.moreButton];
return view;
}
// Load rest of items
- (void)moreButtonSelected:(id)sender {
if (_hasPressedShowMoreButton == NO){
self.hasPressedShowMoreButton = YES;
}
else if (_hasPressedShowMoreButton == YES){
self.hasPressedShowMoreButton = NO;
}
[self.matchCenter reloadData];
}

Custom UITableViewCell's content is not showed

I'm trying to create a custom view cell. But it's not showing. The tableview cells are created correct number but their contents are not showed.
VDCoreTableViewCell.h
#interface VDCoreTableViewCell : UITableViewCell
#property (weak, nonatomic) UIImageView *cell_image;
#property (strong, nonatomic) UILabel *title;
#property (weak, nonatomic) UILabel *subTitle;
VDCoreTableViewCell.m
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
self.title = [[UILabel alloc] initWithFrame:self.bounds];
CAGradientLayer *gradientLayer = [CAGradientLayer layer];
gradientLayer.frame = self.title.bounds;
gradientLayer.colors = [NSArray arrayWithObjects:(id)[[UIColor whiteColor]CGColor], (id)[[UIColor blackColor]CGColor], nil];
[self.title.layer insertSublayer:gradientLayer atIndex:0];
}
return self;
}
VDViewController.h
#interface VDViewController : VDCoreViewController <UITableViewDelegate, UITableViewDataSource>
#property (strong, nonatomic) UITableView *tableView;
#end
VDViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
self.tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
[self.tableView setAutoresizingMask:UIViewAutoresizingFlexibleBottomMargin|UIViewAutoresizingFlexibleWidth];
[self.tableView setDataSource:self];
[self.tableView setDelegate:self];
[self.tableView registerClass: [VDCoreTableViewCell class] forCellReuseIdentifier:#"cell_id"];
[self.view addSubview:self.tableView];
}
- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
VDCoreTableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil)
{
cell = [[VDCoreTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MyIdentifier];
}
cell.title.text = #"test";
cell.subTitle.text = #"test";
}
Help please.
You have to add the titleLabel to your cell
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
self.title = [[UILabel alloc] initWithFrame:self.bounds];
CAGradientLayer *gradientLayer = [CAGradientLayer layer];
gradientLayer.frame = self.title.bounds;
gradientLayer.colors = [NSArray arrayWithObjects:(id)[[UIColor whiteColor]CGColor], (id)[[UIColor blackColor]CGColor], nil];
[self.title.layer insertSublayer:gradientLayer atIndex:0];
[self.contentView addSubview:self.title]; //Add your label what you have created to content view
}
return self;
}

Delegate method is being called but doesn't execute properly

I'm having a problem with one of my delegate methods. I have a collectionViewController to which I have added a UILongPressGestureRecognizer, which is calling a delegate method fadeOutLabels in my UICollectionViewCell. I can confirm the delegate method being called by a NSLog statement NSLog(#"fadeOutLabels was called");. But the other code inside that function isn't being executed. I'm quite sure I'm missing something completely obvious, but I can't seem to figure it out myself. Code as follows:
FOFPhotoCell.h
#protocol FOFPhotoCellDelegate <NSObject>
#required
-(void)fadeOutLabels;
#end
#interface FOFPhotoCell : UICollectionViewCell {
id delegate;
}
#property (nonatomic, weak) id<FOFPhotoCellDelegate> delegate;
#property (nonatomic) UIImageView *imageView;
#property (nonatomic) NSDictionary *photo;
#property (nonatomic) NSArray *fetchPhotos;
#property (nonatomic) UILabel *titleLabel;
#end
FOFPhotoCell.m
#implementation FOFPhotoCell
#synthesize delegate = _delegate;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
CGFloat widthFromBounds = self.contentView.bounds.size.width;
self.imageView = [[UIImageView alloc] init];
[self.contentView insertSubview:self.imageView atIndex:0];
UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 30, widthFromBounds, 60)];
self.titleLabel = titleLabel;
self.titleLabel.backgroundColor = [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.3];
self.titleLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleHeadline];
self.titleLabel.textColor = [UIColor whiteColor];
self.titleLabel.textAlignment = NSTextAlignmentCenter;
[self.contentView insertSubview:self.titleLabel atIndex:1];
}
return self;
}
-(void)fadeOutLabels
{
NSLog(#"fadeOutLabels was called");
[UIView animateWithDuration:1.0
delay:0.0 /* do not add a delay because we will use performSelector. */
options:UIViewAnimationOptionCurveEaseIn
animations:^ {
self.titleLabel.alpha = 0.0;
}
completion:^(BOOL finished) {
[self.titleLabel removeFromSuperview];
}];
}
FOFPhotosViewController.h
#import <UIKit/UIKit.h>
#import "FOFPhotoCell.h"
#interface FOFPhotosViewController : UICollectionViewController <FOFPhotoCellDelegate>
#end
FOFPhotosViewController.m
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
FOFPhotoCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"photo" forIndexPath:indexPath];
NSArray *photosArray = [self.dishes valueForKeyPath:#"avatar_url"];
NSArray *nameArray = [self.dishes valueForKeyPath:#"name"];
// NSLog(#"photoURL %#", _responseDictionary);
cell.backgroundColor = [UIColor lightGrayColor];
[cell.imageView setImageWithURL:[NSURL URLWithString:[NSString stringWithFormat:#"http://xx.yy.zz.qq:4000%#",[photosArray objectAtIndex: indexPath.row]]]];
cell.titleLabel.text = [NSString stringWithFormat:#"%#", [nameArray objectAtIndex:indexPath.row]];
UILongPressGestureRecognizer *tapAndHold = [[UILongPressGestureRecognizer alloc] initWithTarget:cell action:#selector(fadeOutLabels)];
tapAndHold.minimumPressDuration = 0.5;
[self.collectionView addGestureRecognizer:tapAndHold];
[self.collectionView reloadItemsAtIndexPaths:[NSArray arrayWithObject:indexPath]];
return cell;
}
I would really appreciate if some one could help me with this issue.
Thanks in advance
Chris
I believe your problem comes from the LongPressGestureRecognizer that should be instantiated in your custom cell and not in your view controller.
Basically, if you have a hundred cell how the long press gesture recognizer is supposed to know which cell you have pressed and which label to fade out.
You can try this instead, in your custom cell :
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
UILongPressGestureRecognizer *tapAndHold = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(fadeOutLabels)];
tapAndHold.minimumPressDuration = 0.5;
[self addGestureRecognizer:tapAndHold];
....
}
}
And of course remove those lines in the view controller.

UITableViewCell subclass

I have this code segment:
if (cell == nil)
{
CGRect cellFrame = CGRectMake(0,0,300,250);
cell = [[UITableViewCell alloc] initWithFrame:cellFrame
reuseIdentifier:CellTableIndetifier];
CGRect nameLabelRect = CGRectMake(0, 5, 70, 20);
UILabel* nameLabel = [[UILabel alloc] initWithFrame:nameLabelRect];
nameLabel.textAlignment = NSTextAlignmentCenter;
nameLabel.text = #"Name";
nameLabel.font = [UIFont boldSystemFontOfSize:12];
[cell.contentView addSubview: nameLabel];
CGRect colorLabelRect = CGRectMake(0, 25, 70, 20);
UILabel* colorLabel = [[UILabel alloc] initWithFrame:colorLabelRect];
colorLabel.textAlignment = NSTextAlignmentCenter;
colorLabel.text = #"Color";
colorLabel.font = [UIFont boldSystemFontOfSize:12];
[cell.contentView addSubview: colorLabel];
CGRect priceLabelRect = CGRectMake(0, 45, 70, 20);
UILabel *priceLabel = [[UILabel alloc] initWithFrame:priceLabelRect];
priceLabel.text = #"Price";
priceLabel.textAlignment = NSTextAlignmentCenter;
colorLabel.font = [UIFont boldSystemFontOfSize:12];
[cell.contentView addSubview:priceLabel];
CGRect nameValueRect = CGRectMake(80, 5, 200, 20);
UILabel* nameValue = [[UILabel alloc] initWithFrame: nameValueRect];
nameValue.tag = kNameValueTag;
[cell.contentView addSubview:nameValue];
CGRect colorValueRect = CGRectMake(80, 25, 200, 20);
UILabel* colorValue = [[UILabel alloc] initWithFrame:colorValueRect];
colorValue.tag = kColorValueTag;
[cell.contentView addSubview:colorValue];
CGRect priceValueRect = CGRectMake(80, 45, 200, 20);
UILabel *priceValue = [[UILabel alloc] initWithFrame:priceValueRect];
priceValue.tag = kPriceValueTag;
[cell.contentView addSubview:priceValue];
}
and I would like to make that make that into a subclass, so I don't have to write all those lines, I just say cell = CustomCell and it does everything in the subclass.
Here is the basic code for a subclass of UITableCellView :
#import <UIKit/UIKit.h>
#interface CustomCell : UITableViewCell
{
}
#end
-----------------------------------------------------------
#import "CustomCell.h"
#implementation CustomCell
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// Initialization code
}
return self;
}
-(void)layoutSubviews{
[super layoutSubviews];
}
/*
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}*/
#end
It is auto-generated if you create a new file of type Objective-C Class and specify UITableViewCell in filed subclass of
Following is what I usually do. If you use the cell only in 1 view controller, you can just put it in the same file as the view controller.
#interface MyCell : UITableViewCell
#property (strong, nonatomic) UILabel* nameValue;
#property (strong, nonatomic) UILabel* colorValue;
#property (strong, nonatomic) UILabel* priceValue;
#end
#implementation MyCell
-(id)init {
self = [super initWithStyle:whatever_style];
// Create & position UI elements
UILabel* nameLabel = [[UILabel alloc] init];
nameLabel.frame = .... // frame, font, etc
[self.contentView addSubview:nameLabel]
self.nameValue = [[UILabel alloc] init];
self.nameValue = .... // frame, font, etc
[self.contentView addSubview:self.nameValue];
// Do the same thing for color, price
return self;
}
#end
By exposing nameValue, colorValue, priceValue, I allow them to be changed from outside (ie the UITableViewController). I didn't expose other labels because they are static. Unless you need special positioning, you don't have to override layoutSubviews. autoresizingMask is sufficient in most cases.
There is two way I use to solve this.
The "quick and dirty" is to design a UITableViewCell into your UITableView with the stuff you need (UILabel, UIImageView,...) and set a unique tag for each element, then when you dequeue a UITableViewCell you can reuse the elements in like this :
UILabel *nameLabel = (UILabel*)[cell viewWithTag:NAME_LABEL_TAG];
if(!nameLabel) {
// If the label does not exist, create it
CGRect nameLabelRect = CGRectMake(0, 5, 70, 20);
nameLabel = [[UILabel alloc] initWithFrame:nameLabelRect];
nameLabel.textAlignment = NSTextAlignmentCenter;
nameLabel.text = #"Name";
nameLabel.font = [UIFont boldSystemFontOfSize:12];
[cell.contentView addSubview: nameLabel];
}
Or the (imo) best way is to create a custom UITableViewCell and subclass UItableviewCell, you have a good tutorial there : Custom UITableViewCell
I guess your are putting this stuff in your cellForRowAtIndexPath: delegate method and I can see why your strive to remove it from this place.
Create a new Objective-C class via New->File and put the subview related calls you posted in the layoutSubviews: method. In cellForRowAtIndexPath: in your table view delegate now use this class instead of the generic UITableViewCell. Don't forget to import your newly created file.
#import "CellVideo.h"
#implementation CellVideo
-(id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
return self;
}
-(id)initWithCoder:(NSCoder *)aDecoder
{
NSLog(#"initWithCoder");
self = [super initWithCoder: aDecoder];
if (self)
{
// Initialization code
MPMoviePlayerController *moviePlayer = [[MPMoviePlayerController alloc] init];
[moviePlayer.view setFrame:CGRectMake(10, 75, 300, 260)];
[moviePlayer.view setBackgroundColor:[UIColor blackColor]];
[moviePlayer.view setTag:333];
[moviePlayer setControlStyle:MPMovieControlStyleNone];
moviePlayer.scalingMode = MPMovieScalingModeFill;
_movie=moviePlayer;
UIImageView *imagrViewThumb=[[UIImageView alloc]initWithFrame:CGRectMake(10, 75, 300, 260)];
[imagrViewThumb setBackgroundColor:[UIColor redColor]];
[imagrViewThumb setTag:333];
[self.contentView insertSubview:imagrViewThumb atIndex:0];
}
return self;
}
-(void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
///use it in this way
CellIdentifier=#"cellvideo";
UITableViewCell *cell=nil;
// CellVideo *cellVideo=nil;
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}

Resources