How to update UITableViewCell height because of text entered into UITextView - ios

I have different examples where we can update the UITableViewCell height based on growing UITextView which actually is working for me. The issue which I am facing is, I have more subviews below UITextView inside a UITableViewCell. This way, the cell's height updates but the position of the subviews remain fixed which causes overlap of UITextView and the subviews.
Just to mention, I am not using auto layout.
How do I fix this ?
These are the three screenshots which will help in understanding my issue :
1. Before TextView is shown :
2. After TextView is shown :
3. After text is entered :

I'm assuming you are using auto layout for this cell (but we could use a code example or Xcode screenshot to help you more specifically). If you are using auto layout, you'll want to make sure that:
You have a constraint between the UITextView and the other UIView subviews below it in the cell
The other UIView subviews are eventually constrained to the bottom of the cell.

Because UITableViewCells are reused, you will find that when adding objects to the contentView, those objects will also be reused without being removed, leading to overlapping subviews. The way around this it to start your cellForRowAtIndexPath with the following code:
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [aTableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
for (UIView * view in [cell.contentView subviews]) {
// clears the cell before reusing
[view removeFromSuperview];
}
Hope this helps.

Are you using auto layout? I have done this before several times with UITableViewCells though it’s mainly been with UILabel and not UITextView.
Your problem might be resolved with auto layout. You layout all your subviews (inside of UITableViewCell) relative to each other. If one view (i.e. UITextView) changes size the other views will then adjust relative to that view. Here are a few useful links.
This isn’t specific to UITableViewCell but has a lot of good examples of various scenarios.
Stanford University Developing iOS 7 Apps: Lecture 9 - Animation and Autolayout
https://www.youtube.com/watch?v=r1sc7NI6-wo

Related

UITableViewCell display under other view

I cannot convince UITableViewCell to display under another view as per the attached image. It happens when I embed UITableView into UIViewController.
VoucherTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"VoucherTableViewCell" forIndexPath:indexPath];
if (cell == nil) {
cell = [[VoucherTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"VoucherTableViewCell"];
}
Image one is before scrolling up.
Image two is the problem.
just try in viewDidLoad this code
self.edgesForExtendedLayout = UIRectEdgeNone;
self.tableView.contentInset = UIEdgeInsetsMake(0, 0, yourTopiew.height, 0);
Follow these steps...
1. Make sure you are using correct Size class for iPhone.
2. Remove your tableView constraints if any.
3. Position your tableView correctly. (Bottom of your buttons)
4. Add top,bottom, left, right constraint to tableView.
5. Also make sure your buttons have correct constraints.
The problem is with the frame and positioning of your table view.
First the table view is places above the buttons in the view hierarchy in you nib file.
Second you need to set the frame and constraints of the tableview as such that it starts right from where the buttons end.

Auto-layout issue on scroll

I have .xib which has some auto-layout like so (might need to click to zoom):
Nothing special, I have 13pt spacing with the border of the superview.
This xib is then loaded in the code into a tableViewCell.
I'm also setting the height in the viewDidLoad of the table like so:
[self.tableView setEstimatedRowHeight:40];
[self.tableView setRowHeight:UITableViewAutomaticDimension];
My cellForRowAtIndexPath is:
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseId forIndexPath:indexPath];
---OR--- (Both don't make a difference)
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseId];
Now the fun begins. The auto-layout works when it wants to, and sometimes I scroll a cell out of view, bring it back and it's not the same size. See image below:
Any ideas on what I am doing wrong?
PS: Not in the screengrab here, but I do have some cells with a lot of text that look like the same height of the big cell on left.
PPS: I've tried the following with no success (based on this article http://useyourloaf.com/blog/2014/08/07/self-sizing-table-view-cells.html ):
Added [self.tableView reloadData]; in the viewDidLoad
I removed the explicit and preferred width on the label
I had the same issue, it seems if you set the text of the label exclusively in - tableView:willDisplayCell:forRowAtIndexPath: instead of - tableView:cellForRowAtIndexPath: then you will observe the behaviour of random incorrectly sized cells.
I've created a test project to demonstrate this https://github.com/sja26/iOS-TestSelfSizingCellsWithUILabel
One reason you get this behaviour - you use
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
Try to use
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
instead. This will reuse your cell with the same size as needed
And, of course check heightForRowAtIndexPath method for properly setup value

UITableView - Sliding content inside each cell horizontally

