I wish to have a table with some label and then I add a text field UI after the label.
I want the Label to be of some fixed size (say 150) and the rest of the cell width be occupied by the textfield.
Hence I set the frame of my cell.textLabel in function
cellForRowAtIndexPath
in this way
[cell.textLabel setFrame:CGRectMake(cell.textLabel.frame.origin.x, cell.textLabel.frame.origin.y, 150, cell.textLabel.frame.size.height)];
but this doesnt seem to work.
Any ideas why and What could be my solution to this?
why don't you add custom lable on your cell...
UILabel *mylabel = [[UILabel alloc] initWithFrame:CGRectMake(5,5, 150, 40)];
[cell.contentView addSubview:mylabel];
Otherwise you need to override -LayoutSubViews method and have to subclass UITableViewCell..
With a UITableViewCell its responsible for laying out its subviews. You have a very high level control over its layout using the UITableViewCellStyle enum.
If you want something custom, override UITableViewCell and add view to its content view or modify existing views. When you do this, be sure to do the layout in the layoutSubviews method, e.g.
- (void)layoutSubviews
{
[super layoutSubviews];
self.textLabel.frame = CGRectMake(self.textLabel.frame.origin.x,
self.textLabel.frame.origin.y,
150,
self.textLabel.frame.size.height);
}
The cell's frame will change when its added to the UITableView. When the cell's frame changes layoutSubviews is called to give you a chance to adjust its subviews. By default the UITableViewCell will do some if its own adjustments which is what was probably causing your issue.
Related
I change the frame of cells (add margins to the left and to the right) according to the code. The problem is cells update their frames only after they disappear and appear again via scrolling. I used table view's - reloadData as well, but it did't help. How do I force cells to be redrawn without scrolling?
- (UITableViewCell *) tableView: (UITableView *) tableView
cellForRowAtIndexPath: (NSIndexPath *) indexPath {
PersonTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: #"TableViewCellID"
forIndexPath: indexPath];
cell.frame = CGRectMake(20, cell.frame.origin.y, cell.frame.size.width-2*20, cell.frame.size.height);
/* tried any of those
[cell setNeedsDisplay];
[cell setNeedsLayout];
[cell layoutIfNeeded];
*/
return cell;
}
I'd recommend using .xibs for this. Much easier.
As far as I know, you are not able to change the frame of a cell in that manner. The cell's height is determined by heightForRowAtIndexPath, and the width is set to the width of the tableView.
You may be able to do it in some manner the way you are attempting, but the cleanest way I know is the following.
If you want there to be a margin around the cell, you can:
Create a nib for a UITableViewCell with a UIView containing all your views, and place a border using constraints.
Embed all your content inside a UIView (lets call this borderedContentView) and place this as the immediate subview of contentView
Place constraints relating borderedContentView to the contentView, with the leading, trailing, top and bottom constraints set to the values that create the border width you desire.
If your tableView has a backgroundColor, you'll have to set the contentView's backgroundColor to the same color as the tableView's backgroundColor so as to create the illusion of a margin. Do this in the tableView's delegate method willDisplayCell: or in a subclass of UITableViewCell awakeFromNib or other related method.
Bask in the glory of your margined cells.
You can also do this programmatically if you prefer not to use interface builder, but it is very easy to do in IB.
Hope this helps.
The solution to the problem is to override setFrame method of UITableViewCell. This way it perfectly works.
I have UIView in my tableview custom cell, when it appears i want to change the position of the the UIView based on certain condition.
i put this code in method cellForRowAtIndexPath:
CGRect newFrame = CGRectMake(11, 306, 302, 95);
[cell.myView setFrame:newFrame];
[cell setNeedsLayout];
I'm certain that the view already have the new position based on NSLog.
But it still in the same position in my screen.
Is there any steps that I missed?
The frame you are assigning based on certain condition, needs to be assigned inside LayoutSubviews method of UITableViewCell Class.
I have a UITableView with UITableViewCell subclass, this cell subclass contains UILabel. Text will load from internet.
I want to resize this UIlabel according to text.
My cell subclass UILabel will only know the size when text arrives from internet, means I have to do resizing of UILabel when cell is drawing like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// resizing label here
cell.mylabel ...
}
Is there any other way to do the same or more efficient way to do the same?
Can resizing can be done inside cell subclass?
When you update the text in the label in the cell you should call sizeToFit on your label to resize it:
[cell.myLabel sizeToFit];
Don't set the frame directly.
Personally, I would perform the sizeToFit on the UILabel inside the cell sub-class like so:
- (void)layoutSubviews
{
[super layoutSubviews];
[self.myLabel sizeToFit];
}
then when the text on the cell is updated (which should happen inside cellForRowAtIndexPath), invoke [cell setNeedsLayout] which will force the layoutSubviews method to fire on the cell.
This approach makes for good separation of concerns and makes the Cocoa framework work for you in the way it is meant to.
If you are hoping the for UILabel to resize vertically as well as horizontally, you will need to set the numberOfLines property to 0 like so:
self.myLabel.numberOfLines = 0;
Do a test to see which tableview delegate methods are called when the table is reloaded. I guess that as your waiting for the network to return your label details then the tableview will have already loaded in at least one time so you will after call [UITableView reloadData]; somewhere. Drop in a few log statements in the various delegate methods to see which is the best method for updating your label.
You can use the code to calculate the size of your label by its text. But you must assign label width or height firstly.
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping;
NSDictionary *attributes = #{NSFontAttributeName:[UIFont fontWithName:#"AppleSDGothicNeo-Regular" size:18], NSParagraphStyleAttributeName:paragraphStyle.copy};
CGRect cellSize = [yourText boundingRectWithSize:CGSizeMake(yourLabelWidth,9999) options:NSStringDrawingUsesLineFragmentOrigin attributes:attributes context:nil];
You should calculate your cell height just like user2239950 said.
It seems your cell height computation is rather intensive and so I think the best place to calculate it is just when you receive your text from internet.
Beside the NSString that stores your text, you should add an NSNumber property that store the height once it has been calculated and re-use it each time you need it.
I have a UITableView in a Storyboard where I have configured the Separator Inset to custom (0,0) as well as for the Prototype Cell (0,0).
While I can see the separator line is now 100% the width of the table, the UIImageView (subclassed to AsyncImageView) is still positioned to the right by 15px.
I've tried setting it on the table view on load and when the cell is constructed from a dequeue but I'm still seeing a padding on the left. (I've queried the cell and table and the inset and frame has zero left padding).
Is there anything I'm missing?
You have to subclass UITableViewCell and call layoutSubviews from your newly created UITableViewCell class, in the layoutSubviews method, use
- (void)layoutSubviews{
[super layoutSubviews];
self.imageView.frame = CGRectMake(0, 0, 50, 50); // override frame of your choice
}
I am trying to display cell's textLabel text to be visible on top of an image that spans the entire cell. I created a custom cell subclass just to make the image width be equal to the entire cell size like so:
- (void) layoutSubviews {
[super layoutSubviews];
self.imageView.frame = CGRectMake(0,0,320,80);
}
Now I would like to display my cells text on top of the cell. I do not have the cell text in the custom cell subclass, rather the code for it is in the TableViewController. Is there a way I can make the text display on top from within the view controller or do I have to put the text to be displayed in the custom cell subclass? Thank you
The best way is to make a custom cell, with an imageView and a label, and add them to the subview when the cell is initialized.
Then make sure they're hooked up to a property so you can configure the frame, as well as the content.
You can display the text in the TableViewController. Just make sure you set the image first before you set the text. I have provided code snippet in the method tableView:cellForRowAtIndexPath:
cell.imageView.image = theImage;
UILabel *textLabel = [[UILabel alloc] initWithFrame:CGRectMake(50.0, 0.0,100.0, 30.0)];
textLabel.text = #"Testing";
[cell.contentView addSubview:textLabel];