I use button in ViewController to go TableViewController. In TableViewController I create int NInt1. But when I go to TableViewController condition doesn't work.
ViewController.m
- (IBAction)Button:(id)sender {
MasterViewController *trns =[[MasterViewController alloc]init];
[_Button.titleLabel.text isEqualToString:#"1"];
trns.NInt1=1;
}
TableViewController.m
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if(_NInt1 == 1){
return 5;
}else{
return 20;
}
}
If you are using the story pass the value like this:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
RecipeDetailViewController *destViewController = segue.destinationViewController;
destViewController.NInt1 = 1;
}
Now see the value of NInt in viewDidLoad of your destination view controller.
I think you need to modify like
- (IBAction)Button:(UIButton *)sender {
MasterViewController *trns =[[MasterViewController alloc]init];
if [sender.titleLabel.text isEqualToString:#"1"]{
trns.NInt1=1;
}
}
on that tableviewController viewDidload check like use NSLog for the object is 1 or not
If you use storyboard, then the destination view controller is not created from your IBAction. It can be verified easily : you never push or present the newly created view controller, which is local in your method.
Instead use prepareForSeguemethod as described in Jaimish answer.
I tried the solution.Finally I got.Thank you.The condition has worked now.
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if([segue.identifier isEqualToString:#"goTableViewController"])
{
TableViewController *tableVC = (TableViewController *) segue.destinationViewController;
tableVC.NInt1 = 5;
}
}
Related
I am trying to send an NSMutableArray of the chosen cell to another view when a cell is clicked. I have the array of the chosen cell, but I can't get it to pass over.
"SearchResultsModalTableViewController.m"
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSMutableArray *aVenue = [self.venues objectAtIndex:indexPath.row];
DetailSearchResultViewController *detailVC =[[DetailSearchResultViewController alloc]init];
detailVC.venueInfo = aVenue;
NSLog(#"%#",aVenue);
}
When you use storyboards, you usually add segues from table cells to a destination storyboard. If that is what you are doing, then the way to deal with the selection is in the prepareForSegue: method of your view controller.
Here is an example. I am assuming that DetailSearchResultViewController in your code is a UINavigationController:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
DetailSearchResultViewController* destinationViewController = (DetailSearchResultViewController*)segue.destinationViewController;
NSIndexPath *p = self.tableView.indexPathForSelectedRow;
NSUInteger idx = p.row;
NSMutableArray *aVenue = [self.venues objectAtIndex:indexPath.row];DetailSearchResultViewController *detailVC =[[DetailSearchResultViewController alloc]init];
destinationViewController.venueInfo = aVenue;
[super prepareForSegue:segue sender:sender];
}
Hello i am trying to pass variable with segue.
I am getting variable to pass with tableView:willSelectedRowAtIndexPath: is this correct way? If it is not, how should i achieve this? (Note: It is working like this.)
- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {
selectedCoffeeShop = [coffeeShops objectAtIndex:indexPath.row];
return indexPath;
}
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"coffeeShopDetailSegue"]) {
CoffeeShopDetailViewController *controller = (CoffeeShopDetailViewController *)segue.destinationViewController;
[segue destinationViewController];
controller.coffeeShop = selectedCoffeeShop;
}
}
If your segue is made from the cell itself, then there is no need to implement either willSelectRowAtIndexPath or didSelectRowAtIndexPath. You only need prepareForSegue:sender: since the sender argument will be the cell, and you can use that to get the indexPath you need,
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(UITableViewCell *)sender {
if ([segue.identifier isEqualToString:#"coffeeShopDetailSegue"]) {
NSInteger row = [self.tableView indexPathForCell:sender].row;
CoffeeShopDetailViewController *controller = segue.destinationViewController;
controller.coffeeShop = coffeeShops[row];
}
}
That way to do it is absolutely fine.
Another way would be to remove the automatic segue trigger from storyboards and instead implement:
tableView:didSelectRowAtIndexPath: to call performSegueWithIdentifier:sender:.
It could look like this:
- (NSIndexPath *)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
selectedCoffeeShop = [coffeeShops objectAtIndex:indexPath.row];
[self performSegueWithIdentifier:#"coffeeShopDetailSegue" sender:self];
return indexPath;
}
In that case you still need your implementation of prepareForSegue:sender:.
You could also do it completely without segues, using UINavigationController, but then you'd have to instantiate the CoffeeShopDetailViewController programmatically as well.
Your approach is perfectly fine though!
As noted in the comments, you can remove [segue destinationViewController];, since this returns the destination view controller which you already saved in the variable controller in the line right above. :)
I am trying to set the property of a View Controller I'm segueing to to a custom object (Restroom), but it's coming out as a UITableViewCell.
Here is code from the origin View Controller that is triggering the segue. The userDidSelectRestroomNotification method is called when a user selects a cell in a table view that lists restrooms - the application is then supposed to segue to a View Controller that lists the details of that restroom:
- (void)userDidSelectRestroomNotification:(NSNotification *)notification
{
Restroom *selectedRestroom = (Restroom *)[notification object];
[self performSegueWithIdentifier:#"ShowRestroomDetails" sender:selectedRestroom];
};
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"ShowRestroomDetails"])
{
RestroomDetailsViewController *restroomDetailsViewController =
(RestroomDetailsViewController*)segue.destinationViewController;
restroomDetailsViewController.restroom = sender;
}
}
Here is the code in my data source where the notification is posed:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// post a notification when a selection is made
NSNotification *notification = [NSNotification
notificationWithName:RRTableViewDidSelectRestroomNotification
object:[self restroomForIndexPath:indexPath]];
[[NSNotificationCenter defaultCenter] postNotification:notification];
}
- (Restroom *)restroomForIndexPath:(NSIndexPath *)indexPath
{
return [self.restroomsList objectAtIndex:[indexPath row]];
}
Point being, I am sending along a Restroom object in my notification.
The issues comes when in the RestroomDetailsViewController, I am trying to set the text of a label to the name of the Restroom object I'm passing along:
#interface RestroomDetailsViewController ()
#property (weak, nonatomic) IBOutlet UILabel *nameLabel;
#end
#implementation RestroomDetailsViewController
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
self.nameLabel.text = self.restroom.name;
}
#end
It crashes at self.nameLabel.text = self.restroom.name. When I inspect the objects, I see that my self.restroom object is actually a UITableViewCell. What confuses me further is that that UITableViewCell appears to be the cell that was selected by the user to trigger the segue -- i.e. the one set up in the data source:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSParameterAssert([indexPath section] == 0);
NSParameterAssert([indexPath row] < [_restroomsList count]);
UITableViewCell *restroomCell = [tableView
dequeueReusableCellWithIdentifier:restroomCellReuseIdentifier];
if(!restroomCell)
{
restroomCell = [[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:restroomCellReuseIdentifier];
}
restroomCell.textLabel.text = [[_restroomsList objectAtIndex:[indexPath row]] name];
return restroomCell;
}
I'm not understanding why this happens and how to get that restroom property properly assigned to the Restroom object.
Why are you using postnotification ?
I don't see any requirement here to use notification. A simple function with parameter will do the work.
Try Following way to call segue
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self performSegueWithIdentifier:#"ShowRestroomDetails" sender:[self restroomForIndexPath:indexPath]];
}
- (Restroom *)restroomForIndexPath:(NSIndexPath *)indexPath
{
return [self.restroomsList objectAtIndex:[indexPath row]];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
Restroom *selectedRestroom = (Restroom *)sender;
if ([segue.identifier isEqualToString:#"ShowRestroomDetails"])
{
RestroomDetailsViewController *restroomDetailsViewController =
(RestroomDetailsViewController*)segue.destinationViewController;
restroomDetailsViewController.restroom = selectedRestroom ;
}
}
I understand it's not typical to have notifications being posted when cells are pressed - but that's how I'm choosing to implement this application currently.
That being said, here's how I ended up getting this to work (thanks to a comment by #rdelmar saying to check what order the methods are being called in):
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"ShowRestroomDetails"])
{
if([sender isKindOfClass:[Restroom class]])
{
RestroomDetailsViewController *restroomDetailsViewController = (RestroomDetailsViewController*)segue.destinationViewController;
restroomDetailsViewController.restroom = sender;
}
}
}
I found that the prepareForSegue method was being triggered when a cell was pressed before my userDidSelectRestroomNotification method. However, I want userDidSelectRestroomNotification to actually be the method that triggers prepareForSegue because it creates the needed Restroom object. Thus I put a check in my prepareForSegue that makes sure the incoming object is a Restroom instance.
All that being said - I don't know if this is more of a hack than a solution.
I have a problem where same view is pushed many times on selection of a row and if user keeps on clicking on the same row it crashes.
MasterDetailVC.m
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
LAClaimReport *record = [_claimReports objectAtIndex:indexPath.row];
if ([record.submitted isEqualToNumber:#1])
{ // if i click on clicking here VC is getting pushed and pushed.
[self.detailViewController showReadonlyViewForClaimReport:record];
}
else
{
[self.detailViewController showEditViewForClaimReport:record];
}
}
LADetailViewController.m
#interface LADetailViewController()
{
LAClaimReport *_claimRecord;
}
-(void) showEditViewForClaimReport:(LAClaimReport *) claimReport
{
_claimRecord = claimReport;
[self performSegueWithIdentifier:#"toEditView" sender:self];
// calls LAClaimReportViewController
}
-(void) showReadonlyViewForClaimReport:(LAClaimReport *) claimReport
{
_claimRecord = claimReport;
[self performSegueWithIdentifier:#"toReadonlyView" sender:self];
// calls LACreateReportViewController.
}
-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"toEditView"])
{
LAClaimReportViewController *viewController = segue.destinationViewController;
viewController.claimReport = _claimRecord;
}
else if ([[segue identifier] isEqualToString:#"toReadonlyView"])
{
LACreateReportViewController *viewController = segue.destinationViewController;
viewController.claimReport = _claimRecord;
}
}
LAClaimReportViewController & LACreateReportViewController are two diff. VC having segues from LADetailViewController. I want that the VC (LACreateReportViewController or LAClaimReportViewController) should not be pushed many times on multiple click of the same row of the masterDetailVC. pls help.
You can just check if the View is already pushed. If it is then don't push it again. If its not pushed then push it.
For this you can make a instance variable may be a bool. Lets call it isPushed. Make isPushed = true; when you push the view. When you pop it then make isPushed = false;.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
LAClaimReport *record = [_claimReports objectAtIndex:indexPath.row];
if ([record.submitted isEqualToNumber:#1] && !isPushed)
{ // if i click on clicking here VC is getting pushed and pushed.
isPushed = true;
[self.detailViewController showReadonlyViewForClaimReport:record];
}
else
{
[self.detailViewController showEditViewForClaimReport:record];
}
}
The above is just an way. One thing is this: [record.submitted isEqualToNumber:#1] always false? If it is then you would like to check that I think.
Hope this will Help.
I'm having an issue with my performSegueWithIdentifier, because he fires and when I get a breakpoint on the viewDidLoad of the NextViewController he enters and executes fine. Problem is there is no output and the screen continues to show the CurrentViewController. What can be the error ?
(CurrentViewController is a TableViewController)
-(NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
_selected = [self.evlist objectAtIndex:indexPath.row];
[self performSegueWithIdentifier:#"eventlist" sender:self];
return indexPath;
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
NSString * event_id = [_selected objectForKey:#"id"];
NSString * event_name = [_selected objectForKey:#"label"];
[segue.destinationViewController setEvent_id:event_id];
[segue.destinationViewController setEvent_id:event_id];
[segue.destinationViewController setEvent_name:event_name];
}
(NextViewController is a ViewController)
- (void)viewDidLoad
{
[super viewDidLoad];
_evname_label.text = _event_name;
_evid_label.text = _event_id;
NSLog(#"This is strange %#",_event_name);
}
He logs everything as expected... the view doesn't show!
Your code appears correct. Are you sure the segue is configured correctly? Check the Style, Presentation and Transition styles.
Sorry but I had a bug in my coding... I was calling the prepareforsegue inside a for cycle and the problem was somewhere around it.
Prepareforsegue outside for and it was cool :) Thanks all