I have a TableView and I implemented this method to return a Cell for each row:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
And in my Cell, I have a ImageView to the left of the cell, follow by a Label to the right of the ImageView.
However, in come case, I want to make the ImageView disappears and have just a Label and move the Label to where the ImageView were.
So I add the following condition in the cellForRowAtIndexPath method
if (//imageView should disappear)
{
cell.image.frame = CGRectMake(cell.image.frame.origin.x,
cell.image.frame.origin.y,
0, 0); // set widht and height of image to 0.
cell.label.frame= CGRectMake(cell.image.frame.origin.x,
cell.image.frame.origin.y,
cell.label.frame.size.width,
cell.label.frame.size.height);
// move the label to where the image were.
[cell layoutIfNeeded];
}
I step thru the code in the debugger, it does get executed. But when I run it, nothing get changed. The image view still there and the Label still to the right of Image View.
Can you please tell me what am I missing?
Thank you.
Related
I have used a UIScroll View. It has a contentView (of type UIView) which again has a questionView (UIView) and a _questionTableView (UITableView). I know this is not the right practice but the design required me to implement like this. Scroll is working perfectly fine.
I have a total of 8 cells and only 4 cells are visible when the screen is opened first. Upon tapping on any of these 4 cells
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
is called.
Upon scrolling down, rest of the cells become visible. But tapping on them doesn't trigger didSelectRowAtIndexPath
I read various stack overflow posts on this issue (to enable tapping on cells) where people suggested to increase the content view size/ scrollView's contentSize/ tableView's height. I tried all of them but no luck.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
MyCell *cell = [tableView dequeueReusableCellWithIdentifier:#"myCell"];
_scrollView.contentSize = CGSizeMake(_questionTableView.frame.size.width, 1000);
_contentView.frame = CGRectMake(0, 0, _questionTableView.frame.size.width * 2, 1000);
_questionTableView.frame = CGRectMake(0, 0, _qTableView.frame.size.width , 500);
self.scrollView.delegate = self;
return cell;
}
Is there nay way to make the cells tappable?
EDIT: I experimented some more and I realized that after several taps on the cell, the method - didSelectRowAtIndexPath is called. But those are some random taps 5-6 times. Couldn't identify a pattern.
Try to deselect property "Delays Content Touches" in your parent scroll view. It may help!
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
I have a standard UINavigationController with a UITableViewController at it's root. In IB, I paint a prototype cell with a label and a UIView. The UIView contains a button. I'd like the UIView to be x-aligned after the label, as a function of the length of text in the label.
In IB, the view's left side is initially aligned with the label's left side. There are no layout constraints in IB.
Here's my cellForRowAtIndexPath ...
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 5;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
NSArray *labels = #[#"SOME STRING", #"SHORTER", #"A VERY MUCH LONGER ONE", #"REGULAR ONE", #"TINY"];
UILabel *label = (UILabel *)[cell viewWithTag:32];
label.text = labels[indexPath.row];
UIView *view = [cell viewWithTag:33];
CGSize size = [label.text sizeWithAttributes:#{NSFontAttributeName:label.font}];
view.frame = CGRectOffset(label.frame, size.width, 0);
return cell;
}
Two problems: I've set breakpoints and watch this code running the first time the view appears. I see the view.frame get changed for each row, but the view does not change position. I remains in it's IB-position, right on top of the label. If I scroll the table down, the views on lower cells (presumably reused) are in the desired position. If I scroll back up, the upper rows are also good. It just fails to work on the initial presentation of the upper cells.
Second problem is that the button contained in only the first row has a subtle, strange effect applied to it's text, like a blur. See attached...
First Row Button (zoomed in mac preview... see that extra blur on the left edge of the letters?)
Other Row Buttons
Stuff I tried:
I've tried a few variations, including using a regular view controller with a table view added (rather than a UITableViewController). I've found that if I reloadData on viewDidAppear, that solves the placement problem, but not the blurry button. (Also, I don't like the idea of needing to reload on viewDidAppear). Doing so on viewWillAppear has no effect at all. I've also tried animating the label change slowly. It happens, but again, only on the second time the cell is configured. I try changing the UIView color to prove the code is being run. The color change happens every time, including the first time, but not the view placement. Am I nuts?
For problem 1:
Try calling [cell layoutIfNeeded] before returning the cell, there should be no performance hit when it does not need relayout.
For problem 2:
try calling CGRectIntegral before you set the frame. ie
view.frame = CGRectIntegral( CGRectOffset(label.frame, size.width, 0) );
I have UiTableView. Cells on it by clicking change itself height. I need to add custom separator lines. I alwaays add to the top of cell. So all work fine, but last cell haven't seporator line on the bottom, and user cann't see the end of tableview. I try to add next code in
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
and then try use it in
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
I create in the begin new UIImageView
#implementation MovieSessionsVC
...
UIImageView *seporatorView;
}
And this my code:
[seporatorView removeFromSuperview];
if (indexPath.row == self.sessions.count - 1) {
seporatorView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"seporator.png"]];
if([self cellIsSelected:indexPath])
seporatorView.frame = CGRectMake(0, 106, cell.width, 0.5);
else
seporatorView.frame = CGRectMake(0, 63, cell.width, 0.5);
[cell addSubview:seporatorView];
}
I use self.sessions.count for number of rows, and heoght of my cells is 64 and 107 when selected
So line appear and work fine, but when I pick up my tableview on maximum it is disappear
If it isonly the last cell where you want to add something to, a line in your case, then it is probalby the easiest to draw the line on top of the footer view. You can create a UIView and assign that to the tableFooterView property of UITableView. That footer may just have a height of 1.0 and is filled with a colour.
You can of course draw a line in drawInRect of that footerView. For doing so you will need to subclass UIView. But I think that some standard UIView with a background colour and a height of 1.0 would do.
Just set the resize property of the separator image same as the image below
The separator image to sit to the bottom on any cell resize.. Make sure the cell resize property is all selected..
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; }