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.
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.
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;
}
data values i have one text filed and two buttons.One button is save,second button is show.
when click save button data will be Stored in Core-Data and then i click Show button data will be displayed on Console. It gone nice.
But now i want when Click show button data will be displayed on UITableView So Please Give me any idea
Thanks in advanced,
this is my code:-
#import "SetViewController.h"
#import "AppDelegate.h"
#interface SetViewController ()
{
NSMutableArray *array;
}
#end
#implementation SetViewController
#synthesize textField;
- (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.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)save:(id)sender {
AppDelegate *appD=(AppDelegate *) [[UIApplication sharedApplication]delegate];
NSEntityDescription *entit=[NSEntityDescription insertNewObjectForEntityForName:#"Team" inManagedObjectContext:appD.managedObjectContext];
[entit setValue:textField.text forKey:#"fname"];
NSError *error;
BOOL isSaved=[appD.managedObjectContext save:&error];
NSLog(#"succesfully saved flag: %d",isSaved);
}
- (IBAction)show:(id)sender {
AppDelegate *appDelegat=(AppDelegate*)[[UIApplication sharedApplication]delegate];
NSEntityDescription *entity=[NSEntityDescription entityForName:#"Team" inManagedObjectContext:appDelegat.managedObjectContext];
NSFetchRequest *fetchRr = [[NSFetchRequest alloc]init];
[fetchRr setEntity:entity];
array=[[appDelegat.managedObjectContext executeFetchRequest:fetchRr error:nil]mutableCopy];
NSLog(#"array %#",array);
for (NSManagedObject *obj in array) {
NSLog(#"Name :%#\n",[obj valueForKey:#"fname"]);
}
}
-(BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return YES;
}
#end
i am tried like this :-
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"ShowData"])
{
ShowViewController *destViewController = segue.destinationViewController;
destViewController.second = [[array valueForKey:#"fname"] componentsJoinedByString(angry)" , "];
NSLog(#" got data for array %#",destViewController.second);
}
}
ShowViewController.h:-
#import <UIKit/UIKit.h>
#import "SetViewController.h"
#interface ShowViewController : UITableViewController<UITableViewDelegate,UITableViewDataSource>
#property (nonatomic, strong) NSString *second;
#end
ShowViewController.m:-
import "ShowViewController.h"
#interface ShowViewController ()
{
NSMutableArray *acess;
}
#end
#implementation ShowViewController
#synthesize second;
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
acess =[second componentsSeparatedByString:#", "];
}
- (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 [acess count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] ;
}
cell.textLabel.text = [acess objectAtIndex:indexPath.row];
return cell;
}
ShowViewController is UITableView.When Click UItableView is open but data will be not Displayed So Please give me any idea
Follow following steps and also read programming guide of UITableview provided by apple:
After getting the array just reload your table view.
Make number of rows = array count.
Customize the cell as per your need.
If you only declared the array as per you shown in code then you must need to initialise it in view did load like this:
array=[NSMutablearray array];
after that get the values from db and stored in array an use UITable view delegate and datasource methods.
First declare your array in your viewDidload() method.
- (void)viewDidLoad
{
yourArray=[[NSArray alloc]initWithObjects:Obj1,obj2,obj3,obj4,obj5, nil];
}
and then use tableview delegate methods. to set array data to tableview.
- (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 [yourArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
// Configure the cell...
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"Cell"];
}
cell.textLabel.text=[yourArray objectAtIndex:indexPath.row];
return cell;
}
If you already have an NSArray that contains your strings, there is no need to go through the whole componentsJoinedByString/componentsSeparatedByString - you can just pass the array to your second view controller.
Accessing the passed data in viewDidLoad won't work though because when you set the property in prepareForSegue the view has already loaded.
Your prepareForSegue should be -
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"ShowData"])
{
ShowViewController *destViewController = (ShowViewController *)segue.destinationViewController;
destViewController.fnames = [array valueForKey:#"fname"];
}
}
In your .h file for ShowViewController declare a property to receive frames -
#property (strong,nonatomic) NSArray *fnames;
Then your table data source methods will be -
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.fnames 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.fnames objectAtIndex:indexPath.row];
return cell;
}
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.