Mysterious rounded line appears at top of custom UITableViewCell - iphone

I have a mysterious problem with a custom subclass of UITableViewCell. The cell subclass is doing some relatively complex layout of UIControl instances, and then storing its height (based on the layout of those controls) in an ivar. I am performing zero custom drawing (I'm not overriding drawRect: at all).
For some reason, there is this strange rounded-corner-looking thing drawing at the top of the cell no matter what the height. I'm not changing the height of the cell's frame itself or anything; I'm just using tableView:heightForRowAtIndexPath:indexPath in my table view delegate. Everything else about the cell renders fineā€”it's just this one strange part.
Has anyone ever seen anything like this happen before? I am using iOS 4.2.

Turns out you have to call [super layoutSubviews] in your subclass' layoutSubviews method even though Apple's API docs say that the default implementation does nothing. Doing this fixed this problem (as well as turning off all autoresizing of subviews).

Related

Where to build custom UITableViewCell: in layoutSubviews or initWithStyle:reuseIdentifier?

As I understand, there seem to be three ways of laying out a custom table view cell:
In Interface Builder.
In layoutSubviews.
In initWithStyle:reuseIdentifier:.
What's the difference between the second and third methods? Also, why not drawRect?
P.S. I'm following Chapter 9 of the book Pro iOS Table Views by Tim Duckett, where we're building custom UITableViewCells. The author shows how to lay out the cell in the same order as above, but I don't know whats the difference between the last two since they both do away with IB. I noticed, though, that the author simply sets the frames in layoutSubviews unlike in initWithStyle:reuseIdentifier: where properties concerning the look of a view are set (e.g., background image, background color, etc.).
You should create your cell subviews in
- initWithStyle: (UITableViewCellStyle) style reuseIdentifier: (NSString*) resueIdentifier
And layout them in layoutSubviews.
-initWithStyle:reuseIdentifier method will be called once at initialization, but you cell may have incorrect frame at this moment.
Thats why you need to layout it in layoutSubviews method, it's called when cell needs to update layout, for example, when autorotation occurs. So if you will layout subviews in this method, you will have valid cell's frame and correct subviews layout.
-[UIView layoutSubviews]
gives you much more control on the way a view is relayout (I suppose in your book example it is done in the table cell contentView).
When you use a NIB file what you do is simply to recreate in memory the view hierarchy with some properties set, but the nib has not the dynamic capability to relayout a cell (or it is limited to the spring/struct or auto-layout capabilities). If you don't use the NIB you must create this hierarchy programmatically.
Especially in a table view cell subclass, you can add to it many properties that could change the way the cell is relayout, e.g. showing a thumbnail image or not, display a certain label or not, and in such cases you probably you need the layoutSubviews method to update the cell layout taking into account all the possible layouts due to different properties values.

using a subclass of UITableViewCell in IB - Why is there a need to override drawRect:?

https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/TableView_iPhone/TableViewCells/TableViewCells.html#//apple_ref/doc/uid/TP40007451-CH7-SW12
In relation to subclassing UITableViewCell, the above link talks about the need to override drawRect: to explicitly draw the cells content.
But why is this necessary? Can we not just create a subclass of UITableViewCell in IB, add the required subviews in IB, create the required outlet connections and then set the values of these subviews programmatically.
Why is there a need to override drawRect:?
You're not required to override drawRect: any more than you are required to use the textField implementation methods for UIAlertView. Drawing the cell's content, however, can boost performance in some cases, particularly if you have multiple non-opaque layers and can draw them into one opaque cell, because the renderer doesn't have to composite and blend multiple times. By drawing into a single opaque layer, the hardware only has to blend right before it gets displayed on screen.
Note that if you don't experience lag or if you have animation in each cell themselves, then drawing will not help you.
I can't find in your link where it says you are supposed to subclass DrawRect method.
I don't think apple recommand it.
I have developped an entire app with a lot of tableControllers with custom tableViewCells, using nib files and never subclassing drawRect method.
I never noticed any problem, and my app passed successfully the app store review.

UITableview gets jerky while scrolling because of custom cell creation?

I have used custom cell class for my uitableview and used in cellForRowAtIndexPath method.
In that method cellIdentifier is already been defined and even cell property is used as dequeueReusable.
But while scrolling my tableview each time my custom cell objects gets created and its methods get called. Because of that on device, scrolling gets jerky effects.
I have also checked if(cell==nil) and inside that i m assigning my image and labels property for that custom cell. But each and every time, this condition gets true and program pointer goes inside that condition.
Please guide me on this.
If possible please provide some example code.
Thanks in advance
Mrunal.
I have pretty complex UITableViewCell. For me the trick was to set the shouldRasterize of the cell layer's to YES. But it introduced blurry text. To avoid that I set the scale - [self.layer setRasterizationScale:[[UIScreen mainScreen] scale]].
As many others have pointed out, we can't really help you unless you post your code (your CellForRowAtIndexPath should be enough).
Generally speaking there are many ways of improving scrolling performance on UITableViews and the top ones I use are (and have used in other Stack Overflow answers):
Always reuse cells, use the dequeuereusablecellwithidentifier when
creating new cells. This prevents the overhead of the OS creating
and destroying lots of objects when scrolling fast.
Collapse the view hierarchy of the cell. Instead of having lots of
views and subviews, create a custom view and do all your cell
drawing in the drawRect. Apps like Twitter use this approach for
super fast cell drawing.
Ensure your images are opaque. You can do this by ensuring all image
assets don't have alpha channels baked into them and by setting the
layer's opaque property to YES.
If you are setting any properties of the cell image's layer property (like shadow or rounded rectangles) this can affect scrolling performance. Setting the layer's shouldRasterize to YES will help, but you should really think hard about doing any intensive drawing operations within cells.
For more details see http://developer.apple.com/library/ios/#samplecode/TableViewSuite/Introduction/Intro.html%23//apple_ref/doc/uid/DTS40007318-Intro-DontLinkElementID_2
This is happening because of ImageView. Create your labels and imageViews inside if(cell == nil) in CellAtIndexPathMehtod of UITableView and assign its value outside this if.
And If your images are loading from server then use Asynchrnous image loading

UITableView separators disappears?

in my uitableview, i subclassed uitableviewcell's, and i added a subview to the contentview with flexible width and height. the cells are of dynamic height.
when the tableview first loads, everything is fine. however, as i start to scroll around, separators start disappearing, and they happen at the same places every launch. scrolling around some more will recover the lost separators.
anyone else encounter this?
I don't know how specific this will be to your project, but I'll tell you what I figured out. Overriding my layoutSubviews method was the problem. I looked at the view hierarchy of my cell before and after I called [super layoutSubviews] and discovered that this method was making the contentView 1 pixel shorter and added a new view below it 1 pixel high with a background color of 0.88/0.88/0.88.
If you can't live with some of the side effects of the superclass implementation, it looks like this view must be added manually.
The problem was related to the dynamic heights. Using either ceilf or floorf solved the problem.

LayoutSubviews for Custom UITableViewCell and UIView

I have a custom UITableViewCell. It has a UIView which is added to the "contentView" of the UITableViewCell. For any update, I'm redrawing that UIView by calling its "setNeedsDisplay" and implementing drawing inside "drawRect" method of the UIView.
The UITableViewCell overrides "willTransitionToState" and according to the bit mask value, asks the UIView to redraw.
Because I'm asking the UIView to redraw itself again, every time I do a "swipe to delete", I see the cell "flicker" a moment; even the text that didn't move position due to the Delete button suffers from a flicker since everything is being redrawn.
I'm aware that a possible solution is not to call "setNeedsDisplay" of the UIView from the "willTransitionToState" but instead call "setNeedsLayout" and have the UIView implement "layoutSubviews".
This is where I'm stuck at: how can I re-layout my UIView since everything inside my UIView is "drawn" (I use "drawInRect" and "drawAtPoint" methods for strings and images). There is also a string on the right side that I wanna hide when the "Delete" button appears (like in the Messages app in iPhone).
How can I do this by doing re-layout instead of re-draw?
Thank you!!!
I think there's an issue with your approach. Rather than draw everything, it's better to set up your subviews in an init method, or in the NIB.
In the willTransitionToState method, update whatever subviews according to the state transition.
In layoutSubviews, update each subview's origin and size as required.
Here's some detail from the willTransitionToState documentation. Although, I'm sure you'd have seen this already:
Subclasses of UITableViewCell can implement this method to animate additional changes to a cell when it is changing state. UITableViewCell calls this method whenever a cell transitions between states, such as from a normal state (the default) to editing mode. The custom cell can set up and position any new views that appear with the new state. The cell then receives a layoutSubviews message (UIView) in which it can position these new views in their final locations for the new state. Subclasses must always call super when overriding this method.