UITableViewCells of different heights place their accessoryViews at different X positions - iphone

My app has some table cells that vary in height. The cells can also have a UIButton set to be a detail disclosure button (round, blue with arrow) as their accessory view.
Depending on the height of the cell, the accessory view is positioned differently. At first I thought it was my layout code for my cell that was causing the problem, so I set up a quick independent test that uses vanilla UITableCells to remove the possibility that it could be my fault.
I set up a view in interface builder, and just added a view table cells to the view, set their heights to different values and then added a detail disclosure button to each. Nothing more, nothing less.
This is what I see:
UITableViewCells with different x values http://jasarien.com/jing/accessoryView_x_difference.png
I added the size guides (thanks to Xscope) so you can see the difference in the accessory view x positions.
The heights are:
top 37px
mid 68px
bottom 44px (default, untouched height)
If I increase the height any heigher than 68px the accessory view doesn't move any further to the left.
Is this a bug? Is there any way I can prevent this from happening?
Here's the test project to reproduce.
TableViewCellHeightsTest.zip

I got the same problem when I downloaded your file. Instead of setting the detail disclosure buttons manually and assigning them to cells as outlets, delete all disclosure indicators and try setting them this way instead:

Note: I set the background color of the content view to blue for ease of view.
Figure 1 (accessory view height is 17.0)
I was facing this problem and had the luxury of 2 colleagues helping me figure out the cause.
We find out that when using the default UITableViewCell (In my case, of style UITableViewCellStyleDefault though I believe it applies to all other styles), if your accessory view's height is anything above the magic number 16.0, the x position of the accessory view start to differ with the variance of height of the cell.
Figure 2 (accessory view height is 16.0)
My colleague had implemented a custom UITableViewCell and using subviews to layout content and was able to avoid this problem.
So you have 3 options:
Restrict your accessory view's height to 16.0 and below.
Use a custom UITableViewCell and layout your own content as subviews.
Use the default accessory type.
Figure 3 (default accessory type UITableViewCellAccessoryDetailDisclosureButton)

I was having the same issue and fixed it by making the custom accessory view the same height as the cell.

Related

estimatedRowHeight API breaks custom cell sometimes

I am using the new iOS 8 API:
self.tableView.estimatedRowHeight = 60
self.tableView.rowHeight = UITableViewAutomaticDimension
This works well in most situations, but it breaks my custom cell if the height of the cell is calculated dynamically sometimes:
Some more information:
It seems tableview does calculate the height correctly(it has empty space between 2 cells), but somehow part of the cell is hidden.
the shown part (the part with white background) of the cell is as height as the cell in my xib file is.
it only happens when the calculated height of the cell is bigger than the hight I set in xib file(which is 60 in my case). If the height is equal to the cell height in xib, it works well. I didn't set any constraint on the height in my xib though.
I saw that you created custom cells via xib files and Interface Builder, correct?
There are settings to use custom heights and set the custom heights in both the cell and table view details in IB. For the cell, I think it's the height property and you check the custom box and input your height.
For the table view, there's a row height property that you check custom for and choose your height there.
I've had wonky stuff happen to my custom cells without making sure these settings are appropriate in IB.
Let me know if that works or if there is another problem!

Resize subviews in table view when editing using auto layout

I have a table view with prototype cells. Currently I have only added a label to the cell. When enabling edit mode, a delete button will appear animating the cell smaller but the label doesn't reposition. This used to be no problem with autoresizing masks but now I can't seem to get it to work.
Does anyone know how I should configure auto layout to have the label positioned inside the cell when in edit mode?
I searched some more and found that it is necessary to remove the horizontal spacing constraint that Interface Builder adds, as this is relative to the UITableViewCell and not the contentView and then add a constraint which is relative to the content view.
You can read more about this in this answer to a similar issue.

Drawing really long text on iPhone

Currently I have UITableViewCell's that hold sometimes really long text (up to 50,000 pixels in height after drawing). However the UITableView delegate documentation says that cells shouldn't be higher than 2009 pixels in height (any ideas why?).
It's only the first section in my table view that has the really long cell, so instead of using a cell for the first section, I thought I'd create a UIScrollView, put a UITextView as the first "cell" and add it to the scrollView, and then add the tableView to the scroll view as well (under the textView). However, having a 50,000 px high UITextView is causing huge memory problems.
What are my options? I know I could use a UITextView that scrolls, but to have a scrollable UITextView with a tableView just causes complicated scrolling behavior. I want to mimic the scrolling of a tableView.
I didn't know it would be an issue to have a 50,000 px high view in a UIScrollView. I thought that's what UIScrollView's are for? Do I have any alternatives?
I would seriously question the UI design where you must render text that large as part of a table cell. The best option would be to put a reasonably-sized summary in a cell with cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;, build a separate view for the long text, and let the user navigate to that view by clicking the disclosure indicator.
As a side note, you could also put a scroll view inside the initial table cell (not all cells must be of the same type; you can make one with a scroll view in it, and use it for the cell at index zero). It's not going to be as usable as the regular cell with a disclosure indicator, though.

Custom UITableViewCell for a grouped table view

I have a grouped table view.
I'm trying to create a custom cell using interface builder, however when I'm putting a label, or a view as a subview for the cell, and stretching it to the entire cell, when I run the app the label goes beyond the cell's dimensions.
Any reason why it would do that ?
I tried to play with the resizing mask to no avail.
When the table is plain, there's no problem.
I guess I'm doing something wrong, cause it's not suppose to be that complicated.
I don't have much experience in creating UITableViewCells with IB, but I would recommend adding your subviews programmatically using a UITableViewCell subclass. Your issue is that the subviews are added directly to the UITableViewCell view, and the left and right margin are part of that view.
The UITableViewCell subview that represents the actual "active" space (the white part of the cell) is contentView. If you add a subview to contentView, then it shouldn't appear outside it. In other words, CGPointZero of contentView is the top left point of the white space.

UITableViewCell's contentView's width with a given accessory type

On an iPhone, how do you figure out the width of a table view cell's content view when it is showing a certain accessory view (disclosure indicator, etc)?
I need this in order to calculate the correct cell height for cells that contain wrapping, variable-length text. But when the table view delegate is asked for a cell height, it doesn't actually have the actual cell instance, so it can't just query the content view bounds directly.
I can easily hard-code a 20-pixel margin on the right which appears to be accurate for a plain style table view in portrait orientation with a disclosure indicator, but would prefer to do it the Right Way so that it keeps working if Apple decides to tweak the margin.
(This is related to this question.)
Personally, I would just hard code the values -- simpler and things will break in a predictable way.
But were I to do this programmatically, I would create a UITableViewCell, set up the editing properties / accessory views you need to measure, and then ask it how big its contentView is.
Of course I would probably heavily cache this -- doing allocations when asking UITableView asks you for height information sounds to me like it would be slow (check with a profiler first though, as always).
I would have a subclass of UITableViewCell that holds all its subelements. You can cange the frame of certain elements when the cell enters and exists editing mode. There is a good example of this in Apple's Table View Programming guide under the section on creating a custom table view cell.
I believe the UITableViewCell's contentView property is the view that contains your labels etc., so the width of that should be your available size to use.