I am currently creating my cell like this
UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil];
cell.imageView.image = [UIImage imageNamed:image];
cell.imageView.tintColor = [UIColor whiteColor];
cell.textLabel.text = #"Push me";
cell.textLabel.textColor = [UIColor whiteColor];
cell.userInteractionEnabled = YES;
return cell;
Everything is working fine but some of my text which is long gets truncated at the end. How can i avoid that?? I don't want to set the numberOfLines property.
Is there a way i can arrange my imageView and textlabel a bit via constraints so that my text looks fine. I tried adding constraints to contentView of cell but that make my cell all weird.
I am new to iOS development and learning. Any help will be greatly appreciated.
If you don't want to set numberOfLines. adjustsFontSizeToFitWidth property will set your content bound to width without truncating it. but it will decrease font size if required.
cell.textLabel.adjustsFontSizeToFitWidth = true
There is no need to add constraint programmatically,
Step 1 - Drag and drop the cell on UITableview
Step 2 - Design your cell with image view and label , use constraints
Step 3 - Create CustomCell.h and CustomCell.m file which will be inherited from UITableViewCell
Step 4 - create IBOutlet for image view and label in CustomCell.h
Step 5 - In your ViewController -
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"CustomCell"];
cell.textLabel.text = [self.dataAraay objectAtIndex:indexPath.row];
return cell;
}
https://www.raywenderlich.com/129059/self-sizing-table-view-cells
UIImageView *imgarrow=[[UIImageView alloc]init ];
imgarrow.frame=CGRectMake(230,2, 27, 27);
imgarrow.image=[UIImage imageNamed:#"check_mark#2x.png"];
[cell addSubview:imgarrow];
//write same code for UILabel
//change rectmake values
Related
I am trying to load my UITextView on UItableViewCell with data but unable to set text. UITextViewDelegate is also set and attached to view controller. The text string is not empty as I checked it using debugger.
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CommentCellIdentifier];
//CommentCell is my custom cell with textView.
CommentCell *commentsCell = (CommentCell*)[tableView dequeueReusableCellWithIdentifier:CommentCellIdentifier forIndexPath:indexPath];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CommentCellIdentifier];
}
//Setting the images for all buttons in service row.
[commentsCell.deletecomment setImage:deleteComment forState:UIControlStateNormal];
[commentsCell.editcomment setImage:editComment forState:UIControlStateNormal];
commentsCell.deletecomment.layer.borderColor = [UIColor blackColor].CGColor;
commentsCell.editcomment.layer.borderColor = [UIColor blackColor].CGColor;
NSInteger commentIndex = 2;
//CommentsArray is NSArray with data.
[commentCell.comments setText:[NSString stringWithFormat:#"%#",[[commentsArray objectAtIndex:indexPath.row] objectAtIndex:commentIndex]]];
return cell;
}
Try changing this line:
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CommentCellIdentifier];
to this line:
CommentCell *cell = (CommentCell*)[tableView dequeueReusableCellWithIdentifier:CommentCellIdentifier];
I was using wrong cellname. Just replaced "commentCell" with "commentsCell" and everything starts working.
[commentsCell.comments setText:[NSString stringWithFormat:#"%#",[[commentsArray objectAtIndex:indexPath.row] objectAtIndex:commentIndex]]];`enter code here`
If you do not need scrolling the textview DISABLE SCROLLING in order for the text to appear.
I am not sure if this is caused by the fact that both the tableview and textview are descendants of UIScrollView, but it could be.
It helped me when I was experiencing the same issue
I've got an app that has a series of views transitioned via navigationController's pushViewController. The final step is a push of a view containing a tableView, and tableViewCell prototype. This transition was taking 4 seconds to complete at which time the UI hangs before the push visually occurs.
I narrowed it down to the call to dequeueReusableCellWithIdentifier for the first time. I then narrowed it down to one or more labels that contained custom fonts loaded in the project.
I was able to fix it by leaving the storyboard font as System, but dynamically assigning the custom font in the code.
My question is why does setting the font in storyboard make this so much slower, and can anything be done to fix that? I'd prefer to have it set in storyboard like the rest of the attributes.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *MyIdentifier = #"tableViewCell";
// The next line takes 4 seconds to run
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil){
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MyIdentifier];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
NSDictionary *data = _data[indexPath.section][indexPath.row];
UILabel *label1 = (UILabel*)[cell viewWithTag:1];
UILabel *label2 = (UILabel*)[cell viewWithTag:2];
UILabel *label3 = (UILabel*)[cell viewWithTag:3];
// Using this instead of storyboard defined fonts loads quickly
// label1.font = [UIFont fontWithName:#"Oxygen-Bold" size:18];
// label2.font = [UIFont fontWithName:#"OpenSans-Semibold" size:13];
// label3.font = [UIFont fontWithName:#"OpenSans-Semibold" size:13];
label1.text = data[#"name"];
label2.text = data[#"subtitle"];
label3.text = data[#"slogan"];
return cell;
}
I have spent a day trying to figure out why my dequeueReusableCellWithIdentifier taking 1 second for adding new Custom Cell on iOS 8 (on iOS 7 – works great).
Fixed by removing Custom Font from storyboard. Thank you so much for the hint.
That's decently a bug by Apple.
I'm trying to have a label in a UITableViewCell that can span two lines, but if there is only one line align it vertically to the first line.
The code to work out the label height (below) seems to work, but the label isn't getting relaid/repainted. If I scroll the cell off the view and back again, the label has the correct height.
I have tried [cell setNeedsLayout], [cell setNeedsDisplay], [titleLabel setNeedsLayout] and [titleLabel setNeedsLayout, and no combination has worked.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"ItemCell" forIndexPath:indexPath];
Item *item = (self.items)[indexPath.section][indexPath.row];
UILabel *titleLabel = (UILabel *)[cell viewWithTag:100];
titleLabel.text = item.title;
titleLabel.backgroundColor = [UIColor redColor];
// Some titles span two lines, so resize to fit the new content.
CGRect textRect = [titleLabel.attributedText boundingRectWithSize:CGSizeMake(titleLabel.frame.size.width, CGFLOAT_MAX) options:(NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading) context:nil];
CGRect labelRect = CGRectIntegral(CGRectMake(titleLabel.frame.origin.x,
titleLabel.frame.origin.y,
titleLabel.frame.size.width,
textRect.size.height));
NSLog(#"%#, %f", titleLabel.text, labelRect.size.height); // This logs out the correct height
titleLabel.frame = labelRect;
return cell;
}
please try my suggestion. may be it will help you with the reusability of cell in UITableview. Please Check the following points in you code:
What to do if you cell == nil while redrawing UITableView in iPhone. thats why you have to make condition like below for reusability of UITableViewCell.
// Get table View Cell
static NSString *CellIdentifier = #"ItemCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray *nib;
nib = [[NSBundle mainBundle] loadNibNamed:CellIdentifier owner:self options:nil];
cell = (UITableViewCell *) [nib objectAtIndex:0];
}
Please test it and let me know.
Turns out I'm using auto layout, which means I can't set the frame directly. Instead I need to add a height constraint and connect it to an IBOutlet on my UITableViewCell subclass.
Let's say that I have
- (UITableViewCell*)tableView:(UITableView*) cellForRowAtIndexPath:(NSIndexPath*)indexPath
{
static NSString *cellID = #"Cell Identifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID];
if (!cell)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellID];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
else
{
return cell;
}
UILabel * nameLabel = [[UILabel alloc] initWithFrame: CGRectMake( 0, 15, box.size.width, 19.0f)];
nameLabel.text = name;
[nameLabel setTextColor: [UIColor colorWithRed: 79.0f/255.0f green:79.0f/255.0f blue:79.0f/255.0f alpha:1.0f]];
[nameLabel setFont: [UIFont fontWithName: #"HelveticaNeue-Bold" size: 18.0f]];
[nameLabel setBackgroundColor: [UIColor clearColor]];
nameLabel.textAlignment = NSTextAlignmentCenter;
[cell addSubview: nameLabel];
}
What is that going to do?
If cell is not nil, and let's say you are at row 5, will it return the cell for row 5 with the exact text labels, etc?
Basically, my question is, if you have custom cells with labels, imageviews, etc. How do you use cellForRowAtIndexPath with dequeueReusableCellWithIdentifier?
You attempt to dequeue a cell. If the attempt failed (cell is nil), then you create a cell and configure it it's views (not the data inside the view). Afterwards, you populate the views with any data or settings that change cell-to-cell. Also, you should add any custom views to the cell's contentView, not the cell itself.
#define NAME_LABEL_TAG 1234
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellID = #"Cell Identifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellID];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
UILabel * nameLabel = [[UILabel alloc] initWithFrame: CGRectMake( 0, 15, box.size.width, 19.0f)];
nameLabel.tag = NAME_LABEL_TAG;
[nameLabel setTextColor: [UIColor colorWithRed: 79.0f/255.0f green:79.0f/255.0f blue:79.0f/255.0f alpha:1.0f]];
[nameLabel setFont: [UIFont fontWithName: #"HelveticaNeue-Bold" size: 18.0f]];
[nameLabel setBackgroundColor: [UIColor clearColor]];
nameLabel.textAlignment = NSTextAlignmentCenter;
[cell.contentView addSubview: nameLabel];
}
// Populate views with data and retrieve data for "name" variable
UILabel *nameLabel = (UILabel *)[cell.contentView viewWithTag:NAME_LABEL_TAG];
nameLabel.text = name;
// Return fully configured and populated cell
return cell;
}
If you have a complex cell, it's often easier to create it in Interface Builder and subclass UITableViewCell so you can have custom properties that refer to your Labels, Buttons, etc.
Yes, dequeueing a cell that you have already added those labels to will still have them and their text just as you left it when you created that particular cell.
Create a UITableViewCell subclass, let's call it MyTableViewCell that has properties holding the labels/imageViews/etc that it will need. Once you have either dequeued or alloc init'ed one of your MyTableViewCell, you can then set the text/images/etc on these properties. Like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"identifier";
MyTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[MyTableViewCell alloc] initWithStyle:UITableViewStylePlain reuseIdentifier:CellIdentifier];
}
cell.nameLabel.text = name;
cell.imageView.image = anImage;
return cell;
}
One major issue with your method is the conditionals surrounding dequeueing and creating. In your method you only set up the cell the label when it is alloc init'ed (you instantly return a dequeued cell without formatting it). However, you want this set up to occur for both dequeued and manually instantiated cells. Notice how this happens in my method, the return statement is at the very bottom. This will ensure that both created and reused cells have the appropriate data.
EDIT: One important thing I left out, you will instantiate the properties of your cell in its initWithStyle: reuseIdentifier: method and add them as subviews to the cell. This is so when you go to set the text of the label (or whatever) in your cellForRowAtIndexPath method, it has already been created. Basically the cell manages creating its own views and the UITableView delegate only has to worry about filling those views with data.
UITableView at first ask you for number of expected cells. Then it's load through - tableView:cellForRowAtIndexPath: method cells which is will be displayed + some to smooth scrolling, more objects it doesn't create. Created objects (by user) stored in table view and you can access not used through dequeueReusableCellWithIdentifier: method. TableView ask user for modifying currently created cells when it's scrolling. If here is free object - take it from dequeueReusableCellWithIdentifier: another - create new one.
in order to not have to allocate every single table cell, a table only allocates what is needed. If only 8 cells fit on a page then a table view will only allocate 8 cells or 9 i don't remember if it has a padding. When you scroll a tableview and the cell goes off the page the cell is queued up to be re-used, instead of re-allocating a new cell the table view takes an existing one this process is called dequeue-ing. When you make/allocate your cells you give it an identifier, this identifier is used to retrieve a cell that is marked with that string.
You can either use this
- (id)dequeueReusableCellWithIdentifier:(NSString *)identifier forIndexPath:(NSIndexPath *)indexPath
This is available after iOS 6
Or you can also register your class somewhere in ViewDidLoad and use ResuseIdentifier, so you don't have to write the ResuseIdentifier part in CellForRowAtIndexpath
- (void)registerClass:(Class)cellClass forCellReuseIdentifier:(NSString *)identifier NS_AVAILABLE_IOS(6_0)
Hope this helps you...
Where Do i add my custom tableview cell label in my UITableview when using NSCoder?
i already Created The UITableViewCell class and hooked everything up in interface builder.
I tried to replace cell.textLabel.text = oneName.name; with cell.label.text = oneName.name; and it just shows a black square.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if (!cell) {
cell = [[CustomCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
// Configure the cell...
NSUInteger row = [indexPath row];
DrillObject *oneName = [self.addDrill objectAtIndex:row];
cell.textLabel.text = oneName.name;
return cell;
}
Are you sure your label is of the right size? When using custom cells, I really recommend using the free Sensible TableView framework. The framework automatically loads your objects' data into the custom labels, and will also automatically resize the labels/cells whenever needed.
There are tow options to add label to your CustomCell class like you want here:
1- add a label onto your cell in xib file and the assign a tag for it and then create a getter like this:
-(UILabel*)label
{
id label = [self viewByTag:3];
if([label isKindOfClass:[UILabel class]])
{
return label;
}
return nil;
}
2- create the label in the init method and DONT forget to set the label background color to clear color like this:
UILabel *label = [UILabel alloc] initWithFrame:myFreame];
[label setBackgroundColor:[UIColor clearColor]];
// now you should have property on .h file like this
#property (nonatomic, weak) UILabel *label;
// so back to the init dont forget to do this
_label = label;
Thats it.