Storyboards and Table View Sections - objective-c

I've noticed that in Storyboards, when dragging out a Table View object from the Library, you also get a chance to configure table view sections, and bunch of other options. For example, if the content is going to be static cells or dynamic prototypes, etc.
Here's a look at the Table View in Interface Builder (.storyboard file):
and here's how the Table View looks like in a .xib file:
So my question is - is it possible to configure/style (drag buttons, images, etc. into cells) a table view in a .xib file using Interface Builder or it can only be done programmatically?

Can be done either way. I prefer doing it in IB as the layout is much easier when you can see what you are doing. For dynamic prototypes, you only design a single cell and the contents will be populated in the cellForRowAtIndexPath method. With a Static Cell tableview, you can design the whole thing (many sections and many rows). The requirement for a Static Cell tableview is that the class HAS to be of type UITableViewController, while for Dynamic Prototypes, it can be either a UITableViewController or (my preference for more flexibility) a UIViewController with a UITableView.
Hint - if this is a Static cell tableview and you only design a screen full of sections and rows, be sure to turn off scrolling for the tableview.

Related

Cocoa binding search field to tableview in a different nib

I've got a user interface that looks pretty much like iTunes. For purposes of encapsulation, the top area and the main table view are in separate classes with separate nibs. I want to bind the search field from the top view controller to the tableview in the bottom view controller. I've arranged it so there are properties to store the NSArrayController in both classes. The array controller is an array of dictionaries, and the dictionaries have a "search_keywords" key that I want to use to filter the tableview.
Is it possible to set up the search stuff in Interface Builder even though it's in a separate nib? I can't figure out what to put in the various boxes.
If it's not possible with IB, I assume it's possible in code, since there is a view controller with references to both of the sub-view controllers and I can get at the search field, table view and array controller objects through properties on the two classes.
How do I set it up? IB would be best, if it's possible.
What I did was use the NSSearchField in the top view controller as a dummy/placeholder. I create the "real" search field in the tableview's nib, and wire up all the bindings stuff as per normal. Then in the main view controller I grab the search field out of the tableview's nib, and replace the dummy searchfield with the real one using replaceSubview:with:
Now I can continue to use IB to modify the bindings, and it doesn't really matter what's in what nib as it all gets placed properly in the view hierarchy at runtime.
In your concept you cannot bind the search field in IB in the desired way.
Do it like
1. Create an accessor-method (accessorMethodForTextInSearchField or what name you want to use) in the TopClass for the Text in the searchField
2. Import the TopClass.h in the MainClass
3. In MainClass you can use
NSString *searchString = [ NSString stringWithString:[ TopClass accessorMethodForTextInSearchField] ];
4. Now search for searchString in the array

Sharing code between a UITableView and a UICollectionView

My iPad and iPhone interfaces use a UICollectionView and a UITableView respectively. In each case, there is a lot of commonality:
each has the same number of sections (hard-coded)
each section has the same number of respective rows/items (derived from the same data source)
each has identical cell content (these are custom views built using auto layout so are suitable for both cases)
each has identical section headers and footers (again, custom content)
each can respond to certain notifications in the same way (e.g. when new data is received, refresh the data source) but with custom parts also (reload the UITableView vs reload the UICollectionView)
each will present the same controllers via cell selection, though the UITableView will push the new controller and the UICollectionView will use a popover.
I am using a shared parent class to cater to some of this. This approach seems especially well suited to the data requirements - the parent class builds the data and is responsible for maintaining it. I use two subclasses to present the data - one with a UITableView and the other UICollectionView.
The presentation side is a little less clean. To take the simplest example, when the table/collection view needs to know the number of sections, in each case I am relying on a customized method in the parent:
return [super sectionsCount]
This allows me to set many values only once and have both views updated.
Then comes the part that is working poorest. Again, to simplify, consider the header view for the first section. In both cases, this should be identical. I have a custom UIView subclass that I want to use, with a couple of properties that will be set the same. The problem here is that the re-usable header for a table view section expects a UITableViewHeaderFooterView and the counterpart for a collection view expects a UICollectionReusableView. So to accommodate this, I'm having to create subclasses of these simply to hold the header view I want in both. So in summary:
What I want: UITableView and UICollectionView should use the same UIView subclass as the header for section. The custom properties of that view should be set identically in each case.
What I am having to do:
Build the required UIView subclass for the header.
Build a UITableViewHeaderFooterView subclass that holds one such header. It's init does nothing more than add a header view.
Build a UICollectionReusableView subclass that equally does nothing more than add a header view.
When the collection view needs a header, create an instance of the UITableViewHeaderFooterView subclass. Set its properties.
When the table view needs a header, create an instance of the UITableViewHeaderFooterView subclass. Set its properties.
Once I have to do this for footers, and especially cells, things are getting kinda icky. I have three times the classes I should need, and I'm repeating all of my code for setting custom properties of the view.
How can I best re-use this logic between the UICollectionView and UITableView?
You can just create stock UICollectionReusableViews, UITableViewHeaderFooterViews, etc. and add your custom view as a subview. If you need to access the custom view later, you can set its tag property and use [view viewWithTag:].

How to add objects to prototype cells in interface builder

Previously i've been able to design the basic look of the UITableView protoype cell in interface builder by dragging objects onto it etc.
I'm trying to do this now with the iPad master detail template but interface builder won't allow it.
I know it can be done programmatically or by creating a seperate .xib but it makes sense to do it this way as it's much more intuitive being able to see how it will look in the actual table view.
Click on the prototype cell.
Open the Attributes Inspector (option+⌘+4)
Under the Table View Cell section, change the style to Custom.
Now you can drag whatever object you like onto the cell.

No content attribute for UITableView in .xib

(XCode 4.2, iOS 5)
In order to reuse a tableview (with a navigation bar and edit/add buttons) I created a UITableViewController subclass with it's own .xib. However, when I add a UITableView to my .xib's main view the content attribute (which I want to set to dynamic prototypes) it doesn't show up. It just shows the sample content (California: Brea, Burlingame, ...). When I add a UITableView in my main storyboard the content attribute does show up.
What is the issue?
For people trying to solve this, it is impossible to set dynamic prototypes cells in a .xib, or even static cells. No embedded sections or cells are supported in .xib files.
If you drag a Table View Controller into a .xib, you'll get an error:
Table views with embedded sections and cells are only supported in
storyboard documents
Xcode 6.3.2

Best way to have UITableView within another table?

I have a grouped UITableView in class A and if you select a row in section 0, I want it to open up to another UITableView. In the first view, I have a lot of other methods and buttons and custom designed stuff, so I don't want to create another XIB for the other table view since I'll have to copy over all the methods and custom designed stuff. I was thinking creating another XIB, but subclassing the class under the original class A this way I can use the methods of class A without having to redefine them again in the new class. But I'm having problems with this. Is there a better way? Can I have two table views in one XIB, and just hide one till the other is called up? But that seems a little messy..
If you simply try subclassing the existing viewcontroller it will have the same info for the selected row, hence it would have to grow exponentially in order to make display the right UITableView.
If your concern is redefining methods, then simply create a class that will hold those particular methods and include it in the UITableViewControllers that will be using them, that way you will only define it once. This way you can simply create a new UITableViewController and push it into a navigation controller everytime you select a given cell.
As an alternative of showing all options within one UITableView you can try the following: you can probably try adding a UIScrollView inside the UITableViewCell. I would make it scroll horizontally while keeping the UITableView scroll vertically.