This is my first native iOS app...
Exactly like the iTunes app on iOS does, by having a tableview that you can scroll vertically, and then each row, you can scroll independently horizontally. At least this is ow I imagine it to work.
how would I implement this? I imagine a view inside each tableCell that can scroll horizontally?
Can any one please shed some light on this and what I might read or try to do
You can add the scroll view into the cells content view and then just the content size property of the scroll view to whatever length you want. Here I have set the width of scroll view to 1000 and the height to 44 (which is the default size of the UITableViewCell).
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
UIScrollView *vwScroll = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
vwScroll.backgroundColor = [UIColor scrollViewTexturedBackgroundColor];
vwScroll.contentSize = CGSizeMake(1000, 44);
[cell.contentView addSubview:vwScroll];
return cell;
}
The only option I can think of is if you place a UIScrollView inside the UITableViewCell's view.
Note though, that this may cause problems in regard to the vertical scrolling behavior of the UITableView itself.
To achieve independently scrolling rows similar to the App Store app on iOS, one approach is to nest a Collection View inside a Table View Cell.
I wrote a Swift tutorial with step-by-step instructions on the setup, including how to wire the Collection View dataSource to the Table View Cell.
The tutorial includes a working sample project on GitHub and a link to an Objective-C tutorial.
I believe the free Sensible TableView framework provides these cells out of the box. Should give you a good head start since you're still starting out. Hope this helps.

UIButton in custom UITableViewCell stop working after rotation

Problem:
I used custom UITalbeViewCell that contains two buttons, they work fine in the portrait orientation. After the rotation, they all stop responding to the button touch up inside function. Some people having problems that their buttons couldn't drew correctly after rotation. Mine looked fine since the buttons are showing in the right places after rotation, but they do not respond to the button press anymore.
For this specific view in my app, I used a UIPageController to implement multi pages in a view, and for the view (name it EmbeddedView for now) embedded in the page's scroll controller, there is a UITableView that contains custom UITableViewCell. Custom table view cell only has a nib, the file's owner is EmbeddedView.
in EmbeddedView:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
/*===== This is the most memory efficient way of creating table view cells =====*/
static NSString *CellIdentifier = #"CellIdentifier";
CustomTableViewCell *cell = (CustomTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
[[self customTableCellNib] instantiateWithOwner:self options:nil];
cell = [self customTableCell];
[self setCustomTableCell:nil];
}
}
What I tried:
I created another nib file for the custom table view cell and used it in -cellForRowAtIndexPath(), I checked the orientation and dynamically create the cell by using different nib, no luck.
I added [tableview reloadData] in -didRotateFromInterfaceOrientation(), didn't do anything.
Would someone point me to the right direction please? Any help is appreciated.
This is the table view Autosizing in IB:
It looks right but the buttons are not working
Update: I tried to specify different Autosizing masks in IB for the table view, and the results are showing below:
<1>
<2>
<3>
<4>
Have you checked how the superview is being resized?
Check if the superview has 'clip to bounds' checked. If it is not check it. That will make the view clip its contents so you see if it is resizing ok.
I'd say the superview is not sizing correctly and because of that the touch events are not well delivered also.
EDIT - So this was the tip that could let the OP reach the solution:
What I normally do in cases like of unexpected behavior in resizing and such is to change every view in the hierarchy to a different, well recognizable, color. Right now you have view A and view B with the same background color (or clear) and you don't see if view B is resizing well. Good luck.

On iOS, what is the difference between adding a subview to a UITableViewCell object "cell" vs to "cell.contentView"?

In the following code, if we do [cell addSubview: someLabel] vs [cell.contentView addSubview: someLabel], they seem to work the same. Is there any difference doing one or the other? (the custom cell in the real code is adding UIImageView and UILabel) (UIView, on the other hand, doesn't have contentView, so we don't need to add subview to its contentView. UITableViewCell is a subclass of UIView by the way)
-(UITableViewCell *) tableView:(UITableView *) tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = nil;
if ([tableView isEqual:self.songsTableView]){
static NSString *TableViewCellIdentifier = #"MyCells";
cell = [tableView dequeueReusableCellWithIdentifier:TableViewCellIdentifier];
if (cell == nil){
cell = [[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:TableViewCellIdentifier];
}
// ... some code to create a UILabel (not shown here)
[cell addSubview: someLabel]; // vs using [cell.contentView addSubView: ...]
I believe If I am not wrong, the contentView is a subview of UITableViewCell.
If you look at this page here, you can see there are actually 3 subviews in a UITableViewCell
I think by default, the Editing Control is hidden until you enter edit mode for a table in which case, the Editing Control appears (the minus button left of each row) and your contentView gets resized and pushed to the right. This is probably what gives the "proper animation" effect mentioned by the other answer.
To test the difference, try adding a subview such as UILabel with text, to the cell rather than the cell.contentView. When you add it to cell rather than cell.contentView and you enter edit mode for your table, I believe your UILabel will not resize, you will see the edit button ontop/below the minus sign button.
Placing your views in the contentView affects proper animation in and out of edit mode. Place all of your subviews in contentView when you're not subclassing, which should be all of the time unless you know what you're doing.

Resources