why init method in cell won't get called when dequeueReusableCellWithIdentifier happened - ios

my code look like this
viewcontroller.m
- (void)viewDidLoad {
[super viewDidLoad];
UITableView *tableView = [[UITableView alloc] init];
tableView.delegate = self;
tableView.dataSource = self;
[tableView registerClass:[TableViewCell class] forCellReuseIdentifier:#"cell"];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
TableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell" forIndexPath:indexPath];
cell.textLabel.text = #"Hello, world";
cell.delegate = self;
return cell;
}
cell.m
- (void)awakeFromNib {
[super awakeFromNib];
[self commonInit];
// Initialization code
}
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self commonInit];
}
return self;
}
- (void)commonInit
{
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(longPress)];
[self addGestureRecognizer:longPress];
}
- (void)longPress
{
[self.delegate actionTriggered:self];
}
so screen shows a tableview with only one cell contains "hello world"
when use long press gesture nothing happened.
so I set a break point in commonInit.
find out this method does not get called.
can't figure out why. and how to fix it.
appreciating any helps.

In 'viewDidLoad' you create a local variable 'tableView'. That variable gets out-of-scope as soon as the method completes.
This can't work.
Assuming the class in your viewcontroller.m file inherits from UITableViewController you just have to make sure you configure the existing tableView property instead of creating a local variable:
-(void)viewDidLoad {
[super viewDidLoad];
// UITableView *tableView = [[UITableView alloc] init]; <-- Don't!
tableView.delegate = self;
tableView.dataSource = self;
[tableView registerClass:[TableViewCell class] forCellReuseIdentifier:#"cell"];
}

Related

Whats wrong with my code,The datasource methods are not called

My code is:
- (instancetype)init {
self = [super initWithNibName:nil bundle:nil];
if (self) {
_tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 20, self.view.frame.size.width, self.view.frame.size.height - 20)
style:UITableViewStylePlain];
for (int i = 0; i < 10; i++) {
[[LHItemSharedStore sharedStore] createItem];
}
}
return self;
}
- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
return [self init];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self.tableView reloadData];
}
- (void)viewDidLoad {
[super viewDidLoad];
self.tableView.delegate = self;
self.tableView.dataSource = self;
[self.view addSubview:self.tableView];
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:#"UITableViewCell"];
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return [[[LHItemSharedStore sharedStore] items]count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"UITableViewCell" forIndexPath:indexPath];
cell.textLabel.text = #"test";
return cell;
}
As the code show, the datasource methods are not called. but when I put
[self.view addSubView:self.tableView];
In viewWillAppear, the methods can be called correctly, also works when I change [self.view addSubView:self.tableView]; to self.view = self.tableView;
The problem with your code is, that init is probably called after viewDidLoad , thus your table view is still nil when your setting the delegates.
problem solved!
seems that i use self.view.fram in my init method, then loadview is called, then call viewDidLoad, in viewDidLoad the init process of _tableView is not end, so _tableView is nil. if I set self.view = self.tableView in viewDidLoad, it will be called util self.tableView is not nil.
benifit i get it is that put view init into viewDidLoad.

How to use generate UITableView for other UIViewController?

I am trying to use a generated UITableView in my UIViewController.
This is how I am trying to generate:-
TableViewGeneratorController.h
#import <UIKit/UIKit.h>
#interface TableViewGeneratorController : UITableViewController<UITableViewDataSource,UITableViewDelegate>
#property(nonatomic,retain) UITableView *tableView;
- (UITableView *)getTableView;
#end
TableViewGeneratorController.m
#import "TableViewGeneratorController.h"
#interface TableViewGeneratorController (){
}
#end
#implementation TableViewGeneratorController
#synthesize tableView;
- (void)viewDidLoad {
[super viewDidLoad];
}
- (id)initWithNibName:(NSString )nibNameOrNil bundle:(NSBundle )nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self){
self.tableView = [[UITableView alloc]initWithFrame:CGRectMake(10, 80, 300, 400)];
tableView.delegate = self;
tableView.dataSource = self;
tableView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
[tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:#"Cell"];
}
return self;
}
- (UITableView *)getTableView
{
return self.tableView;
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 20;
}
- (UITableViewCell )tableView:(UITableView )tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *cellIndentifier = #"Cell";
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:cellIndentifier];
if (cell == nil){
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIndentifier];
}
cell.textLabel.text = #"Yes";
return cell;
}
#end
Now In my UIViewController I am calling that getTableView and adding the UITableView as subview but I am getting exception:-
ViewController.m
TableViewGeneratorController *tableViewGeneratorController = [[TableViewGeneratorController alloc]init];
UITableView *tableView = [tableViewGeneratorController getTableView];
[self.view addSubview: tableView ];
Exception:-
* Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[_UIAppearanceCustomizableClassInfo numberOfSectionsInTableView(inlove): unrecognized selector sent to instance 0x7b1ba7e0'
* First throw call stack:
You should NOT generate any controls in your init function. The init function is only for logic initialization (like setting a bool to YES). Move your table code to viewDidLoad.
This will usually throw errors, since the view is not ready yet.
TableViewGeneratorController.h
#interface TableViewGeneratorController : UIViewController
#property(nonatomic, strong) UITableView *tableView;
- (id)initWithNibName:(NSString )nibNameOrNil bundle:(NSBundle )nibBundleOrNil frame:(CGRect)frame;
- (UITableView *)getTableView;
#end
TableViewGeneratorController.m
#implementation TableViewGeneratorController
#synthesize tableView = _tableView;
- (id)initWithNibName:(NSString )nibNameOrNil bundle:(NSBundle )nibBundleOrNil frame:(CGRect)frame
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self)
{
_tableView = [[UITableView alloc]initWithFrame:frame];
_tableView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
[_tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:#"Cell"];
}
return self;
}
- (UITableView *)getTableView
{
return _tableView;
}
#end
ViewController.m
TableViewGeneratorController *tableViewGeneratorController = [[TableViewGeneratorController alloc] init];
UITableView *tableView = [tableViewGeneratorController getTableView];
tableView.delegate = self;
tableView.dataSource = self;
[self.view addSubview:tableView];
[tableView reloadData];
Implement table view delegate in ViewController.m
initWithNibName() will never be called if you intialize the tableViewGeneratorController with init()

Objective-C custom UITableView class doesn't load

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;
}

UITableView as subview is always empty

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.

UITableViewController not showing data [duplicate]

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.

Resources