UITableView delegate and datasource in UITableViewCell - ios

I have a UITableView inside a UITableViewCell and I need to figure out how to set the sub table view datasource and delegate. At the moment this is what I have:
MainTableViewController.h
#import <UIKit/UIKit.h>
#interface MainTableViewController : UITableViewController <UITableViewDataSource, UITableViewDelegate>
#end
MainTableViewController.m
#import "MainTableViewController.h"
#import "TableViewCell.h"
#interface MainTableViewController ()
#property (weak, nonatomic) IBOutlet UITableView *tableView;
#end
#implementation MainTableViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - UITableView delegate functions
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 3;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellIdentifier = #"tableViewCell";
TableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
cell.cellLabel.text = [NSString stringWithFormat:#"%ld", (long)indexPath.row];
return cell;
}
#end
TableViewCell.h
#import <UIKit/UIKit.h>
#interface TableViewCell : UITableViewCell <UITableViewDelegate, UITableViewDataSource>
#property (weak, nonatomic) IBOutlet UILabel *cellLabel;
#property (weak, nonatomic) IBOutlet UITableView *subTableView;
#end
TableViewCell.m
#import "TableViewCell.h"
#implementation TableViewCell
-(id)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
if (self) {
self.subTableView.delegate = self;
self.subTableView.dataSource = self;
}
return self;
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 1;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"subTabeViewCell"];
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"subTabeViewCell"];
cell.textLabel.text = #"test";
return cell;
}
#end
Because I can't ctrl + drag from my sub table view to the TableViewCell class, I'm trying to set the delegate and datasource programmatically within the initialisation, but it's not working and I'm just getting straight up confused.
I know I can set the datasource and delegate to connect to the first class and then within each of the delegate functions check to see which tableView I'm dealing with, but the with the nature of what I'm trying to do it won't really work, I've tried.
So all help is welcome

So I figured it out, well i figured out a way of doing it. Within the cellForRowAtIndexPath in the MainTableViewController.m, I simply added:
[cell.subTableView setDelegate:cell];
[cell.subTableView setDatasource:cell];
And all is working away

Related

My custom table view wont display data

