Sending a variable to another viewcontroller - iphone

I have two viewcontrollers. One contains a tableview. In the didselectrowforindexpath method i wanna send an object to another viewcontroller but the object is null when it is passed to the destination view controller.
The object that im sending is service_ID that belongs to the TableServiceNews class. The destination viewcontroller inherits TableServiceNews.
Here is the code for didselectrow :-
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
TableServiceNews *serviceTable = [[TableServiceNews alloc]init];
serviceTable.service_ID = [ServiceID objectAtIndex:indexPath.row];
serviceTable = [self.storyboard instantiateViewControllerWithIdentifier:#"navigationServiceNews"];
[self.slidingViewController anchorTopViewOffScreenTo:ECRight
animations:nil onComplete:^{
CGRect frame = self.slidingViewController.topViewController.view.frame;
self.slidingViewController.topViewController = serviceTable;
self.slidingViewController.topViewController.view.frame = frame;
[self.slidingViewController resetTopView];
}];
}
The slidingviewcontroller method is using a class that i got from github, https://github.com/edgecase/ECSlidingViewController is the link.

Be sure that service_ID is defined in the implementation (#synthesize) , if it didn't work, make sure to assign the value to it after you push the new viewcontroller to load it first.
I hope that was helpful

Replace :
TableServiceNews *serviceTable = [[TableServiceNews alloc]init];
serviceTable.service_ID = [ServiceID objectAtIndex:indexPath.row];
serviceTable = [self.storyboard instantiateViewControllerWithIdentifier:#"navigationServiceNews"];
with :
UIViewController *serviceTable = [self.storyboard instantiateViewControllerWithIdentifier:#"navigationServiceNews"];
((TableServiceNews*)serviceTable).service_ID = [ServiceID objectAtIndex:indexPath.row];
The problem might be assigning service_ID value before instantiating your serviceTable from storyboard.
By the way, instantiatViewControllerWithIdentifier return a UIViewController. So you need to cast it to use it like the subclass you've created.

Related

how to call didSelectRowAtIndexPath from another class

I am in situation where i need to call didSelectRowAtIndexPath from another calls for that i do like this
i make object of that class and call viewdidload so my table view get initialised
- (void)_hideTapped:(id)sender
{
LeftController *left = [[LeftController alloc]init];
[left viewDidLoad ];
}
in LeftController
- (void)viewDidLoad {
[super viewDidLoad];
mainArray = [[NSMutableArray alloc]initWithObjects:#"Go To Camera",#"Big Contacts List",#"Where Am I? On map",#"Watch And Alarm",#"Calculator With Big Letters",#"Big KeyBoard For Email",#"Calendar With Events",#"Settings", nil ];
// NSLog(#"mainArray%#",mainArray);
if (!_tableView) {
UITableView *tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
tableView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
tableView.delegate = (id<UITableViewDelegate>)self;
tableView.dataSource = (id<UITableViewDataSource>)self;
[self.view addSubview:tableView];
self.tableView = tableView;
[self iDecideWhichCell];
}
}
-(void)iDecideWhichCell
{
NSIndexPath *path = [NSIndexPath indexPathForRow:0 inSection:0];
[self tableView:self.tableView didSelectRowAtIndexPath:path];
}
this is part of my didSelectRowAtIndexPath
i am using JASidePanels for splitview like facebook and this is how they push viewcontroller it works fine if i go to leftcontroller and click by my self but when i do this whole process programmatically then its not working
if (indexPath.row ==0)
{
NSLog(#"%#",tableView);
self.sidePanelController.centerPanel = [[UINavigationController alloc] initWithRootViewController:[[NewViewController alloc] init]];
}
please any one can tell me how can i achieve this
i checked this answer calling didSelectRowAtIndexPath from other ViewController not responding iPad
but i dont understand how to implement this in my code
tableView:didSelectRowAtIndexPath: is a delegate method. You shouldn't call it directly. It is called for you when a table view row is selected.
You should create a delegate for the LeftController, so the LeftController can remain as the delegate of its own tableView.
Implement in LeftController.h:
#class LeftController;
#protocol LeftControllerDelegate
-(void)leftController:(LeftController *)leftController didSelectTableView:(UITableView *)tableView rowAtIndexPath:(NSIndexPath *)indexPath;
#end
#interface LeftController : UIViewController
#property(nonatomic, weak) id<LeftControllerDelegate> delegate;
// ... other public properties
-(id)initWithDelegate:(id<LeftControllerDelegate>)delegate;
// ... other public methods
#end
Implement in LeftController.m:
-(id)initWithDelegate:(id<LeftControllerDelegate>)delegate
{
self = [super init];
if (self) {
self.delegate = delegate;
}
return self;
}
-(void)viewDidLoad
{
[super viewDidLoad];
//create the tableView...
//set the tableView delegate
tableView.delegate = self;
//do other view setup...
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self.delegate leftController:self didSelectTableView:tableView rowAtIndexPath:indexPath];
}
In your other view controller implementation, e.g. MyOtherController.m:
//create instance of LeftController that has self as delegate
LeftController *left = [[LeftController alloc] initWithDelegate:self];
and implement the delegate method:
-(void)leftController:(LeftController *)leftController didSelectTableView:(UITableView *)tableView rowAtIndexPath:(NSIndexPath *)indexPath
{
//Yay! This instance of MyOtherController has received the delegate message from LeftController, including details of table view and row selected.
}
Effectively here, you have a delegated the tableView messages to the LeftController, and in turn you've delegated the LeftController functionality to its delegate. You set its delegate in the init method when you created and initialised it.
Hope it makes sense, let me know!
You can make your own method in which class you want to handle didSelectRowAtIndexPath and call that method from didSelectRowAtIndexPath of same class. Also Set delegate to handle events.

CellForRowAtIndexPath is not invoked

I'm writing an app hat has many views and I used sliding views library (ECSlidingViews). The problem is when I fill an array with objects and fill the table with the objects in tableView:cellForRowIndexPath: method, it does present the data in the table, but when I go to other view and come back the data disappears because tableView:cellForRowIndexPath: is not called. Here is the code:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"begin of cellForRowAtIndexPath");
SchedualeCell *cell = (SchedualeCell *)[tableView dequeueReusableCellWithIdentifier:#"Cell"];
Course *temp = [array objectAtIndex:indexPath.row];
cell.nameLb.text = temp.name;
cell.hourLb.text = [NSString stringWithFormat:#"%d",temp.hour];
cell.startTimeLb.text = temp.startTime;
cell.endTimeLb.text = temp.endTime;
NSLog(#"End of cellForRowAtIndexPath");
return cell;
}
tableView:numberOfRowsInSection: and numberOfSectionsInTableView: is invoked when I come back to the view that has the table view.
P.S.: The view is UIViewController that has table view inside of it, and I searched all StackOverflow before posting my problem.
EDIT : this is where I set the delegate and datasource
- (void)viewDidLoad
{
[super viewDidLoad];
NSLog(#"Did Appear");
// Do any additional setup after loading the view.
self.view.layer.shadowOpacity = 0.75f;
self.view.layer.shadowRadius = 10.0f;
self.view.layer.shadowColor= [UIColor blackColor].CGColor;
if (![self.slidingViewController.underLeftViewController isKindOfClass:[MenuViewController class]])
{
self.slidingViewController.underLeftViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"Menu"];
}
[self.view addGestureRecognizer:self.slidingViewController.panGesture];
if (array == nil)
{
array = [[NSMutableArray alloc]init];
}
table.delegate = self;
table.dataSource = self;
[table reloadData];
}
and I did included The delegate and datasource in the header
#interface MainViewController : UIViewController<UITableViewDataSource , UITableViewDelegate,addDelegate>
First of all , it's not numberOfRowsAtSection and numberOfTableView. It's numberOfSectionsInTableView and numberOfRowsInSection.
Things you can do :
1) NSLog your numberOfRowsInSection. Note that , If it's "0" then your cellForRowAtIndexPath is never going to be called.
2) If you are using your UITableView inside some UIView then you should add :
[self.view addSubview:table];
3) Don't Forget to include :
#interface yourViewController : UIViewController<UITableViewDataSource,UITableViewDelegate>
Once check that you reframed the tableview in ViewWillAppear.
Some times if we set out of frame, CellForRowAtIndexPath will not call.

How to pass data to detail view after being selected in a table view?

I have a UITableViewController that has data populated from an NSMutableArray called userList. When specific user is selected, it goes to a detail view, and updates the title in the NavBar, but it wont pass the data to update a UILabel in the UIView.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:NO];
//Attempt at a singleton to pass the data
DetailView *details = [[DetailView alloc] init];
details.userNameLbl = [userList objectAtIndex:indexPath.row];
DetailView *detailVC = [[DetailView alloc] initWithNibName:nil bundle:nil];
//This line doesn't pass the data
detailVC.userNameLbl.text = [userList objectAtIndex:indexPath.row];
//This line does update the title in the NavBar
detailVC.navigationItem.title = [userList objectAtIndex:indexPath.row];
[self.navigationController pushViewController:detailVC animated:YES];
[details release];
[detailVC release];
}
Should I be trying to push the data from the table view to the detail view, or have the detail view try to pull the data from the table view?
DetailView.h has the following line that is in fact hooked up in IB.
IBOutlet UILabel *userNameLbl
The userNamelbl isn't instantiated until the view is loaded from the nib file. This doesn't happen immediately at initialisation, but will have happened by the time viewDidLoad is called.
So, you should to declare a property in DetailView to store your title, and then assign that value to userNamelbl.text in the viewDidLoad method.
For example, in your table viewController:
DetailView *detailVC = [[DetailView alloc] initWithNibName:nil bundle:nil];
detailVC.userName = [userList objectAtIndex: indexPath.row];
and in your detail viewController:
- (void) viewDidLoad
{
[super viewDidLoad];
self.userNameLbl.text = self.userName;
}
The viewController's navigationItem property is created when the viewController is initialised, hence you can assign to the navigationItem.title immediately.
Swift code
let detailVC = DetailView(nibName: nil, bundle: nil)
detailVC.userName = userList.objectAtIndex(indexPath.row) as? NSString
and
class DetailView: UIViewController {
#IBOutlet var userNameLbl: UILabel
var userName:NSString?
override func viewDidLoad() {
super.viewDidLoad()
self.userNameLbl.text = self.userName
}
}
Are you mixing UIViews and UIViewControllers? You should have a DetailViewController class that inherits from UIViewController or some sublcass (like UITableViewController); it will have DetailViewController.m and DetailViewController.h files to declare and define your class. It should have a corresponding nib that defines the UIView that the UIViewController loads; it will have a DetailView.xib file.
You can't assign the value to the UILabel directly because UIView hasn't been loaded at the time you need to assign the user name value.
In order to do what you want, you should declare a public property (userName) to "push" the value onto the detail view controller from the master controller. Once the detail view is loaded, it can assign the value from the property to the label and nav bar.
In your master view controller (UITableViewController):
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:NO];
DetailViewController *detailVC = [[DetailView alloc] initWithNibName:#"DetailView" bundle:nil];
detailVC.userName = [userList objectAtIndex:indexPath.row];
[self.navigationController pushViewController:detailVC animated:YES];
[detailVC release];
}
In your detail view controller:
DetailViewController.h
#property (retain) NSString* userName;
#property (nonatomic, retain) IBOutlet UILabel *userNameLbl;
DetailViewController.m
#synthesize userName;
#synthesize userNameLbl;
-(void) viewDidLoad {
[super viewDidLoad];
self.userNameLbl.text = self.userName;
self.navigationItem.title = self.userName;
}
Presumably your DetailView requires the data from your selected row to function?
If so, I'd say the 'correct' approach would be to create a custom init method that passed in the data you required. For example:
[[DetailView alloc] initWithTitle:(NSString *)title text:(NSString *)text]
There's nothing inherently wrong with your approach, but passing the data the view controller requires at its creation is architecturally better (in my opinion, I'm sure someone will disagree!). For example, think of a table view controller - you pass in the table view style in the init method, you don't set it later on. Same for a UIImageView - you have an initWithImage method that lets you set the image at creation.

