iOS 8 Self Sizing Cells With Accessory View - ios

Using iOS 8.3 simulator and Xcode 6.3.2.
I'm using the self sizing cells technique in iOS 8, and it works terrifically when the cell has no accessory view, but breaks when the cell has an accessory view. I set constraints on the label inside the cell:
Then I use an estimatedRowHeight and set the rowHeight to UITableViewAutomaticDimension (I'm omitting tableView:numberOfRowsInSection: here, but it just returns 3 for this example):
#implementation MyTableViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.tableView.estimatedRowHeight = 44.0f;
self.tableView.rowHeight = UITableViewAutomaticDimension;
}
...
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
MyCell *cell = (MyCell *)[tableView dequeueReusableCellWithIdentifier:#"myCell" forIndexPath:indexPath];
cell.titleLabel.text = #"Test comment Test comment Test comment Test comment Test comment Test comment Test comment Test comment Test comment Test comment Test comment ";
return cell;
}
#end
And bam, everything looks great:
But when I add an accessory view in the Storyboard, without changing any of the code:
the first cell goes to hell. Xcode's view debugger tells me the label height is 1785 points, and I had to use a gif to show it here:
I do notice that the other two cells are sized fine. I also note that when I rotate the simulator, the first cell gets resized properly, including after it's rotated back to portrait.
Does anyone know why the accessory view messes this up so badly, and what I can do to fix it? A sample project is available at http://github.com/UberJason/SelfSizingNightmare.

This is a bug indeed. I have sent your project to Apple. There is a reply from Apple.

It seems to be caused by the label inside the cell having numberOfLines = 0.
Although I'm not sure why, it looks as though adding the accessory to the cell leaves auto layout unable to calculate the height of the label when the table first loads.
I was able to fix your example by adding a preferred max width to the label - which seems to be enough to let the layout system figure out the height in time:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
MyCell *cell = (MyCell *)[tableView dequeueReusableCellWithIdentifier:#"myCell" forIndexPath:indexPath];
// Give the layout system something to help it estimate the label height
cell.titleLabel.preferredMaxLayoutWidth = self.titleLabel.bounds.size.width;
cell.titleLabel.text = #"Test comment Test comment Test comment Test comment Test comment Test comment Test comment Test comment Test comment Test comment Test comment ";
return cell;
}
Alternatively, calling [tableView reloadData] in viewDidAppear also seems to fix it.

Related

UITableviewCell subview appears only on scrolling or cell reuse (iOS)

