Can anyone explain me what is happening here while initialising UITableViewCell .Thanks in advance
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
NSArray *nibArray=[[NSBundle mainBundle]loadNibNamed:#"CustomCell" owner:nil options:nil];
self=[nibArray objectAtIndex:0];
}
return self;
}
Try this
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"CustomCell"];
if (cell == nil) {
// Load the nib array from the custom cell XIB.
NSArray *nibArray = [[NSBundle mainBundle] loadNibNamed:#"CustomCell" owner:self options:nil];
// Grab a pointer to the first object
cell = [nibArray objectAtIndex:0];
}
//set cell data
return cell;
}
Related
At first I had this code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
DropDownTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"DropDownTableViewCell"];
if (!cell) {
NSArray *topLevelObjects =
[[NSBundle mainBundle] loadNibNamed:#"DropDownView"
owner:self
options:nil];
for (DropDownTableViewCell *object in topLevelObjects) {
if ([object class] == [DropDownTableViewCell class]) {
cell = object;
break;
}
}
NSAssert(cell, #"Cell must not be nil");
}
cell.nameLabel.text = [self.dataSource buttonDownPicker:self stringForRowAtIndexPath:indexPath];
return cell;
}
At first moment when I show tableView and tableView cell's starts loading from nib I have UI freezing for a few seconds (caused by loading from nib for EVERY displayed cell). This can be solved by loading cell from nib earlier:
- (void)awakeFromNib {
DropDownTableViewCell *cell = [[[NSBundle mainBundle] loadNibNamed:#"DropDownView" owner:self options:nil] objectAtIndex:0];
}
But this way looks "hacky". Is there more appropriate solution?
Edit according to given answers:
I've tried to use registerNib forCellIdentifier but it didn't LOAD nib, it just BINDING nib with identifier and at first time when tableView appears all cells causing load nib to memory
This is not "hacky" at all. For loading cells from a nib what you usually do is load the nib and then register the cell for reusable identifier of your choosing. For instance in one of my projects I have a view controller with a table view. In the view did load I call:
[[NSBundle mainBundle] loadNibNamed:#"ChannelListCell" owner:self options:nil];
[self.channelListTableView registerNib:[UINib nibWithNibName:#"ChannelListCell" bundle:nil] forCellReuseIdentifier:#"channelListCell"];
Then in the cell for row at index path:
cell = [tableView dequeueReusableCellWithIdentifier:#"channelListCell" forIndexPath:indexPath];
In your case the dequeued cell is always nil since you did not register it.
Try like this.....
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
UINib *nib = [UINib nibWithNibName:#"" bundle:nil];
[self.tblview registerNib:nib forCellReuseIdentifier:#"DropDownTableViewCell"];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
DropDownTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"DropDownTableViewCell"];
return cell;
}
You can register your class first like bellow in your viewDidLoad. It make faster and better
[self.tableViewObject registerClass: [DropDownTableViewCell class]forCellReuseIdentifier:#"DropDownTableViewCellIdentifier"];
And please add following method in your DropDownTableViewCell.m file
-(id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"DropDownTableViewCell" owner:self options:nil];
// Grab a pointer to the first object (presumably the custom cell, as that's all the XIB should contain).
self = [topLevelObjects objectAtIndex:0];
return self;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier=#"DropDownTableViewCellIdentifier";
DropDownTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: CellIdentifier];
//Access all cell properties here.
return cell.
}
Please refer https://stackoverflow.com/a/30954273/914111 for better knowledge.
I currently have a tableView with custom cells that I've called AMPFeedbackTableViewCell. The cells load up perfectly fine.
Here is the code:
-(UITableViewCell*) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:#"feedbackCell"];
AMPFeedbackTableViewCell* cell = (AMPFeedbackTableViewCell*) [tableView dequeueReusableCellWithIdentifier:#"feedbackCell"];
if (cell == nil)
{
cell = [[AMPFeedbackTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"feedbackCell"];
cell.currentFeedback = [[AMPFeedback alloc] init];
cell.currentFeedback = [_feedbackArray objectAtIndex:indexPath.row];
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"FeedbackTableCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
I'm trying to pass something to the cell before it starts like in this case it's _currentFeedback. The custom cell has a AMPFeedback item and I want it to set it before it loads. So I can use it like this : (NOTE: This is in AMPFeedbackTableViewCell
- (void)awakeFromNib
{
// Initialization code
if (_currentFeedback != nil)
[self loadImages];
}
However, _currentFeedback is always nil. Is there a way I can pass it over then call awakeFromNib?
Thanks in advance
If you are not insist on doing this inside awakefromNib, there's another way (and maybe better) to do this:
in AMPFeedbackTableViewCell.h
#property (strong) AMPFeedBack *currentFeedback;
in AMPFeedbackTableViewCell.m
#synthesize currentFeedback = _currentFeedback;
- (void)setCurrentFeedback:(AMPFeedback *)feedback {
if (feedback==nil) return;
_currentFeedback = feedback;
[self loadImages];
}
and then we can trigger it directly in main code:
-(UITableViewCell*) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
AMPFeedbackTableViewCell* cell = (AMPFeedbackTableViewCell*) [tableView dequeueReusableCellWithIdentifier:#"feedbackCell"];
if (cell == nil) {
cell = [[AMPFeedbackTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"feedbackCell"];
}
cell.currentFeedback = [_feedbackArray objectAtIndex:indexPath.row];
Hope it helps.
You can do initialization and loading of data in the following method of custom uitableview cell
-(id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// Initialization code
}
return self;
}
and you can load customcell in your tableview
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *eventListCell = #"EventListCell";
EventListCell *cell = (EventListCell *)[tableView dequeueReusableCellWithIdentifier:eventListCell];
if (cell == nil)
{
cell = (EventListCell*)[[[NSBundle mainBundle] loadNibNamed:#"EventListCell" owner:self options:nil] objectAtIndex:0];
// here you can access the custom class public variable to set data .
}
}
This question already has answers here:
2 different types of custom UITableViewCells in UITableView
(3 answers)
Closed 9 years ago.
I'm having an issue and would like to know if what I am trying to do is even possible.
I have a ViewController that has a UITableView as a subview. I then loaded a custom cell and it worked fine. However, I needed another custom cell in the same tableview - this second cell has a separate nib as well.
Is this possible?
Two different custom cells in on section in a UITableView?
I did try something like this:
- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier1 = #"ContentCell";
static NSString *CellIdentifier2 = #"SpaceCell";
// Space Cell
if (indexPath.row== 0) {
CellSpace *cell = (CellSpace *) [tableViewdequeueReusableCellWithIdentifier:CellIdentifier2];
return cell;
}
// Content cell
else {
CellView *cell = (CellView *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier1];
// Configure cell
return cell;
}
}
However it seems the else statement is never fired and I normally get a crash saying the method returned nil.
UPDATE
I used the advice and code here and came up with this:
#pragma mark - UITableView Delegate Methods
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 160;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 22;
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
-(UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier1 = #"UsernameCell";
static NSString *CellIdentifier2 = #"PasswordCell";
if(indexPath.row == 0) {
BBUsernameRegistrationCell *cell = (BBUsernameRegistrationCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier1];
if(cell == nil) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:CellIdentifier1 owner:self options:nil]; // set properties
cell = nib[0];
}
// set properties
return cell;
}
// Content cell
else {
BBPasswordTableViewCell *cell = (BBPasswordTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier2];
if(cell == nil) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:CellIdentifier2 owner:self options:nil]; // set properties
cell = nib[0];
}
// set properties
return cell;
}
}
However I only see the first Cell in my tableview. If I switch the cells around the second one loads. But not both at the same time. Does anyone have any idea why?
Yes, it is possible..
- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier1 = #"ContentCell";
static NSString *CellIdentifier2 = #"SpaceCell";
// Space Cell
if (indexPath.row== 0) {
CellSpace *cell = (CellSpace *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier2];
if(cell == nil) {
cell = [[CellSpace alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier1];
// set properties
}
// set properties
return cell;
}
// Content cell
else {
CellView *cell = (CellView *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier2];
if(cell == nil) {
cell = [[CellView alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier2];
// set properties
}
// set properties
return cell;
}
}
in your custom cell, do something like this in initWithStyle method:
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"CellView" owner:self options:nil];
for (id currentObj in topLevelObjects ) {
if ([currentObj isKindOfClass:[CellView class]]) {
self = (CellView*) currentObj;
}
}
return self;
}
Yes it is possible. But before use this dequeueReusableCellWithIdentifier:. Just register your cell and corresponding nib files.
code as..
-(void)initiateCellRegisteration
{
static NSString *CellIdentifier1 = #"ContentCell";
static NSString *CellIdentifier2 = #"SpaceCell";
[self.tableView registerClass:[ContentCell class] forCellReuseIdentifier:CellIdentifier2];
[self.tableView registerNib:[UINib nibWithNibName:CellIdentifier2 bundle:nil] forCellReuseIdentifier:CellIdentifier2];
[self.tableView registerClass:[SpaceCell class] forCellReuseIdentifier:CellIdentifier1];
[self.tableView registerNib:[UINib nibWithNibName:CellIdentifier1 bundle:nil] forCellReuseIdentifier:CellIdentifier1];
}
Call this method in viewDidLoad
If you are using the cell nib then you need little tricky way to get your cell nib like
static NSString *CellIdentifier = #"ProductCell";
IVProductCell *cell = (IVProductCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray* objects = [[NSBundle mainBundle] loadNibNamed:#"IVProductCell" owner:nil options:nil];
for (id currentObject in objects) {
if ([currentObject isKindOfClass:[IVProductCell class]]){
cell = (IVProductCell*) currentObject;
}
}
}
I have a custom UITableViewCell that's loaded from a nib. I can pull this into my app with a reuseIdentifier by performing the following steps:
1) Set the reuse identifier in the Nib as "CustomCellIndentifier"
2) Register the nib:
[[self tableView] registerNib:[UINib nibWithNibName:#"CustomCell" bundle:nil] forCellReuseIdentifier:#"CustomCellIndentifier"];
3) Return the cell in tableview:cellForRowAtIndexPath
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:#"CustomCellIndentifier"];
return cell;
}
My question is, how can I return a cell WITHOUT a reuse identifier? I have a small table and I don't want the cell to be reused (it messes up some subviews I have in the cell if I scroll).
I've tried a combination of setting the above 3 reuse identifiers to nil and they all generate errors.
I've also tried this below, but the cell contents reset if I scroll past the cell and I get an error message "no index path for table cell being reused":
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:nil];
if (cell == nil) {
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"CustomCell" owner:self options:nil];
cell = [topLevelObjects objectAtIndex:0];
}
return cell;
}
I think this is not a good way, but as per your requirement Use this:
Write the init method in your CustomCell class
- (id)init
NSArray *nibObjects = [[NSBundle mainBundle] loadNibNamed:#"QuestionOptionCell" owner:self options:nil];
CustomCell *theEditView = [nibObjects objectAtIndex:0];
self = theEditView;
theEditView = nil;
return self
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
CustomCell *cell = [[CustomCell alloc] init];
if (cell == nil) {
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"CustomCell" owner:self options:nil];
cell = [topLevelObjects objectAtIndex:0];
}
return cell;
}
I would like to know where to enter custom code to change the value of a Label property for a UITableViewCell.
I am not sure how this is loaded, as I have put an NSLog in the ViewDidLoad and (id)initWithStyle instance methods but neither write to the log.
I have setup a NIB and custom class all correctly linked, and the Label is linked as a property and no longer causes an error. But I am unable to setText.
This is how the custom cell is called:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
LeftMenuTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray* views = [[NSBundle mainBundle] loadNibNamed:#"LeftMenuTableViewCell" owner:nil options:nil];
for (UIView *view in views) {
if([view isKindOfClass:[UITableViewCell class]])
{
cell = (LeftMenuTableViewCell*)view;
}
}
}
return cell;
}
This is the code in the IMP file for the LeftMenuViewCell class.
-(void)viewDidLoad {
displayName.text = [self.user objectForKey:#"displayName"];
I can set the displayName to a string and this does not change either. If I add an NSLog to the viewDidLoad for the custom cell class it is not shown, like it is not loaded, but the cell is loaded...?
Without code specifics, I can only give a vague'ish answer.
Your custom cell will need to subclass UITableViewCell, and you need to provide your table with this custom subclass when the data source method tableView:cellForRowAtIndexPath:.
I'd suggest reading up on how cells are added/used with UITableViews:
http://developer.apple.com/library/ios/#documentation/UserExperience/Conceptual/TableView_iPhone/TableViewCells/TableViewCells.html#//apple_ref/doc/uid/TP40007451-CH7-SW1
Let's say that you have custom UITableViewCell with UILabel called testLabel. If your NIB and custom class are properly linked than you can use following code:
MyTableViewCell.h
#interface MyTableViewCell : UITableViewCell
#property (nonatomic, assign) IBOutlet UILabel *testLabel;
#end
cellForRowAtIndexPath in your UITableViewController or UIViewController:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"MyTableViewCellId";
MyTableViewCell *cell = (MyTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"MyTableViewCell" owner:self options:nil];
cell = [topLevelObjects objectAtIndex:0];
}
[cell.testLabel.text = [_dataSource objectAtIndex:[indexPath row]]];
return cell;
}
Hope it helps :)
For example
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
RouteCell *routeCell = [self.tableView dequeueReusableCellWithIdentifier:routeIdentifier];
if (routeCell == nil) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"RouteCell" owner:nil options:nil];
routeCell = [nib objectAtIndex:0];
}
routeCell.travelTime.text = #"Here you are setting text to your label";
return routeCell;