In XCode 5 I startet with the Tab-Bar example and added a UITableView to my ViewController in storyboard. I'd like to use a custom class for that UITableView, so I added a new class to my project and set the class of my UITableView to be that new class in storyboard. I also set the cellIdentifier. The problem is that the app is still using the default UITableView class.
Could you please tell me what I'm missing?
Here is my custom UITableView class
#import <UIKit/UIKit.h>
#interface CustomTableView : UITableView <UITableViewDelegate, UITableViewDataSource>
#end
#implementation CustomTableView
- (CustomTableView*) init {
self = [super init];
if (self) {
self.delegate = self;
self.dataSource = self;
self.autoresizingMask = UIViewAutoresizingFlexibleHeight;
[self reloadData];
}
return self;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 3;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 20;
}
- (NSString*)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
return #"header title";
}
- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString* staticCellIdentifier = #"customIdentifier";
UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:staticCellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:staticCellIdentifier];
}
cell.textLabel.text = #"cellTitle";
return cell;
}
#end
You need to implement initWithCoder: which is the designated initializer interface builder uses.
Something like this:
- (CustomTableView*) initWithCoder:(NSCoder *)aDecoder{
self = [super initWithCoder:(NSCoder *)aDecoder];
if (self) {
self.delegate = self;
self.dataSource = self;
self.autoresizingMask = UIViewAutoresizingFlexibleHeight;
[self reloadData];
}
return self;
}
Related
I'm trying to create a view programmatically which will have two views inside of it, one is for searching and the other one is a tableview which will shows photos;
But i'm having EXC_BAD_ACCESS error with code=2, all of the controller code is below. I suspected there is an infinite loop, but don't understand why.
Thanks for any help...
#interface PhotosViewController () <UITableViewDataSource, UITableViewDelegate>
#property (strong, nonatomic) UITableView *tableView;
#end
#implementation PhotosViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.title = #"Instagram";
[self.tableView registerClass:[PhotoTableViewCell class] forCellReuseIdentifier:CellIdentifier];
self.tableView.estimatedRowHeight = UITableViewAutomaticDimension;
self.tableView.allowsSelection = NO;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)loadView
{
_tableView = [[UITableView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame] style:UITableViewStylePlain];
_tableView.autoresizingMask = UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth;
_tableView.delegate = self;
_tableView.dataSource = self;
[_tableView reloadData];
[self.view addSubview:_tableView];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
PhotoTableViewCell *cell = (PhotoTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
// Configure the cell...
[self configureCell:cell atIndexPath:indexPath];
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
// NSLog(#"%f", self.navigationController.navigationBar.bounds.size.height);
return /*tableView.bounds.size.height -self.navigationController.navigationBar.bounds.size.height -*/40.0;
}
#pragma mark - Helper Methods
- (void)configureCell:(PhotoTableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath {
// configure photo cell
if (cell == nil) {
cell = [[PhotoTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.namelabel.text = #"Mister Tester";
cell.dateLabel.text = #"2 hours ago";
}
In loadView should you not call [super loadView] or assign self.view first.
I believe reading self.view without that can cause an infinite loop.
i have created a UItableView named _tableView, here is the code for table view in view.m
- (void)viewDidLoad
{
[super viewDidLoad];
tableData = [NSArray arrayWithObjects:#"Team Members",#"MembershipStatus",#"relation of status",#"Registerd events", nil];
[_tableView setUserInteractionEnabled:TRUE];
[_tableView reloadData];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [tableData count];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 54;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
[newCell setUserInteractionEnabled:TRUE];
newCell.textLabel.text = [tableData objectAtIndex:indexPath.row];
return newCell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"id");
}
while executing the code I got the table correctly. But when i am selecting one of the list item it won't respond. (i.e., the NSLog is not working). did i miss something ?? or what i do wrong ??
In your -viewDidLoad write:
[_tableView setDelegate:self];
check if the tableview's delegate is set to your viewController
#interface MyView : UIViewController <UITableViewDelegate, UITableViewDataSource>
in viewDidLoad:
self.tableview.delegate=self;
Check with your code
#interface ClassName : UIViewController <UITableViewDelegate, UITableViewDataSource>
in viewDidLoad:
self.tableView.delegate = self;
self.tableView.dataSource = self;
or
_tableView.delegate = self;
_tableView.dataSource = self;
check in .h file
#interface MyView : UIViewController is set or Not. if its not set then Set 1st there.
then in .m File while Creating TableView there
you just write
_tableView.delegate = self;
_tableView.dataSource = self;
I have a ViewController which has several subviews (Graphs) added using function
[self.view addSubview:subView]
Now, I want to add a UITableView as subview, but when I do this, my table is always empty. Methods like numberOfSectionsInTableView, numberOfRowsInSection, etc are never called.
My table doesn't have a XIB file. This is the code from my .M file:
#import "TableSubviewViewController.h"
#implementation TableSubviewViewController
#synthesize data;
#synthesize tableFrame;
-(id)initWithStyle:(UITableViewStyle)style{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
-(void)viewDidLoad{
[super viewDidLoad];
self.view.frame = tableFrame;
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return [[self.data allKeys]count];
}
-(NSString*)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{
return [[self.data allKeys]objectAtIndex:section];
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return 1;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if(cell == nil){
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.textLabel.text = #"Some text";
return cell;
}
And this is the code in my main ViewController, in which I'm creating TableSubviewViewController:
TableSubviewViewController *tableSubView = [[TableSubviewViewController alloc]initWithStyle:UITableViewStyleGrouped];
tableSubView.tableFrame = tableFrame;
tableSubView.data = data;
[self.view addObject:tableSubView.view];
What Am I missing?
Thank you
TableSubviewViewController tableSubView must be main ViewController's global variable , can't be a local variable in the method viewDidLoad of main ViewController
U need to set datasource and delegate methods do like this
// in TableSubviewViewController.h file put a custom initilizer
#interface TableSubviewViewController : UIViewController
- (id)initTheSubviewTableVIewWithFrame:(CGRect)rect; //your custom initialiser
#end
//TableSubviewViewController.m file
#import "TableSubviewViewController.h"
#interface TableSubviewViewController ()<UITableViewDataSource,UITableViewDelegate>
#end
#implementation TableSubviewViewController
//dont use this method left blank
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialisation
}
return self;
}
//you can make custom initiliser method
- (id)initTheSubviewTableVIewWithFrame:(CGRect)rect
{
self = [super init];
if(self)
{
UITableView *subViewTable = [[UITableView alloc]initWithFrame:rect];//since u are creating the tableview programatically u need to set datasource and delegate programatically
subViewTable.dataSource = self; //add this
subViewTable.delegate = self; //this also
[self.view addSubview:subViewTable];
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
//datasource and delegate methods
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return 2;
}
//use as reqired
//-(NSString*)tableView:(UITableView *)tableView titleForHeaderInSection: (NSInteger)section{
// return 3;
//}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return 1;
}
-(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 = #"Some text";
return cell;
}
//in main ViewController.m controler u need to do like this
TableSubviewViewController *subViewTable = [[TableSubviewViewController alloc]initTheSubviewTableVIewWithFrame:CGRectMake(self.view.bounds.origin.x, self.view.bounds.origin.y, self.view.bounds.size.width, 150)];//created the subviewTableView tableview
//set properties that u defined for tableview delegate and datasource
[self.view addSubview:subViewTable.view];
hope this helps u :)
Make sure your .h file use
and set delegate and datasource to self.
TableSubviewViewController *tableSubView = [[TableSubviewViewController alloc]initWithStyle:UITableViewStyleGrouped];
tableSubView.tableFrame = tableFrame;
tableSubView.delegate = self;
tableSubView.dataSource = self;
tableSubView.data = data;
[self.view addObject:tableSubView.view];
After that check whether array self.data have object or not. It might be possible that array is blank.
Why isn't the numberOfSectionsInTableView method not being called? It's called if I add [self.tableView reloadData] in viewDidLoad, but even then, cellForRow does not get called.
Edit: I updated the following code to register the nib for the UITableViewCell.
In a UIViewController, I have:
- (void)viewDidLoad
{
[super viewDidLoad];
XXFeedTableViewController *tableViewController = [[XXFeedTableViewController alloc] initWithStyle:UITableViewStylePlain];
tableViewController.view.frame = self.view.bounds;
[self addChildViewController:tableViewController];
}
XXFeedTableViewController.h
#interface XXFeedTableViewController : UITableViewController
#end
XXFeedTableViewController.m
#import "XXFeedTableViewController.h"
#import "XXFeedTableViewCell.h"
#interface XXFeedTableViewController ()
#end
#implementation XXFeedTableViewController
- (id)initWithStyle:(UITableViewStyle)style {
self = [super initWithStyle:style];
if (self) {
}
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
[self.tableView registerNib:[UINib nibWithNibName:#"XXFeedTableViewCell" bundle:nil] forCellReuseIdentifier:#"XXFeedTableViewCell"];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 5;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"XXFeedTableViewCell";
XXFeedTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
cell.textLabel.text = #"Hey";
return cell;
}
#end
Apple docs say:
If no nib file is specified or if the nib file defines no data source
or delegate, UITableViewController sets the data source and the
delegate of the table view to self. When the table view is about to
appear the first time it’s loaded, the table-view controller reloads
the table view’s data.
Try this, and see if it works. This is the way Apple recommends now with a nib based cell.
-(void)viewDidLoad {
[super viewDidLoad];
[self.tableView registerNib:[UINib nibWithNibName:#"XXFeedTableViewCell" bundle:nil] forCellReuseIdentifier:#"XXFeedTableViewCell"];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 5;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"XXFeedTableViewCell";
ROFeedTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
cell.textLabel.text = #"Hey";
return cell;
}
After Edit:
In your initial controller, you should add the table view controller as a child controller before you add its subview:
XXFeedTableViewController *tableViewController = [[XXFeedTableViewController alloc] initWithStyle:UITableViewStylePlain];
self addChildViewController:tableViewController];
tableViewController.view.frame = self.view.bounds;
[self.view addSubview:tableViewController.view];
[tableViewController didMoveToParentViewController:self];
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
UITableViewController not loading data
I have created a UITableViewController in the following way
#import "KLActionsViewController.h"
#interface KLActionsViewController ()
#end
#implementation KLActionsViewController
#synthesize actionList,delegate;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)loadView
{
}
- (void)viewDidLoad {
[super viewDidLoad];
NSMutableArray* list = [[NSMutableArray alloc] init];
self.tableView = [[UITableView alloc] init];
self.tableView.delegate = self;
self.tableView.dataSource = self;
self.actionList = list;
self.clearsSelectionOnViewWillAppear = NO;
self.contentSizeForViewInPopover = CGSizeMake(320.0, 400.0);
[self.actionList addObject:#"Obj1"];
[self.actionList addObject:#"Obj2"];
[self.actionList addObject:#"Obj3"];
[self.actionList addObject:#"Obj4"];
}
- (int)numberOfSectionsInTableView:(UITableView *)tableView
{
NSLog(#"in number of section");
return 1;
}
- (UITableViewCell *)cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
NSString* lab = [self.actionList objectAtIndex:indexPath.row];
// NSLog(lab);
NSLog(#"here in there");
cell.textLabel.text = lab;
return cell;
}
- (NSInteger)numberOfRowsInSection:(NSInteger)section
{
NSLog(#"Total entries : %i ",[self.actionList count]);
return [self.actionList count];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (self.delegate != nil) {
[self.delegate actionSelected:indexPath.row];
}
}
- (void)viewDidUnload
{
[super viewDidUnload];
self.actionList = nil;
self.delegate = nil ;
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#end
But when I try to create it's instance and show it in a UIPopoverController all I can see is an empty table and no data in it. Also, numberOfRowsInSection and cellForRowAtIndexPath never get called.
Any help ?
You are creating a new table view inside viewDidLoad: but not making it a subview of this controller's view. Since you say you see an empty table, this leads me to believe that you're loading one table from your .xib file, but setting the dataSource only of this new one.
If that's how it's structured, use a connection in the .xib from the table view to the self.tableView property and don't create a new object...just configure the one you have.