IBOutlets in UITableView Static Cells - swift

I created a UITableView (and related classes), with two sections:
the first one is a static custom cell
the second one is a prototype cell
To control the static cell, I implement a class, and in that class I added IBOutlet to an object (for example label) in the static cell. When I attempt to access that outlet in the class controlling the table view, I get this error:
outlet doesn't exist
I made a video, for explain better my problem.

Short version
UITableView cannot be at the same time a Static Cells and a Dynamic Prototypes content. You need to pick one or the other.
Because you need Dynamic Prototypes, use Dynamic Prototypes.
Long version
Steps to create Dynamic Prototypes:
Select your Table View in IB > Show Attributes Inspector > Table View > Content > Dynamic Prototypes
From the section IB > Show the Object Library, drag as many Table View Cell onto your table view as you have cell types.
If you have some cells that never change at run time, you can very well create 1 instance of each right there in IB ; they will behave like Static Cells
For the custom cells(†), the recommended practice is to create subclasses of UITableViewCell, and apply that custom class to the relevant cell or cells (IB > Show the Identity Inspector), and pick your Custom Class from the list. This of course implies you have created such sub-classes.
Do not forget to assign a unique identifier to each cell prototype, so that you can retrieve these at runtime using dequeueReusableCellUsingIdentifier;
With this setup, you can select your Table View Cell, IB > Show Assistant Editor, and control-drag references in your custom class. You may need to tell the Assistant Editor which file to pick.
(†) There are plenty of other ways to do this ; all outside of the scope of this response.

Related

Why Xcode refuses to show the TableViewCell class for the prototype cell on storyboard?

I have a TableViewObject on my storyboard which has a corresponding UITableView class.
Within that TableViewObject I also have the 'cell' which manages the layout of a given prototype cell - the class associated with this is of type UITableViewCell.
The issue is that no matter where on the storyboard I click, when I show assistant editor it opens the UITableView class - not the one corresponding to the UITableViewCell.
I think it hasn't always been this way because I managed to drag/drop controls to make outlets in the past but now it refuses to comply - what can I try to fix this?
I've confirmed that the UITableViewCell class is the one shown in the Identity Inspector for the cell and also tried deleting the Derived Data folder that someone recommended - but this hasn't solved it.
To give some further detail, for other TableViewController/Cell combos I have the option by clicking 'automatic' of selecting one of two files, but for the problematic one there is only one file (see screenshots).[![enter image description here][2]][2]
Don't use assistant editors at all. They are a dead letter. If you want to display the code for the table view cell subclass at the same time as the storyboard, just Option-click on the code file for the table view cell subclass in the project navigator — or select the prototype cell, switch to the Identity inspector on the right, and Option-click the little arrow next to the class name.

IOS create new UITableViewCell with properties of a prototype cell