As in the image below, the UITableView subview appears only on tableview reload or cell reuse (during scrolling, mostly). The blue color circle is what I want in my UITableViewCell. When it first appears, it will be a small dot as you can see in the picture, and on scrolling or refreshing the tableview, it appears as the full circle.
What can be the issue?
I use the following code in cellforRowAtIndexPath method
cell.categoryRoundBackground.layer.cornerRadius=cell.categoryRoundBackground.frame.size.height/2;
try using dequeueReusableCellWithIdentifier: forIndexPath:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
CustomTableViewCell *cell1 = (CustomTableViewCell *)[tableView dequeueReusableCellWithIdentifier:#"CustomID" forIndexPath:indexPath];
The most likely problem is that at the moment when you access your cell's frame height the first time by calling
cell.categoryRoundBackground.frame.size.height / 2
the cell has never been placed in a table view, it has no idea what its frame height is going to be, and so it uses some default value. The actual height depends on the value returned by your code in heightForRowAtIndexPath: method.
You can work around this problem by computing the frame size yourself. You should be able to do that, because your code supplies the value to heightForRowAtIndexPath:.
It's possible that you change the corner radius before that the view layouts its subviews.
You should try to put the line
cell.categoryRoundBackground.layer.cornerRadius=cell.categoryRoundBackground.frame.size.height/2;
inside
- (void)viewDidLayoutSubviews {}
You have to Override the method in CustomTableViewCell
- (void)layoutSubviews{
[super layoutSubviews];
self.categoryRoundBackground.layer.cornerRadius=self.categoryRoundBackground.frame.size.height/2;
self.categoryRoundBackground.layer.masksToBounds = YES;
}
and In CellForRowAtIndexPath: you have to write these lines at the end
// Update layout
[cell.contentView setNeedsLayout];
[cell.contentView layoutIfNeeded];
Hope it will solve your problem

Picture in Table View Cell Not Showing

In this project I have absolutely no code. In my main.storyboard I have a TableViewController with so far 1 cell. In that one cell I put an Image View in, then I selected the certain picture. The cell is 320 (Width) by 44 (Height). Everything seems fine in the main.storyboard, however I press run, the app opens but there is nothing there, only a bunch of lines.
Any help would be great I will give screenshots to anyone who needs them in order to help me solve this problem. I am using xCode 5.1
If you don't want to write any code than you must tableView type to static!
Check that.
Here's the snippet for TableViewDelegate. Hope this will help. Don't forget to thumbs up
Make sure you have this in your TableView
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return 1; ---->> should return 1
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return 10; ----->> return how many rows you want to show, mostly you write
return yourarray.count;
}
I think the problem will be in the method below
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = nil; ---->> Instead of UITableViewCell you need to
change to the class name of the
TableCell ( This is where your cell is
created)
cell = [tableView dequeueReusableCellWithIdentifier:#"Cell"];
if(!cell){
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle
reuseIdentifier:#"Cell"]; ---->>Instead of UITableViewCell you need to
change to the class name of the
TableCell ( This is where your cell is created)
}
cell.textLabel.text = #"Cell";
return cell;
}
You have to use either a static tableview that uses predefined cells or (by default) use a dynamic tableview - in that case you have to provide the cells in code by adhering to the tableviews data source protocol. Which you seem to not be doing now.
So, in interface builder, set the tableview to be static and you can build the cells in interface builder and they will be displayed. Make sure you delete the boilerplatecode in table viewcontroller that is given to you to easily implement the protocol (if you don't delete it, the default code returns nil off the cells and so none will get displayed).
When you get it working, find a nice tableview tutorial. I suggest ray wenderlich or the cs193p course on itunesU.

Dynamic sized labels inside a table not refreshing in ios

My table has cells which have several labels. I want one of these labels to fit its size so text begins right below the Title (remember that Labels align text vertically unless you fit its container).
Problem is, the very first time the table is loaded all labels' texts are succesfully populated but label sizes don't actually graphically apply until the NEXT time a refresh is asked. (if I ask for a reloadData with the exact same information, the labels' sizes work flawlessly).
This is some of my cellForRowAtIndexPath code:
cell.body.text = user.message;
[cell.body sizeToFit];
The only solution I've found so far is double calling [table reloadData] but this is an ugly solution. Any way I can fix this?
Edit: Previous code was a summary, I'll show the whole code here as requested:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
TwitterTweetCell *cell = [tableView dequeueReusableCellWithIdentifier:#"TwitterTweetCell"];
// Populate cell
TweetModelData *tweet = [self.twitterModelData.tweets objectAtIndex:[indexPath item]];
cell.tweetName.text = tweet.user;
cell.tweetChannel.text = tweet.userName;
cell.tweetBody.text = tweet.message;
[cell.tweetBody sizeToFit];
return cell;
}
Regarding cell size, everything is working ok. Depending on the size of the message each cell has a different size which was pre-calculated before.
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return ((TweetModelData *)[self.twitterModelData.tweets objectAtIndex:[indexPath item]]).tweetHeight + 30.0f;
}
I finally found it. Don't know the reason, but it seems disabling "Use autolayout" on my storyboard fixed it.
I'm guessing auto-layout was overwriting the layout changes I was applying so they had no effect until the next data reload.

Tableview showing the wrong size of cell [duplicate]

This question already has answers here:
UITableViewCell frame height not matching tableView:heightForRowAtIndexPath:
(3 answers)
Closed 9 years ago.
in table i am setting the height for cell using(heightForRowAtIndexPath)delegate of table view
the code is:
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 100;
}
but i am checking the size of cell in delegate method(cellForRowAtIndexPath) and code is:
- (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// Dequeue or create a cell
UITableViewCellStyle style = UITableViewCellStyleDefault;
UITableViewCell *cell = [aTableView dequeueReusableCellWithIdentifier:#"BaseCell"];
if (!cell)
cell = [[UITableViewCell alloc] initWithStyle:style reuseIdentifier:#"BaseCell"] ;
cell.textLabel.text = [NSString stringWithFormat:#"Cell %d", numberOfItems - indexPath.row];
NSLog(#"%f",cell.frame.size.height);
return cell;
}
when i am printing the value(frame of cell)cell on console its giving me 44.00.why this is happening even i am setting height of cell..please explain me and what to do to get the cell oh height 100..thanks in advance
actually i want to make custom type table view which support difrrent orientation of view and it is universal app so it will better to call the cell size in behalf of checking every time (iphone/ipad,diff orintation)....plz help me to accomplish requirement
If the cell is being shown correctly, and by correctly I mean with a height of 100 pixels as you have written in your tableView:heightForRowAtIndexPath:, I'm pretty sure it's because you're asking for the cell's height in the wrong place:
the cell has just been init'd with the default init method, the height returned is therefore the default one, of 44 pixels as nslog prompts in your console, on rendering the delegate sets the right height returned from your method and everything is set up correctly.
I had this issue months ago, for some reasons I needed to know cell's height in the tableView:cellForRowAtIndexPath: method, I came out with a workaround for that: I've stored all rowHeights values in an NSArray, since they were dynamic and different row by row according to their content.
I came out with something like
CGFloat height = [[heightsData objectAtIndex: indexPath.section] objectAtIndex: indexPath.row];
Do you have set your delegate for UITableViewDelegate ?
Try to put any log in your tableView:heightForRowAtIndexPath: method at first to see if your delegate is set.
hi friends dev had given explanation
NSLog(#"%f",[self tableView:tableView heightForRowAtIndexPath:indexPath]);

UILabel in a UITableViewCell With Dynamic Height

I'm having some problems implemented dynamic row heights in a UITableView - but it isn't the cells that I'm having a problem with, its the UILabel inside of the cell.
The cell just contains a UILabel to display text. My tableView:heightForRowAtIndexPath: is correctly resizing each cell by calculating the height of the label that will be in it using NSString's sizeWithFont: method.
I have a subclass of UITableViewCell that just holds the UILabel property that is hooked up in storyboard. In storyboard I've set its lines to 0 so it will use as many lines as it needs, and I've set its lineBreak to Word Wrap.
Here is how I'm setting up the cells:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
ExpandCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
SomeObject *object = self.tableObjects[index.row];
cell.myLabel.text = [object cellText];
[cell.myLabel sizeToFit];
return cell;
}
When I build this, I get my table view with the cell's all sized to the correct height for their content, but the labels are all 1 line that just runs off the side of the cells. However, if I scroll the table so cell's leave the screen, and then scroll back to them, their label will be resized correctly and the cell will look how I expected it to initially.
I have also attempted calculating the labels frame with the same method I'm calculating the row height with, and I get the same behavior - it doesn't draw correctly until it scrolls off of the screen and back on again.
I have found two ways to work around this, and neither are acceptable solutions.
First, if in viewDidAppear: I call reloadData on my tableview, the cells and labels draw themselves correctly the first time. This won't work for my situation because I will be adding and removing cells to this table, and I don't want to call reloadData every time a cell is added.
The second workaround seems very strange to me - if I leave the font settings at the default System Font 17 on the UILabel, the cells draw themselves correctly. As soon as I change the font size, it reverts to its behavior of not drawing a label correctly until it leaves the screen and comes back, or gets reloadData called on the tableView.
I'd appreciate any help with this one.
I ended up resolving this by alloc/init'ing the label in cellForRowAtIndexPath. I'm not entirely sure why this is a solution - but it appears the problem I was experiencing has to do with how storyboard (or when, perhaps?) creates the objects within the cell. If I alloc/init the label in the cell in cellForRowAtIndexPath, everything loads and sizes correctly.
So... my current fix is to check if the cell has my custom label in it. If it doesn't, I alloc/init the label and put it in the cell. If it does have one, as in its a cell that's been dequeued, then I just set the text in the label that is already there.
Not sure if its the best solution, but its working for now.
I ended up resolving this by unchecking the AutoSizing checkbox in IB. It is unclear why auto-layout was causing this problem.
I ran over the same problem and I end up solving it by calling [cell layoutIfNeeded] before return the cell
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
ExpandCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
SomeObject *object = self.tableObjects[index.row];
cell.myLabel.text = [object cellText];
[cell layoutIfNeeded];
return cell; }

Resources