So I'm trying to rename a UILabel inside an instance of the UITableViewCell class from an instance of UITableView, however, the UILabel is not loaded by that time and so when I print it out in the debugger, it's nil.
So, instead I made a NSString inside the UITableViewCell and set that instead, which behaves expectedly because the debugger prints it out as what I set it.
Now my question is where in the lifecycle should I set the UILabel with the NSString that I successfully set
-(void) layoutSubviews
{
[super layoutSubviews];
self.fileLabel.text = self.fileName;
NSLog(#"filelabel.text: %#", self.fileLabel.text);
}
layoutSubviews is not working is there any other method which I should use?
If i understand your question- you are trying to add a label to a subclass of UITableViewCell, if so then use cellForRowAtIndexPath method like -
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
YourCell *urCell = (YourCell *)cell;
// Configure the cell...
urCell.fileLabel.text = #"Some text";
return cell;
}
Why don't you set it in the - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath method? This method is supposed to be called when you are laying out the cell and this is also possibly where you would be adding the label to the cell.
Related
I want a tableview inside another tableviewCell like the following image.It shows one complete cell with a few details and a tableview. How can i do this?I was following this link Link.This is an old code .It is using xibs.I dont have any idea where to set the delegate for the inner tableview.Please help.Any suggestion will be realy helpfull.
My first idea would be:
Subclass UITableViewCell ("MainTableViewCell") and extend it with UITableViewDelegate and UITableViewDatasource.
Next to all the properties you need in "MainTableViewCell" add a TableView "tableViewFilms" and an array "films" for the Films. Also don't forget to add the datasource methods for a tableview to the implementation file.
To easily setup a cell I add a setup-method to the header-file. Which can be called once the cell is instantiated. You can modify it as you want, give it as many parameters as you want and in the implementation (see step 4) set datasource and delegate of your inner tableview.
- (void)setupCellWithDictionary:(NSDictionary *)dict AndArray:(NSArray *)filmsForInnerTable;
You can call this method in your datasource method, once a cell is instantiated:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
MainTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"MainTableViewCell" forIndexPath:indexPath];
NSDictionary *dict = (NSDictionary *) allDataDictionaries[indexPath.row];
[cell setupCellWithDictionary:dict AndArray:filmsForInnerTable];
return cell;
}
Subclass UITableViewCell another time: "FilmTableViewCell"
When setting up the a Cell of "MainTableViewCell", set the delegate and the datasource of "tableViewFilms" to self (object of "MainTableViewCell").
- (void)setupCellWithDictionary:(NSDictionary *)dict AndArray:(NSArray *)filmsForInnerTable{
self.films = filmsForInnerTable;
self.tableViewFilms.dataSource = self;
self.tableViewFilms.delegate = self;
[self.tableView reload];
//more instructions
}
Populate the tableview with the data from the array "films" using "FilmTableViewCells".
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
FilmTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"FilmTableViewCell" forIndexPath:indexPath];
Film *film = (Film*)films[indexPath.row];
[cell setupCellWithFilm:film];
return cell;
}
Hope this helps.
Don't forget to use Outlets, the method definitions and to set the reuse-identifiers for the cells!
Check my answer in this ios 8 Swift - TableView with embedded CollectionView. You have replace that UICollectionView with UITableView.
Everything else is pretty much the same. Its just a head start with UITableView and UICollectionView created programmatically.
I can change it accordingly if you don't understand.
I have custom cell called MyCustomCell, there is a label named pushLabel, in table view I get parameters of label like this:
cell.pushLabel.text = #"text";
I need to get in that label parameters in viewDidLoad (where table view is located), how this can be done?
In viewDidLoad method, UITableView still should have not been loaded so there no way you can get UITableViewCell objects.
One solution can be, maintain flag say you have
//Add in your .h file
BOOL hidePushLabel;
Now use these flag to hide intially in tableview like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *strCellIndentifier = #"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:strCellIndentifier];
if (cell)
{
//By default hidePushLabel will be NO so hide pushLabel
if(!hidePushLabel)
cell.pushLabel.hidden = YES;
else
cell.pushLabel.hidden = NO;
}
return cell;
}
On my UITableViewI am using custom UITableViewCells. Each of these cells has a number of labels. When the user selects a cell, I need to capture the contents of just one of these labels, but I don't know how to do that. Here is my code. The line that I am using to attempt to get this label text is basically pseudo-code that clearly won't compile. Can somebody please tell me what I need to do here? Thanks!
- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
...
Groups *group = [self.fetchedObjects objectAtIndex:indexPath.row];
cell.groupDescriptionLabel.text = group.group_descr;
cell.groupIDLabel.text = [group.group_id stringValue];
return cell;
}
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// capture the user selection
Groups *group = [self.fetchedObjects objectAtIndex:indexPath.row];
UITableViewCell *selectedCell = [tableView cellForRowAtIndexPath:indexPath];
NSString *selection = selectedCell.groupDescriptionLabel.text; //<-- pseudo-code
NSLog(#"%#", group.group_descr);
...
}
It's generally a bad idea to get data out of the view. You shouldn't really be using any view objects as a way of storing information.
You are already getting the string when you are in the cellForRowAtIndexPath method.
You should be able to do the same in didSelectRowAtIndexPath to get the same string.
That way you don't have to get the text out of the label at all.
Thanks
If you know that celForRowAtIndexPath is going to be returning one of your custom cell types instead of a generic UITableViewCell, cast the result to your custom cell class:
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// capture the user selection
MyCellClass *selectedCell = (MyCellClass *) [tableView cellForRowAtIndexPath:indexPath];
NSString *selection = selectedCell.groupDescriptionLabel.text; //<-- pseudo-code
NSLog(#"%#", selection);
//...
}
I'm wondering if there is any difference between these two approaches of setting properties on a UITableViewCell.
Option A:
In your storyboard file, on your UITableViewCell, drag your UIElements onto the UITableViewCell, tag each UIelement. Then in:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReuseableCellIdentifier:#"MyCell"];
UILabel *aLabel = [cell viewWithTag:TAG_FROM_IB];
aLabel.text = #"my text";
UIImageView *aImageView = [cell viewWithTag:TAG_FROM_IB];
aImageView.image = [UIImage imageNamed:#"myImage.png"];
return cell;
}
option B:
Drag the UIElements onto the UITableViewCell in the storyboard. Create a custom subclass of UITableViewCell, change the class of the UITableViewCell to your new custom subclass, access the properties by:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
MyTableViewCell *cell = [tableView dequeueReuseableCellIdentifier:#"MyTableViewCell"];
cell.aLabel.text = #"my text";
cell.aImageView.image = [UIImage imageNamed:#"myImage.png"];
return cell;
}
I was just wondering if there was a "preferred" or "better" way to create custom UITableViewCells. Thanks!
definitly no. two!
it much more concise: cleaner and clearer to use then! performance wise it is also superior BUT thats not a measurable amount...
+(IMHO) performance should never be the initial reason for a design decision.
So I am trying to display horizontally scrollable collection view inside tableviewcell. the code i am using is
(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = (UITableViewCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
UICollectionViewController *cv = [self.storyboard instantiateViewControllerWithIdentifier:#"collectionViewID"];
cv.view.frame = cell.contentView.bounds;
[self addChildViewController:cv];
[cell.contentView addSubview:cv.view];
[cv didMoveToParentViewController:self];
return cell;
}
I am getting error: Object can not be nil. I'd appreciate if someone can help me out understanding the error.
I have done this in my app.
I found it much easier to subclass UITableViewCell. The I could put all the UICollectionView setup and the UICollectionView datasource and delegate inside the code for the cell.
I then provided one public property of type NSArray which I pass into the cell. The cell then uses this array as the datasource for the UICollectionView that it owns itself.
Made it a lot easier to manage.
check your UICollectionViewControlle's attribute inspector for identifier value {collectionViewID}
EDIT
[self addChildViewController:cv]; --> I think you want to add cv to the cell, isn't you?