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

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.

Related

Design suggestion required in UITableView Swift

I just need a suggestion to Implement tableView for the application.
According to reference image is this a collectionView used in tableView?
Actually I want to implement 4 views on the top of the tableView something like Reminder app of apple. Obviously not to copy design but I need 4 views within UITableView.
These 4 views are also scrollable as its the part of tableview.
I am confused in this how can I achieve this design image attached.
my main concern is 4 top views tile style.
Image
In your case you may better use tableHeaderView property of UITableView and set your "reminder" view as tableHeaderView:
self.tableView.tableHeaderView = myReminderView
If you need to implement it as a cell, for some reasons, just create a custom UITableViewCell subclass and add UICollectionView with all DataSources/Delegates implementations you need inside this cell class.

UITextView in UITableViewCell subclass, how to keep the data separate from the view

So I don't know what the best way to follow MVC is. Similar to the address books app, I want to have a UITableVeiewcell that has the ability to edit notes. I figured I would do that with a UITextView in a UITableViewCell subclass. My subclass has just that as a property, and a label that says "notes". I can see a few use cases that I need to consider,
1) when they are done editing and click outside or hit return.
2) when the text goes beyond the size of the cell I need to resize the cell.
Because my UITextView is in IB, is there a good way to define the delegate methods for the UITextView since my UITableView is in another ViewController subclass? Like how do I pass that information back?
Or, is it better to create my UITableViewCell subclass in code since it's just a couple of items so all my delegate and resizing code is done in the view controller class?
Thanks!
After text field editing was finished, you can store it's value in some dictionary in your controller. You can use cell's indexPath as key in this dictionary. In such way you will not lose your data with dequeue cells.
To resize cell you must call reloadData method and change rowHeight property of entire tableView or implement tableView:heightForRowAtIndexPath: delegate method to set needed row height to current cell.
I haven't use UIKit since iOS 3.1, so the second part of my answer can be out of date, but I hope it will help you =)

How to fix the header and first row in a UITableView

I´m new trying to make some apps using objective c, so I´ve an idea using uitableview but I don't imagine how can I get this.
I´m trying to do something like you do in a spreadsheet where you have a fixed header and the first column too
So when scroll the uitableview vertically the header will stay visible at top of the table and rows will change
And finally when you scroll in horizontal direction the first cell of the row will stay visible and will change the header depending of how you scroll the uitableview
I hope you could give me an idea how to get this, because I don't imagine how to do this, also I don´t have a lot of experience with this programming language.
Thanks!
In a non-grouped table, section headers "stick" at the top of the table as the table scrolls. You can provide a custom UIView (or sub-class thereof) for a section header through the delegate method –tableView:viewForHeaderInSection:. This header view could be created on-the-fly programmatically or loaded from a NIB file. Either way, you can have it contain whatever you want, even update it as the app runs (provided you have given yourself access through ivars or class variables to the views contained in your header view.) If you go this route, you'll want to be clever about allocating resources that comprise this view, so that you are not constantly allocating new resources! This delegate method can be called frequently, and on all but the first call you could simply return the previously created (but updated as and if necessary) header view.
UITableView isn't designed to do this, although I am sure you could figure out some way eventually.
My approach would be to use a fixed UIView of some sort (possibly a UILabel, etc) in a UIViewController's nib as the header/locked cell, and add the UITableView under that. You couldn't then use a UITableViewController, but would have to implement the delegate and dataSource methods in your UIViewController, and use a UISwipeGestureRecognizer to pick up the gestures from the tableView and update the other views.
I've done this by adding a UIView that mimics the first cell in my table. In my case I am using a subclass of UITableViewCell, but that is perhaps not relevant. Normally this view is hidden with an alpha of 0.
If you view controller is the delegate of the UITableView then it will also be the delegate for the inherited UIScrollView. So in your view controller you can implement scrollViewDidScroll. When the scrollView's contentOffset is positive I set my custom view's alpha to 1 (I also do some small size tweaks to make sure there is a perfect match), and when the contentOffset returns to 0 or negative, I reset the alpha back to 0.
prepend the first row of data in your array to what ever in the first row is your headings, put the text in bold with attributed text, It wont be sticky but you will have headings...

table view cells with different controls

I was working with the grouped table view , and i wanted different controls for every row i.e switch control for 1st,radio button for 2nd ,checkbox for 3rd and so on.. how can this be implemented programmatically that is without using interface builder
thanks in advance
CharlieMezak said is right, you need to create in UIControls directly in cellForRowAtIndexPath , and add as subviews to contentView of the cell
For reference see the link below
http://www.e-string.com/content/custom-uitableviewcells-interface-builder
the link specifies the code to create cells programmatically as well as using IB.
Table View Programming Guide for iOS
Read the programing guide, and remember to use different CellIdentifier for each type of cell.
This is a pretty vague question.
Obviously you need to provide the cells to the tableview in its cellForRowAtIndexPath delegate/datasource method. So, either in that method or during the initialization of your view controller, build the UITableViewCell instances that you need, adding the various controls that you want to them as subviews and connecting the controls to your view controller so you can detect when they have been changed. Then just return the appropriate cell in the cellForRowAtIndexPath method.
Personally, I think it's a lot easier to use IB in cases like this. Just create an IBOutlet instance variable for each custom cell you want, and return the right cell in cellForRowAtIndexPath.

Content of custom table view cells not drawing correctly

I have several parts in my app where I use custom table view cells.
Their content is created with subviews.
The problem is that on some of these cells, the content does not appear at all or does not appear correctly until after the cell was selected for the first time.
One example is a custom cell which has a custom subview which can be set after its creation. This view does not appear at all before I selected the cell and its views were redrawn. Calling -[setNeedsDisplay] in the subview's setter method does not help either.
The problems was that I was using the cells themselves to calculate their height. For some reason, the subviews (which were part of the cell used to calculate the height) weren't appearing correctly in the cells that were used for the actual displaying.
Therefore my advice: Never use a UITableViewCell to calculate its own height. This may work in principle (it doesn't crash), but might bite you later in unexptected and hard-to-debug ways.