I have a UITableView, with 8 differents type of cell. Those custom cell have some design in commom (like a upper left icon, a title, a subtitle...). However, under those common features, each cell is different. In order to have less to maintain, my 8 cells inherits from a default abstract cell with the commons IBOutlet.
Now my question is : what is the best, most proper way to do this?
At first, I thought of using registerNib:forCellReuseIdentifier: but this means 8 different xib. In this case, if one of the common design feature change, I would need to go trought all 8 xibs to change the same thing. I thnik it's not very productive and clean.
I thought also of registerClass:forCellReuseIdentifier: but this methods does not create the cell with a nib, so I would need to do everything programmatically.
The solution could be have one common xib, different registered class in the tableview, and those will be responsible for using their own custom design. But I can't see how to achieve this with those two previous methods.
I would use a single nib file with 8 different UITableViewCell subclasses. You should be able to use registerClass:forCellReuseIdentifier: and inside the class (which subclasses UITableViewCell) you make use of the nib file. If it is not clear I'll try to provide some code.
Related
I have a custom UITableViewCell called StandardTableViewCell. This is made in a XIB with autolayout.
The cell is registered with the method registerNib:forCellReuseIdentifier:
What I am trying to do now is subclass StandardTableViewCell without making a new XIB.
Is it possible to reuse the cell without making a new XIB while keeping the cell's File Owner?
Have you thought of creating a category instead of subclassing? Not sure what you're exactly doing, but that might work instead.
Unfortunately that's not possible, so you have to use a less than ideal solution, here's some options:
Implement the functionality in the same Standard cell and toggle it.
Duplicate the standard nib and replace the cell class.
Don't have a standard nib and just make one for each subclass (if they are different this is probably the best idea).
I have a UITableView where I'd like to have multiple types of UITableViewCells. The different types of cells have a lot of similar properties, but have a few key differences, so I was hoping to create a template UITableViewCell class (TemplateCell) that the different cell types could extend.
I've tried doing this by creating a the TemplateCell class and having an associated .xib file. I then tried to go to my UITableView storyboard file and created my various cell types that subclassed my template. However, when I added those cell types to the storyboard file, they showed up as blank and didn't have any of the properties I had in the template file.
Is there an better way to create UITableViewCell templates?
You can create a TemplateCell class and separate classes for every other Cell (inherited from TemplateCell). Then you could assign common IBOutlets of EVERY subclassed cell to it TemplateCell class. Or you could operate with them by looking for the views with specific tags if you don't want to bother with outlets for base class.
Unfortunately you can't draw views in IB respecting some base view, so you should draw each cell separately, but you can use common outlets declared in the base class, and those outlets (properties) that differ, put into inherited cell classes.
Without 3d-parties IB doesn't support loading views from xib to a storyboard or another xib. You can use XXNibBridge for that.
Who is the best optimized way?
Create objects in my UITableView using storyboard (Drag and drop in my cell), or create objects programmatically (cellForRowAtIndexPath)?
When the project compile and run in device which of the two options will run faster?
In terms of pure performance, code created UI objects are faster than any nibs / storyboards objects, only because storyboards and nibs files are stored on disk until they are loaded in memory and translated in UIKit objects.
That being said, it also depends on how you are implementing it. If you use prototype cells in storyboard vs creating cells everytime in cellForRowAtIndexPath, then storyboards win because of the reuse cells (though you can also reuse code created cells).
And that being said again, the performance win you have by creating UI with code is ver small and not even close to be perceptible by the human eye. Therefore, for me, using the storyboard is a no brainer for the ease of creating interface without polluting your code.
You can see a nice article about that here: http://www.toptal.com/ios/ios-user-interfaces-storyboards-vs-nibs-vs-custom-code. The article is approx. 1 year old but it still is accurate.
The effective performance will be identical for the same layouts. I would choose one approach over the other based on different needs.
Storyboard prototype cells can be faster to setup, easier to get Autolayout constraints working correctly, but you cannot re-use that prototype cell outside of its Storyboard. If using the same cell layout across multiple views is required, writing your table view cell in code or using a nib file is required.
Also, it should be pointed out that cellForRowAtIndexPath is still required when using a Storyboard prototype cell in order to configure your cells, assuming you have some sort of dynamic data to display. Similarly, in the programmatic approach you should not be creating views in cellForRowAtIndexPath but rather configuring them.
I have a working UITableViewCell. Now I have a different cell I need to make which is exactly like the previous one - but has a UIWebView instead of UIImageView.
I was thinking of doing a different xib for the cell, but the thing is they have tons of code and logic in common (for the rest of the controls)
What is my best approach in this case?
You can make a parent class: put all the common code there, then make 2 subClasses of this superClass, they'll inherit the superClass code, and put there all the code and objects specific for each of them
I've got a static TableView that now needs to become a dynamic TableView, because other views need to be placed around the ViewController, and this can not be done using containers in my case.
The question is: how do I efficiently convert the table view from static to dynamic?
I'm aware of having to change the inheritance from UITableView to UIViewController and add the plus the delegate methods.
But how about all of the Table-Sections: I have 3 sections with 6 types of cell in the static table. Do I really need to subclass UITableViewCell for all of these cell-types and deal with everything manually, or is there a more clever way to do this?
You really can't just convert between the two. By merely implementing some of the tables delegate methods, like cellForRowAtIndexPath:, you loose your static content. That being said, the table should be dynamic the entire time. This way, you can define logic to determine whether or not it should show the content that you originally added statically, or the new dynamic content.
Additionally, you don't need a view controller to implement the delegate/datasource methods. If you already have a subclass of UITableView, that's fine. You can set it as its own delegate/datasource, and implement those methods within the subclass.
And to answer your last question, no there really isn't a better way to do that. I recommend that you create one base class that subclasses UITableViewCell that implements everything that the cells will share, and then implement the individual changes in subclasses of this base class. Using multiple cell subclasses in a table view sounds a lot worse then it is.