I'm newbie in iOS development, and have a problem with my application. I have implemented a tabbar navigation and a TableView, but when call method didselectrowatindexpath i dont see the detailView linked. This is the code of my app:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"ciao");
// UITableViewStyleGrouped table view style will cause the table have a textured background
// and each section will be separated from the other ones.
controller = [[DetailViewController alloc] init];
//initWithStyle:UITableViewStyleGrouped
//andDvdData:[dao libraryItemAtIndex:indexPath.row]];
controller.title = [[dao libraryItemAtIndex:indexPath.row] valueForKey:#"content"];
[self.navigationController pushViewController:controller animated:YES];
}
#import "DetailViewController.h"
#interface ListItemsTableView : UIViewController {
IBOutlet UITableView *myTableView;
Dfetch *dao;
DetailViewController *controller;
}
You're not using the right initializer for UIViewController.
The one you're expected to use is [UIViewController initWithNibName: bundle:] (documentation at Apple linked for you).
I suspect your "controller" object is NULL.
Related
say I have a UITableView and upon selecting a new table row (thus firing the delegate method), I want to load a new UIView (which I have created in storyboard) and pass to it a data item.
Obviously the new UIView is added as a UIViewController in storyboard and has its own controller class..
How would I go about doing that?
Thank you!
Try something along the lines of this:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
DetailViewController *dvController = [[DetailViewController alloc] initWithNibName:#"DetailView" bundle:[NSBundle mainBundle]];
[self.navigationController pushViewController:dvController animated:YES];
}
If you are using storyboards and not XIB files, use this code...
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
DetailViewController *dvController = [self.storyboard instantiateViewControllerWithIdentifier:#"DetailViewController"];
[self.navigationController pushViewController:dvController animated:YES];
}
Also you need to set the "Identifier" field in Interface Builder to the name used in self.storyboard instantiateViewControllerWithIdentifier:
Cheers!
I'm loading a UIViewController into one of my Nav controller's hierarchies, which will contain some text and some images. At the bottom, I will want to create a expandable and collapsable tableview.
First off, is this idea possible? If it is, how do I add it and where do I place the data source and delegate methods?
Can I just make a separate subclass of the TableViewController and then add it to my ViewController as a subview?
Yes, you can create a UITableView whose delegate, datasource, and parent view are not necessarily a UITableViewController. Since the UITableView is a UIView, you can add it as a subview of any other UIView. Any NSObject can be the delegate or datasource, as long as you implement the required protocol methods.
#interface MyViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>
In fact, in my experience, not many people even use UITableViewControllers. When was the last time you wanted your table view to take up the entire usable space? In general, I create a plain old UIViewController and add a UITableView as a subview of its view, in addition to other subviews.
/************************************************/
/************* MyCustomController.m *************/
/************************************************/
#interface MyCustomController () <UITableViewDataSource, UITableViewDelegate>
#property (nonatomic, strong) UITableView *tableView;
#end
#implementation MyCustomController
- (id)initWithNibName:(NSString*)nibName bundle:(NSString*)bundleName
{
self = [super initWitNibName:nibName bundle:bundleName];
if (self)
{
self.tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
tableView.datasource = self;
tableView.delegate = self;
[self.view addSubview:self.tableView];
}
return self;
}
#pragma mark - UITableViewDataSource Methods
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// return number of rows
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// return cell
}
#pragma mark - UITableViewDelegate Methods
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// handle table view selection
}
#end
It's pretty easy, in something like your viewDidLoad method:
UITableView *tableView = [[UITableView alloc] initWithFrame:self.view.bounds];
[self.view addSubview:tableView];
Just remember that a UITableViewController is a subclass of UIViewController only with the tableview set as the controller's view.
So yes definitely possible and used quite frequently when you want to have a tableview but also other custom UI elements which prevent you from using the UITableViewController.
I'd normally choose to add it to my view controller's view in either its initialisation method or viewDidLoad method. This will vary based on whether you're creating your views from a NIB or entirely programatically.
In case of NIBs:
- (id)initWithNibName:(NSString*)nibName bundle:(NSBundle*)bundleName
{
if ((self = [super initWitNibName:nibName bundle:bundleName]))
{
self.theTableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewWhateverStyleYouWantHere];
theTableView.dataSource = self, theTableView.delegate = self;
[self.view addSubview:theTableView];
[theTableView release];
}
}
And then you can set the frame of your tableview in your viewDidLoad method.
I'd personally prefer to do the whole thing in interface builder as you'd achieve the same result with way less code to maintain.
If you're like me and already had created a UITableViewController and then realizing that you did so much work on it that re-writing it would be a pain, you can just do the following to add the UITableViewController to the UIViewController as a subview.
UITableViewController* tableViewController = [[UITableViewController alloc] init];
[self.view addSubview:tableViewController.tableView];
All the other answers above works great. I figure I'd add to this for those that have a heavily invested implementation of a UITableViewController and feel like refactoring would be a pain.
My problem is how to reload the tableview
I have 2 viewcontrollers.
In first Viewcontroller I have one tableview. if I select any row in tableview it goes to second viewcontroller.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath;
{
NextPageController *nextView = [[NextPageController alloc] initWithNibName:#"NextPageView" bundle:nil];
[self.navigationController presentModalViewController:nextView animated:YES];
[nextView release];
}
in second view controller I have one textfield. If I enter any value into the textfield I need to disaplay that value into the first viewcontroller tableview.
can any one help me?
Thanks in advance.
give NextPageController a protocol and a delegate,just like this:
#protocol (NextPageControllerDelegate)
-(void)displayString:(NSString *)inputString;
#end
#interface FirstTableViewController : UITableViewController {
id<NextPageControllerDelegate> stringDelegate;
}
#property (nonatomic, assign) id<NextPageControllerDelegate> stringDelegate;
and in the .m file:
#implementation
#synthesize stringDelegate;
then, when you alloc the NextPageViewController, insert this:
(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath;
{
NextPageController *nextView = [[NextPageController alloc] initWithNibName:#"NextPageView" bundle:nil];
nextView.stringDelegate = self;
[self.navigationController presentModalViewController:nextView animated:YES];
[nextView release];
}
of course, your table view controller must conforms to the NextPageControllerDelegate protocol, and give the implementation of
-(void)displayString:(NSString *)inputString;
after that, when you are in nextView, and want to have the table view display that string, you may do this:
if(nil != self.stringDelegate)
[self.stringDelegate displayString:someString];
ant then it's done
Make Global String ,
Assign it in secondViewController and when you pop from secondViewController to FirstViewController , viewWillAppear will call.
make logic such it uses global variable and then reload table ..
you need to have a global NSString variable in appDelegate that stores your text of text filed in second view.
Now, when you come back to previous page, in
- (void) viewWillAppear
{
[yourDataSourceArray addObject:appDelegate.yourGlobalString];
[yourTableView reloadData];
}
and yes make sure that your yourDataSourceArray is NSMutableArray.
Hope it helps you.
You could create a property for an NSString in your first view, and a property for an instance of the first view controller (UITableViewController?) in your second view. Then upon saving or popping or whatever you're doing in the second view controller once you have entered the text you want, you could set the property of the NSString, pop the view, and reload the tableView in viewWillAppear. Alternatively you could use delegation as Lewen described.
create global NSMutableArray.
Store and add all data in that NSMutableArray.
In -(void) viewwillappear of first class, call [tablename reloadData];
I'm working on an app for my client. I'm stuck now.
I don't know how to explain. But i make a photoshop image of it.
http://i.stack.imgur.com/cV4mL.jpg
user tap on parent tablecell.
execute didSelectRowAtIndexPath:(NSIndexPath *)indexPath. User select cell.
parent cell update.
Anyone know what is this called?
Do you have tutorial for it?
// FirstViewController (1st in your Photoshop-design)
...
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
SecondViewController *secondViewController = [[SecondViewController alloc] init];
secondViewController.cell = [tableView cellForRowAtIndexPath:indexPath];
[self.navigationController pushViewController:secondViewController animated:YES];
}
...
-------------------------
// SecondViewController.h
#interface SecondViewController : UITableViewController {
UITableViewCell *cell;
}
#property (nonatomic, retain) UITableViewCell *cell;
-------------------------
// SecondViewController.m
...
#synthesize cell;
...
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
self.cell.detailTextLabel.text = #"Something";
[self.navigationController popViewControllerAnimated:YES];
}
...
Use UINavigationController with UITableViewController as its root controller and when diving deeper, instantiate a different UITableViewController for that and push it on the navigation stack. Popping is similar.
There are good examples for UINavigationController accessible from Apple's docs.
I have a UIViewController (AbcViewController) with NavigationController. AbcViewController uses UIView (AbcView) as its view. AbcView has a UITableView. I have set this TableView's datasource in AbcViewController and delegate in its SuperView i.e. AbcView. How will I push another UIViewController (XyzViewcontroller) into navigationController when I select a row in this table because it gives
"error: request for member 'navigationController' in something not a structure or union"
when I do this:
[self.navigationController pushViewController:xyzViewcontroller animated:TRUE];
I also did this:
AbcViewController *parentVC;
[parentVC.navigationController pushViewController:xyzViewcontroller animated:TRUE];
Though it builds successfully, XyzViewcontroller's view does not appear. It does not push XyzViewcontroller's view onto navigationController.
We can make a delegate on AbcView so that we can refer back to the view's viewController which in this case is AbcViewController. We can set delegate as:
#interface AbcView : UIView
{
id delegate;
}
#property(nonatomic, assign) id delegate;
Then in AbcViewController, set the view's delegate like this:
[abcView setDelegate:self];
Now in table method using our delegate from within AbcView as:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[delegate pushOtherView];
}
it will call - (void)pushOtherView method in AbcViewController whose definition is:
- (void)pushOtherView
{
XyzViewcontroller * xyzViewcontroller = [[[XyzViewcontroller alloc] init] autorelease];
[self.navigationController pushViewController:xyzViewcontroller animated:YES];
}
But before using this method, it should be mentioned in protocols otherwise it will show
Warniing:
-pushOtherView' not found in protocol(s).