Github: https://github.com/nneeranjun/Maps.git
I have a CoordinatesCustomCell (TableViewCell) which contains three labels (all of which I have linked properties in the CoordinatesCustomCell.h file). When I create a cell using the reuse identifier in my TableViewController and try to change the text of the labels, they don't appear to be changed when I run the app. Please view my code with the github link above.
DataTableViewController:
#import "DataTableViewController.h"
#import "CoordinatesCustomCell.h"
#import Firebase;
FIRDatabaseQuery*data;
#implementation DataTableViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection: (NSInteger)section {
return 2;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
CoordinatesCustomCell *cell = [tableView dequeueReusableCellWithIdentifier:#"CoordinatesCustomCell" forIndexPath:indexPath];
cell.latitude.text = #"Hello";
cell.longitude.text = #"Hello";
// Configure the cell...
return cell;
}
#end
CoordinatesCustomCell.h:
#import <UIKit/UIKit.h>
#interface CoordinatesCustomCell : UITableViewCell
#property (weak, nonatomic) IBOutlet UILabel *index;
#property (weak, nonatomic) IBOutlet UILabel *latitude;
#property (weak, nonatomic) IBOutlet UILabel *longitude;
#end
You need the first call regiterNib or registerClass for your cell in viewDidLoad method
[self.tableView registerClass:[CoordinatesCustomCell class] forCellReuseIdentifier:#"CoordinatesCustomCell"];
or
[self.tableView registerNib:[UINib nibWithNibName:#"CoordinatesCustomCell" bundle:nil] forCellReuseIdentifier:#"CoordinatesCustomCell"];
if you use .xib or storyboard for prototype cell
Don't forget set
self.tableView.delegate = self;
self.tableView.datasource = self;

Subviews in UITableViewCell's containView are not added into the UI hierarchy in iOS9

I create a simple demo with storyboard on Xcode 7 with iOS9. The demo creates a tableview where the UITableViewCell contains a single UILabel. All the UI is defined on storyboard.
However, after running the demo, the app shows an empty table.
Is there someone have the same problem?
[updated the UITableViewCell code]
Cell.h
#import <UIKit/UIKit.h>
#interface Cell : UITableViewCell
#property IBOutlet UILabel *label;
#end
Cell.m
#import <Foundation/Foundation.h>
#import "Cell.h"
#implementation Cell
- (void)awakeFromNib {
// Initialization code
//[self.contentView addSubview:self.label]; //uncomment this line, it will work correctly. But in iOS7/8, we do not need to add this line.
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
#end
ViewController.m
#import "ViewController.h"
#import "Cell.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 1;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 40;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
Cell * cell = [tableView dequeueReusableCellWithIdentifier:#"testCell"];
cell.label.text = #"good";
NSLog(#"cell =%#, %#", cell.label, [cell.label superview]);
return cell;
}
#end

Self-sizing UITableViewCell with UITableView inside it - self-sizing doesn't work

I am having trouble with the new concept of self-sizing cells. They work great for simple custom cells, however, I am trying to have a UITableView inside one of my custom UITableViewCells. I thought I had set up everything correctly, the UITableView inside the cell has constraints and everything and the delegates and datasources are connected as well. What's happening is that 'numberOfRowsInSection' in ChecklistTableViewCell gets called and returns 5, but not the corresponding cellForRowAtIndexPath. Therefore, the cell that should include another UITableView is only shown as a smaller cell with no content.
My 'research' via Google has told me that cellForRowAtIndexPath might not get called because the space for the cells is too small. So, I set the rowHeight of all cells to some constant and the UITableView inside the cell is displayed - but I loose the self-sizing functionality.
Therefore, my question, do self-sizing cells not work with more complex components within custom cells or am I missing something basic or important?
First, the code of my UIViewController:
#interface MyViewController ()
#property (weak, nonatomic) IBOutlet UITableView *tableView;
#property (nonatomic, strong) NSArray *elements;
#end
#implementation MyViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.tableView.estimatedRowHeight = 500.0;
self.tableView.rowHeight = UITableViewAutomaticDimension;
}
#pragma mark - UITableView methods
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
Element *element = self.elements[indexPath.row];
if (something) {
...
} else if (something else) {
ChecklistTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"identifier"];
if (cell == nil) {
cell = [[ChecklistTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"identifier"];
}
cell.checklist = element.checklist;
return cell;
} else {
...
}
}
- (NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.elements count];
}
#end
Here is my code for the cell that has a UITableView inside of it:
#interface ChecklistTableViewCell : UITableViewCell <UITableViewDataSource, UITableViewDelegate>
#property (weak, nonatomic) IBOutlet UITableView *checklistTableView;
#property (strong, nonatomic) NSArray *checklist;
#end
#import "ChecklistTableViewCell.h"
#implementation ChecklistTableViewCell
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// Initialization code
}
return self;
}
- (void)layoutSubviews
{
[super layoutSubviews];
// Setup table view (self-sizing cells!)
self.checklistTableView.estimatedRowHeight = 50.0;
self.checklistTableView.rowHeight = UITableViewAutomaticDimension;
}
#pragma mark - UITableView methods
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
ChecklistElementTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"someIdentifier"];
if (cell == nil) {
cell = [[ChecklistElementTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"someIdentifier"];
}
cell.checklistElementTitleLabel.text = self.checklist[indexPath.row];
return cell;
}
- (NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.checklist count];
}
#end
And the code for the UIChecklistElementTableViewCell (there's no 'special' code in the .m file):
#interface ChecklistElementTableViewCell : UITableViewCell
#property (weak, nonatomic) IBOutlet UILabel *checklistElementTitleLabel;
#property (strong, nonatomic) IBOutlet M13Checkbox *checkbox;
#end
In the end, I went with implementing
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
where I return the calculated height for the cell with the table view in it and for all other cells, I return UITableViewAutomaticDimension.
It's not what I had hoped for, but it works. If anyone has another solution, I'm still very interested.
Are you sure that you set correctly you Autolayout's constraints for the cell's elements?
Did you set all the UILabel's line numbers to 0?

Using a delegate to transfer data

I have a view controller with a static cell named 'Make' I have two controllers one called "AddCarTableViewController" and "MakeTableViewController" when you click on the static cell named 'Make' it presents the make table view controller where you can select the make, then pops the view controller and am trying to store the selected value in the detailTextLabel of the static cell. here is my code for all the controllers.
The problem I'm having is once I select the make everything happens as it should I even log the selected item and it saves it after popping the view controller, but I can't figure out how to implement selected item into the detailTextLabel. Any help will be much appreciated!
"MakeTableViewController.h"
#import <UIKit/UIKit.h>
#import "AddCarTableViewController.h"
#protocol CarMakeDelegate <NSObject>
- (void)updateCarMake:(NSString *)updateMake;
#end
#interface MakeTableViewController : UITableViewController
#property (nonatomic, strong) NSArray *carMakes;
#property (nonatomic, weak) id <CarMakeDelegate> delegate;
#end
MakeTableViewController.m
#import "MakeTableViewController.h"
#interface MakeTableViewController ()
#end
#implementation MakeTableViewController {
NSIndexPath *oldIndexPath;
}
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.carMakes = [[NSArray alloc] initWithObjects:#"Acura", #"Aston Martin", nil];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [self.carMakes count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
cell.textLabel.text = [self.carMakes objectAtIndex:indexPath.row];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:NO];
oldIndexPath = indexPath;
NSString *addMake = self.carMakes[indexPath.row];
[self.delegate updateCarMake:addMake];
NSLog(#"%#", addMake );
[[self navigationController] popViewControllerAnimated:YES];
}
#end
AddCarTableViewController.h
#import <UIKit/UIKit.h>
#import "MakeTableViewController.h"
#interface AddCarTableViewController : UITableViewController
#property (strong, nonatomic) NSString *makeName;
#property (weak, nonatomic) IBOutlet UITableViewCell *makeCell;
#end
AddCarTableViewController.m
#import "AddCarTableViewController.h"
#interface AddCarTableViewController ()
#end
#implementation AddCarTableViewController
- (void)viewDidLoad
{
[super viewDidLoad];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return 4;
}
-(void)updateCarMake:(NSString *)updateMake {
self.makeCell.detailTextLabel.text = updateMake;
}
#end
You don't need to use delegate in this case. Just update the underlying data model. and call
[tableview reloadData];
When the makeViewController is popped.
In the AddCarVC's cellForRowAtIndex, add another line to check if current indexPath corresponds to Make cell and if it does update the detailLabel text.