Set Nav Bar's Title From Array

I have a rootTableView with cells that are loaded from an array:
logArray = [[NSArray alloc]initWithObjects:#"John", #"Jack", #"Jill", nil];
When I click a cell, for example the cell called "Jack", it will take me to a sub table for "Jack"
How to I set the title of that sub tableView to "Jack", etc.
Under the tableView delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
NextViewController *nextView = [[NextViewController alloc] initWithNibName:#"NextViewController" bundle:nil];
**nextView.title = [logArray objectAtIndex: indexPath.row];**
//push the nextView here
}
I think you can try using the UITableView section header for this
You need to create a property in your sub tableview that you can pass the name along to. Something like this should be in your didSelectRowAtIndexPath method.
UITableViewCell *currentCell = [self.tableView cellForRowAtIndexPath:indexPath];
MySubtableviewController *mstvc = [[MySubTsbleViewController alloc] init];
mstvc.nameProperty = currentCell.textLabel.text;
[self.navigstiomController pushViewController:mstvc];
Something like that where the nameProperty is declared in your sub tableView controller.
Then in your sub view controller, just set the title in viewDidLoad.
self.title = self.nameProperty;
Hope this helps.

Call UIViewController from "subview"

I have a UIViewController which when it loads it loads up this..
MapViewController *mapController = [[MapViewController alloc] initWithNibName:#"MapView" bundle:nil];
self.mapViewController = mapController;
[self.view insertSubview:mapController.view atIndex:0];
[mapController release];
I also have a switch views button that can change to a table view....
if (self.tableViewController ==nil)
{
TableViewController *tableController = [[TableViewController alloc] initWithNibName:#"TableView" bundle:nil];
self.tableViewController = tableController;
[tableController release];
//[self.view insertSubview:detailController atIndex:0];
}
if (self.mapViewController.view.superview == nil)
{
[tableViewController.view removeFromSuperview];
[self.view insertSubview:mapViewController.view atIndex:0];
}
else
{
[mapViewController.view removeFromSuperview];
[self.view insertSubview:tableViewController.view atIndex:0];
}
I am trying to change the view to a detail view based on selecting a row in the table view and I cannot work out how to call it at all. All methods I have seem to fail! Please help!
Add the UITableViewDelegate protocol to your controller class.
#interface myTableViewController : UITableViewController <UITableViewDelegate>
When you create your table veiw controller set its delegate to be your controller using:
myTableViewController.delegate = self; // Assuming your setup code runs within the table view controller
In your tableViewController, implement didSelectRowAtIndexPath:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
int rowSelected = [indexPath indexAtPosition:0]; // Assuming your UITableView has a single section.
The class you should look at for handling row selection is UITableViewDelegate, which has the method:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath