How to use generate UITableView for other UIViewController? - ios

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()

Related

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

Calling a subview

#import "sideTableViewController.h"
#interface sideTableViewController ()
{
NSArray *colours;
}
#end
#implementation sideTableViewController
#synthesize colorNames;
#synthesize sideTableView;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
self.sideTableView.delegate= self;
self.sideTableView.dataSource=self;
colorNames = [NSArray arrayWithObjects:#"Archie",#"Sethi",#"Rajan" ,#"Deepak" ,nil];
}
- (NSInteger)sideTableView:(UITableView *)sideTableView numberOfRowsInSection:(NSInteger)section
{
return [colorNames count];
}
- (UITableViewCell *)sideTableView:(UITableView *)sideTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = nil;
cell = [sideTableView dequeueReusableCellWithIdentifier:#"MyCell"];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"MyCell"];
}
cell.textLabel.text =[colorNames objectAtIndex:indexPath.row];
// NSLog(#"the indexpath is %#",indexPath);
return cell;
}
- (void)sideTableView:(UITableView *)sideTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [sideTableView cellForRowAtIndexPath:indexPath];
cell.accessoryType = UITableViewCellAccessoryCheckmark;
[sideTableView deselectRowAtIndexPath:indexPath animated:YES];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
and this is the header file...
#import <UIKit/UIKit.h>
#interface sideTableViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>
{
NSArray *colorNames;
}
#property (strong, nonatomic) IBOutlet UITableView *sideTableView;
-(IBAction)showMessage;
#property (nonatomic, retain) NSArray *colorNames;
#end
I'm trying to get an image as a background to an existing tableview.
i'm getting an exception regarding: [sideTableViewController tableView:numberOfRowsInSection:]: unrecognized selector sent to instance 0x7593640
please help i'm new in IOS programming!
may this code help you simply add the below code to just above
- (NSInteger)sideTableView:(UITableView *)sideTableView numberOfRowsInSection:(NSInteger)section
add this code
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return 1;
}

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.

Adding a UITableView as a Subview

I am trying to create a view that has a UITableView as only part of that view. I believe this is the correct pattern when creating from code (not interface builder) but please feel free to add suggestions if my approach is wrong as well.
The exception I am getting is:
[KBSMoreViewController tableView:numberOfRowsInSection:]: unrecognized selector sent to instance
I have a class header as below (I am implementing the constructor in the implementation):
#import <UIKit/UIKit.h>
#interface KBSMoreTableView : UITableView
- (id)initWithFrame:(CGRect)frame style:(UITableViewStyle)style;
#end
I then have a ViewController class header as:
#interface KBSMoreViewController : UIViewController <UITableViewDataSource, UITableViewDelegate>
#end
The ViewController, which is part of a tab bar and works fine (outside of the tableview I am trying to add) implementation is written as:
#import "../Models/KBSMoreTableView.h"
#interface KBSMoreViewController ()
#property (strong, nonatomic) KBSMoreTableView* tableView;
#property (strong, nonatomic) NSString* cellIdentifier;
#property (copy, nonatomic) NSArray *source;
#end
#implementation KBSMoreViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
self.tabBarItem = [[UITabBarItem alloc] initWithTabBarSystemItem:UITabBarSystemItemMore tag:0];
self.source = [[NSArray alloc] initWithObjects:#"Test1", #"Test2", nil];
self.cellIdentifier = #"MoreCellId";
}
return self;
}
- (NSInteger)numberOfRowsInSection:(NSInteger)section
{
return self.source.count;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:self.cellIdentifier];
if (cell == nil)
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:self.cellIdentifier];
cell.textLabel.text = self.source[indexPath.row];
return cell;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.tableView = [[KBSMoreTableView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame] style:UITableViewStylePlain];
self.tableView.dataSource = self;
self.tableView.delegate = self;
[self.view addSubview:self.tableView];
}
The error is very clear. You don't implement the tableView:numberOfRowsInSection: table view data source method. Instead, you have created a method named numberOfRowsInSection:.
Change this:
- (NSInteger)numberOfRowsInSection:(NSInteger)section
to:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

UITable Cell not appearing on XIB when navigated from another XIB

I did an empty project on UITable Cells and it worked. Using the same code I added in to an existing project where there are multiple xib linked. When navigating from another xib to this page, the table cells did appear but the content and the required number of cells did not run.
Below is the code of my current project:
OptionViewController.m:
#import "OptionViewController.h"
#import "FishAppDelegate.h"
#import "MainViewController.h"
#import "PetFishViewController.h"
#import "MarineFishViewController.h"
#interface OptionViewController ()
#end
#implementation OptionViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.title =#"Choose a category :)";
// Do any additional setup after loading the view from its nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(IBAction)PetFish:(id)sender
{
PetFishViewController *petFish = [[PetFishViewController alloc]initWithNibName:nil bundle:nil];
[[self navigationController] pushViewController:petFish animated:YES];
}
// this is the sub class containing table cells
-(IBAction)MarineFish:(id)sender
{
MarineFishViewController *MarineFish = [[MarineFishViewController alloc]initWithNibName:nil bundle:nil];
[[self navigationController] pushViewController:MarineFish animated:YES];
}
#end
At the current sub class: marine fish
MarineFishController.h
#import <Foundation/Foundation.h>
#interface MarineFishViewController : UITableViewController
{
NSMutableArray *fishList;
}
#end
MarineFishController.m :
#import "MarineFishViewController.h"
#import "MarineFish.h"
#implementation MarineFishViewController
{
/*NSArray *tableData;
NSArray *thumbnail;
*/
}
-(id) init{
//call the superclass
self = [super initWithStyle:UITableViewStyleGrouped];
if(self){
fishList = [[NSMutableArray alloc] init];
MarineFish *Item1 = [[MarineFish alloc] initWithName:#"Shark" imageName:#"Sea.jpg"];
[fishList addObject:Item1];
}
return self;
}
-(id)initWithStyle:(UITableViewStyle)style{
return [self init];
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [fishList count];
}
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//create an instance of uitableviewcell
//check for a reusable cell first, use if exist
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"UITableViewCell"];
//if there is no reusable cell of this type,create new one
if(!cell)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"UITableViewCell"];
}
//set text on the cell
MarineFish *p = [fishList objectAtIndex:[indexPath row]];
[[cell textLabel] setText:[[NSString alloc] initWithFormat:#"%#",[p fishName]]];
}
#end
Regarding to the table. I only added one item to the fish list which is item1 and hence should only have one cell in display.
You don't need to override init and initWithStyle: methods. Move your code from init to viewDidLoad
- (void)viewDidLoad
{
[super viewDidLoad];
fishList = [[NSMutableArray alloc] init];
MarineFish *Item1 = [[MarineFish alloc] initWithName:#"Shark" imageName:#"Sea.jpg"];
[fishList addObject:Item1];
}
EDIT
Error was so oblivious...
-(UITableViewCell*)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
Must return a UITableViewCell object. So put return cell; at the end. Here is edited MarineFishViewController.m.

Resources