IBOutlet works in iOS 6 but null in iOS 4.3?

I have a custom view for my tableview's header
UIView *headerTableview_;
#property (nonatomic, retain) IBOutlet UIView *headerTableview;
I have connected it to xib file.
Then in .m file,
#synthesize headerTableview = headerTableview_;
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{
return headerTableview_.frame.size.height;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{
return headerTableview_;
}
Then, I try to run it, in iOS 6 it's displayed well, but in iOS 4.3, it's not displayed at all.
What could be the problem? Anyone knows how to fix this weird problem?
Thanks!
In your .h file
#interface testViewController : UIViewController <UITableViewDataSource, UITableViewDelegate>
{
UITableView *tableView;
}
#property (retain, nonatomic) IBOutlet UIView *testView;
#end
In your .m file
#implementation testViewController
#synthesize testView;
- (void)viewDidLoad
{
[super viewDidLoad];
tableView = [[UITableView alloc]initWithFrame:self.view.frame style:UITableViewStylePlain];
tableView.delegate = self;
tableView.dataSource =self;
[self.view addSubview:tableView];
[self.view bringSubviewToFront:tableView];
// Do any additional setup after loading the view, typically from a nib.
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{
return testView.frame.size.height;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{
return testView;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return 2;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return 3;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = #"Products";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];}
//UIImage *currentTweet = [[xmlParser tweets] objectAtIndex:1];
cell.textLabel.text= #"text label";
cell.detailTextLabel.text=#"detailTextLabel";
return cell;}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)dealloc {
[testView release];
[super dealloc];
}
#end
Create a new class file named HeaderTableview. See if this initializes properly when assigning in IB.
//.h
#class HeaderTableview;
#interface ViewController : UIViewController
#property (nonatomic, retain) IBOutlet HeaderTableview *headerTableview;
//.m
#synthesize headerTableview = _headerTableview;
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{
return _headerTableview.frame.size.height;
}

Resources