I am working on an app that has several prototype cells in one view. This worked well for easily altering the appearance of the app while in development using the storyboard. However, now I'm adding search (filtering) capability. I would like the appearance of the tableview to remain unchanged, just filter out some of the results.
My understanding is that I have to create new cells to do this. Is this correct? If it is, is there a way to create a cell with all the properties of my prototype cells. As it is now, the newly created (search result) cells have default settings.
Thanks.
You can certainly use copy and paste. Create a xib file (an empty one), and copy the cell you want from your table view in the storyboard, and then paste it into the xib file. In the viewDidLoad method for your table data source, register that nib file:
[self.searchDisplayController.searchResultsTableView registerNib:[UINib nibWithNibName:#"SearchCell" bundle:nil] forCellReuseIdentifier:#"SearchCell"];
Then in the cellForRowAtIndexPath method, you just dequeue a cell with that identifier for your search results table view.
The thing to understand clearly is that the table view that appears when you are doing a search with the UISearchDisplayController conglomerate is not your table view. It is a different table view, and you do not have a UITableViewController managing it - the UISearchDisplayController does that. Thus you must take other measures if you want that different table view to look like your table view.
EDIT: On the whole (and after the little exchange with rdelmar in the comments on his answer), I tend to think the easiest solution is to abandon the use of cell prototypes altogether. If you design the cell in a nib (xib), you can then use that cell both for the real table and for the search results table. In both cases you register the nib with the respective table view - and then dequeue just does the right thing all by itself, in both cases, with no change in the code.
You can see me doing something similar here:
https://github.com/mattneub/Programming-iOS-Book-Examples/blob/master/ch21p632searchableTable/p536p550searchableTable/RootViewController.m
... except that in that case I'm registering the same cell class for both tables, not the same nib. But it all comes down to the same thing. However, note that I do not start with a storyboard, so I never fell into the trap of using a prototype cell in the first place.

Implementing another table view in a UITableViewController ios

I need to add a new table view to my UITableViewController which will includes a different data and design.
the above prototype cells is the new table view I've added in storyboard, and the main table view is the second one which includes (title, label, and image).
Is it allowed to create another table view in UITableViewController, or should I create a UIViewController and implement the two tables in it???
In fact, I've finished the implementation of the first table view controller, so I need to implement the new one.
the attached image is showing what I want:
You will be better off with a UIViewController that has two tableViews as subviews if you want both of your tables to be shown at the same time. UITableViewController should be used only when there is just one tableView shown at a certain time.
You can either have one UIViewController being the dataSource and delegate for both of the tableViews, or have a UITableViewController for each of your tables and add them as subviews to a UIViewController that will be a container view for both of them. The latter will probably save you some time debugging possible issues as having two tableViews with a single delegate/dataSource requires a lot of duplicate code in the same place.
I think you should use UIExpandableTableView
there is detailed usage on github page
Scree example of UIExpandableTableView
Are you looking to have them be two independent tables, or is it a master/child setup?
If they are independent, I suggestion using one table and two sections, then depending on the section number return to correct cell.
For master/child, think about making a view that looks like a cell and have the master cells be the sections views and the children be the actually rows. You can make a section class that stores if the children are visible or not and in the numberOfRowsInSection method return the count if visible or 0 if not.
Just a couple ideas

Create custom class for Navigation Controller (Immediate crash)

I'm working on a Storyboards based app which constitutes of multiple view controllers linked via a Navigation Controller (initial view controller). This is used as the home screen. I'm using static cells and a static table view.
Now, I want to hook up some labels, buttons, etc as outlets/actions to "the .h" file and subsequently write custom methods in the .m file. But (as expected?) there's yet no custom class to select from in the identity inspector. So I created a new custom class as a subclass of UITableViewController (which seems to be the correct one?)
My new, custom class is now hooked up to my storyboard view controller. I then enter (what I believe to be) the correct numberOfSectionsInTableView: 1, and numberOfRowsInSection:5 (I got 1 section including 5 rows). When ran, it immediately crashes with the following error:
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'unable to dequeue a cell with identifier Cell - must register a nib or a class for the identifier or connect a prototype cell in a storyboard'
If return 0 sections and 0 rows, everything works fine (expect there are no rows displayed). Once I return anything > 0 in either of them, it crashes with this error.
What have I missed? Is there anything else I'm supposed to add to the file before it can be attached as a custom class and I can use it as any other custom class? Again, I've set up everything in the interface builder (storyboard), including the table cell rows, its styling, etc. What am I doing wrong?
My Table View Setup
My Table Cell Setup
Pretty sure this is the answer: in storyboard, make sure a prototype cell is painted on the table view (the one in the crashing view controller) and make sure it has a reuse identifier set to "Cell". Your code for rowAtIndexPath: is trying to dequeue a cell with that identifier and it's not there.
The identifier can be set using the attributes inspector (the middle tab on the upper right) in storyboard.

How to make a derived UITableVIew work

I've made a new class in my Xcode project which is derived from UITableView
I then drag a UITableView from in the interface builder onto my view and change the class of the object to my derived class. Then I drag the outlet from the table to the files owner and hook it up to an outlet variable in my main view, which is of the same type as my derived class.
How do I also set up the datasource and delegate so that they belong to the derived class?
I've got two table views on my main viewcontroller, and one of them uses that controller itself which works fine. The delegate and datasource is the file owner of the view controller.
But my other table view will be for different data, so I want it to use the datasource and delegate which is implemented on my derived tableview.
When you click on the UITableView-derived object are you not able to see the delegate and datasource members under the Table View Connections pane of the Inspector window? It should be as simple as dragging a connection from each to file's owner, or whatever object you want to make delegate/datasource. I've seen them go away when all you do is change the class type of an object, but if you write headers and make sure your class says that it is derived from UITableView then return to IB I believe you will see them again.
(apparently IB2 used to handle this the way you expected - in IB3 it is best to derive in Xcode first, then use the derived class in IB)