Why should I set a Custom-class for a Cell within the UIBuilder? All examples I can find are setting the Identifier and use this on in ...cellForRowAtIndexPath:...?
Is this useless here?
Edit:
Sorry, I think, this was not asked clearly - so I'll try again:
Normally (all found examples) the Cell-Identifier (in the attributes inspector) is set an this ID is used in the ...cellForRowAtIndexPath:...-method to identify, which Class should be used.
Beside the Cell-Identifier (attributes inpector), there is the the possibility to set the custom class (identity inspector). When will I use this setting in the context of table-cells?
If you use Custom Cells in the Interface Builder, you can easily manipulate the appearance of your custom cell, and make it have custom properties and behave in specific ways which is very effective.
Custom Class is used whenever you make your own class for a UITableViewCell.
#import "UITableViewCell.h"
#interface MyCell : UITableViewCell
#property NSString *myCustomProperty;
#end
Then in the code, you can access the custom properties of your cell by doing something like:
MyCell *cell = (MyCell*)[tableView objectAtIndexPath:indexPath];
[cell setMyCustomProperty:#"Custom Cells Yey!"];
Also, may I also note that the identifiers are primarily used to manage memory effectively in UITableViews. The table views use trickery in their implementation to cache the cells rather than create new cells every time you scroll a little bit otherwise that would be overkill so you can use identifiers to cache rows in the tableview automagically.
Related
I am creating a UITableView which has multiple types of cells.So I creating multiple cell using xib and for each cell I have one .h file one .m file and one .xib file.All these cells has some common things like cell background color,property(UILabel,UIView) and actions(UIButton click).
So I am doing a set of common things again and again.So how can I create a super class of these cell so that I can come out of the problem.I should be linked the custom xib cell to my super class.
Edit 1.0 :-
Suppose I have created a Super Cell subclass of UITableViewCell having the all the common properties of those cells in its header file (SuperCell.h) and also implemented all the common actions in its implementation file (SuperCell.m).Then I Made all those .xib cell header file as a subclass of my SuperCell. Now how can linke these .xib files header property to the SuperCell header property which is same.
Edit 2.0 :-
Thanks #Fogmeister for pointing me out that it will be a big hierarchies and difficult to maintain.And If I want to add some new label in child cell then I am also not clear where should I add and how to linked with the super cell.
Let me clear my question explaining my project a little bit.
I am creating an social app like facebook which has Text post,single image post,double images post,multiple images post, poll,event,etc.
So for my social app landing page I have a UITableview controller and all these type of post is linked to one one cells.All these cell has some common things like Post ownername(UILabel),#handler (UILabel),profile pic ( ImageView) ,Post time (UILabel),like button (UIButton),comment button (UIbutton) etc.
I have done everything and it is working fine.I have written a lot of common code for setting up all these cell as there is not SuperCell of these cells.So I am trying to figure out a solution to make it little bit easier.
Thanks
Ah, I see your problem now. As a very first starting point I can think of two possible (maybe three) ways of approaching your issue.
(N.B. everything here is just me using the Facebook app as an example, your actual app may differ).
At the moment you have different cells StatusCell, PhotoCell, VideoCell, ShareCell, etc...
Each of these have various different elements... userNameLabel, userAvatarImage, timeLabel, likeButton, commentButton.
Then each has a "contentArea" that contains the status, photo, video, url, etc...
First solution - Component views
The first approach I was thinking is to keep your different cell types but then to create UIView subclasses to easily populate the areas. So instead of the cells having the different user labels and images etc... create a view called UserDetailsView.
This UserDetailsView will take a single property of a User object. It then uses this object to populate the different labels it contains such as userNameLabel, userAvatar etc...
Now you can just add this view to each different cell type.
You can also create components for the ShareView which might include likes, comments, etc...
Second solution - Generic cells
In addition to creating these different components for each different type of Cell you could actually use a single type of cell. (This would only work if the content is in roughly the same place for each).
So the additional part to create now are the different content views. This might be a StatusView, PhotoView, etc...
Now you can use one generic cell type that has a space for a content view. (Maybe placed inside a container view for positioning and constraints).
Third solution - React Native
What Facebook does for their timeline is to use the React Native framework that they have created for immutable view hierarchies. This is a more complex method as it requires reworking the way you build stuff but definitely one to keep in mind for the future.
https://facebook.github.io/react-native/
create your "parent cell":
#interface SuperCell : UITableViewCell
#end
#implementation SuperCell
// background logic and all the stuff that is equal for your child cells
#end
with it's .h and .m files.
then create your "child cells" (with their .h and .m files) and make them inherit from your "parent cell":
#interface SomeCustomCell : SuperCell
#end
#interface AnotherCustomCell : SuperCell
#end
and so on...
Custom Cell For UITableViewCell
I'm developing an iOS application and i need to make a custom cell for my side menu, i have seen so many examples and i found out those two approaches :
Make a class (.h and .m files) that inherits from UITableViewCell and put the outlets in the .h file then apply the class on the cell and connect those outlets to the labels and/or images from your cell in the storyboard.
Or the easy way is to give a tag to the labels/images or whatever you have in the cell in your storyboard.
My Question: I'm wondering which way is more accurate and professional and used by most iOS developers ?
Definitely the first one. It's clear and maintainable in the future. The purpose of the tag is not to store arbitrary values. See my answer regarding this.
This article has some details on the usage of tags
As everybody knows, there is easy to initialise UITableViewCell:
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"cell"];
But how to create my own table view style definition "UITableViewCellStyleCustom"?
As the other answers already pointed out, there are tons of tutorials as on how to create your own cell style.
However, remember the preferred way to create a table view cell is to reuse one in tableView:cellForRowAtIndexPath: like so:
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"myIdentifier" forIndexPath:indexPath];
EDIT
If you want to implement your own version of initWithStyle:reuseIdentifier:, you can obviously create your own enumeration of cell styles, e.g.:
typedef NS_ENUM(NSInteger, MyTableViewCellStyle){
MyTableViewCellStyleFile,
MyTableViewCellStyleFolder
};
Then you can define a custom init method like so:
-(instancetype)initWithMyStyle:(MyTableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier;
Apart from that, UITableViewCellStyleDefault is part of the enumeration UITableViewCellStyle in UIKit. So it is basically just an integer value and passing a different value than the defined will not work in default init methods.
There are a couple of solutions for this:
You prototype your own custom cell on a storyboard. This is a quick way of creating a custom cell without too much of a hassle. If I am not mistaken this is not available in NIBs.
Create your Cell in a NIB.
On both approaches, you will have to then subclass a UITableViewCell and add the behaviour you want to it. You will also need to specify on the Storyboard or Nib, that you want that cell to have the type of the subclass you just created. There a tons of tutorials on the web on how to do it.
First, you need to subclass UITableViewCell to get a custom cell.
When initializing in code (why?), just use UITableViewCellStyleDefault as the style parameter in the designated initializer. I recommend initializing the cell via storyboard or Interface Builder.
Apologies in advance, as I am extremely new to iOS and objective-C and this is probably a very basic question, but I've hit a wall, and after days of searching the Web, I'm still lost:
I'm generating a dynamic table with various different types of prototype cells. One type has only a text field into which the user can enter or edit an arbitrary string. I've designed the cells in the Storyboard Editor because I would rather not muck about with generating everything programmatically if possible.
I have a string already in a variable which i want to use to populate the text field.
How do you go about addressing and populating this field? I assume the answer involves doing so at the moment the cell is called into existence with dequeueReusableCellWithIdentifier, but this is as far as I've managed to get...and I need help connecting the dots.
I have already read the Apple "Table View Programming Guide for iOS," and it's been unhelpful with this problem.
(if I could have tagged this question "noob"...)
Create a new subclass of UITableViewCell and set the class of your cell to this class. (select the cell and then click the identity inspector, the 3rd icon from the left. Enter the class name there where it says: Class) You will also need to specify an Identifier for the cell. I often times put in the same name as the class, so don't get the two confused in the code below. One is the identifier, the other is a class.
In your cellForRowAtIndexPath, get an instance of your special class.
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellIdentifier = #"EventCell";
EventCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
[cell populateTextField];
return cell;
}
When you have the storyboard open, you can control-drag from the text box to your new class to create an outlet property. (Let's call it textField)
Your property would look like this after you ctrl-drag and then enter when the dialog is shown:
#property (weak, nonatomic) IBOutlet UITextField *textField;
Then in your new class, create that populateTextField method:
-(void)populateTextField {
self.textField.text = #"My special string";
}
Also note, that you can put in placeholder text on a textField, so you may not need to go through all of this.
I have a static UITableView built from a Storyboard that works well. I want to fill the first category programmatically, though, from a user-defined file
Simply put, I want to go through all the strings in an array and add them as cells for the rows of the first category. For the second category, I have a series of mildly complex cells (containing a number of labels, textfields, buttons and other controls), defined in the storyboard, that I don't feel like recreating in code.
As far as I understand, the default behaviour for a UITableView built from a storyboard is to use the nib file as an implicit datasource. If I use a custom class as datasource, my second section doesn't work. I have thought of two possible ways to fix this:
Fill my first category from the datasource and delegate the rest to the nib file. Is this possible? Is there some method to programmatically ask the nib to fill my UITableView?
Export my storyboard-built cells into code and paste this code into my datasource. This method has the disadvantage of making my second category harder to modify.
Is one of those two options feasible? Is there another option?
I would use dynamic prototype cells. Then, I would set up the ViewController as the delegate and the dataSource. I would then create a custom subclass of UITableViewCell and connect the elements of the second section to IBOutlets in the custom UITableViewCell.
If the first section wasn't something that could be done with one of the generic cell types, I would also create a custom subclass of UITableViewCell for that section as well.
I would then use the cellForRowAtIndexPath: method to set up the cells with the information that I want in them. So if my first section used FirstSectionCell and my second section used SecondSectionCell as custom subclasses of UITableViewCell my cellForRowAtIndexPath: would look like this:
-(UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if(indexPath.section==0)
{
FirstSectionCell *firstCell = [tableView dequeueReusableCellWithIdentifier:#"First Cell Prototype"];
//Set up the first cell.
return firstCell;
}
else if(indexPath.section ==1)
{
SecondSectionCell *secondCell = [tableView dequeueReusableCellWithIdentifier:#"Second Cell Ptototype"];
//Set up second cell.
secondCell.someLabel.text = #"whatever";
//etc.
return secondCell;
}
else
{
//if you have another section handle it here.
}
}
There are two kinds of table views when you use Storyboards:
Static
Dynamic
You're currently using the former. You define everything in the Storyboard and have very little code.
But you need to change to the latter.
You can still keep your UITableViewCells in the Storyboard; there's no need to do that in code (though you can if it makes things easier). You can refer to the template cells using the "reuse identifer."
Otherwise you've pretty much got it. You'll need to write code to implement the data source and (possibly) more methods of the table view delegate.
It's kind of fiddly switching from static to dynamic. I keep meaning to raise a Radar because I'm sure Xcode could be making it easier to do...