Segue after login with facebook ios 6 - facebook

I'm using Facebook SDK 3.1, my login system is ok, after login in I want to go to other ViewController. I connected both with a segue and the identifier, but now I don't know how I can implement it.
Here, after this:
if (appDelegate.session.isOpen) {
[self.buttonLoginLogout setTitle:#"Log out" forState:UIControlStateNormal];
[self.textNoteOrLink setText:[NSString stringWithFormat:#"https://graph.facebook.com/me/friends?access_token=%#", appDelegate.session.accessTokenData.accessToken]];
}
On my TableViewCell example I'm using it like this:
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"test"]) {
NSIndexPath *selectedIndexPath = self.tableView.indexPathForSelectedRow;
RestauranteDetalhesViewController *destViewController = segue.destinationViewController;
destViewController.idRest =[bd.idrestauracao objectAtIndex:selectedIndexPath.row];
}
But here I don't have a indexpath to give to the (id)sender.

Hey Fabio Cardoso there are two types of Segues
Trigger less segue and
Triggered segue
In trigger less segue you just directly drag from one ViewController to another. You dont mention on which action you want the Segue to be done. To do this you need to create segue identifier like you did above. And call the below line in your code.
[self performSegueWithIdentifier:#"YOUR_IDENTIFIER" sender:self];
In second way of segue you directly Ctrl+drag from a button to another ViewController. So no need of writing any code for this. When ever you click on that button it will either do Push, Model or custom segue what ever you selected in storyboard.
When a segue if performed below method is called in the Source ViewController. Here you can write you own code to either pass value from first ViewController to another or any other stuff.
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
If there are more than one segue from your ViewController than the identifier will be of use. You can use the identifier like this
if ([segue.identifier isEqualToString:#"YOUR_IDENTIFIER"])
Note: Segue is only one way, so if you create segue from first ViewController to another and if you want to come back (In case of model action) you have to write the delegate method for second ViewController and on clicking the button action call
**FirstViewController.h**
#interface FirstViewController : UIViewController <SecondViewControllerDelegate>
{
}
- (IBAction) buttonTapped:(id)sender;
**FirstViewController.m**
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"YOUR_IDENTIFIER"])
{
SecondViewController *svc_obj = segue.destinationViewController;
svc_obj.delegate = self;
}
}
- (void) buttonTapped:(id)sender
{
[self performSegueWithIdentifier:#"YOUR_IDENTIFIER" sender:self];
}
- (void) secondViewControllerDidCancel: (SecondViewController *) controller
{
[controller dismissViewControllerAnimated:YES completion:nil];
}
**SecondViewController.h**
#class SecondViewController;
#protocol SecondViewControllerDelegate <NSObject>
- (void) secondViewControllerDidCancel: (SecondViewController *) controller;
#end
#interface SecondViewController : UIViewController
{
}
#property (nonatomic, weak) id <SecondViewControllerDelegate> delegate;
- (IBAction)cancelButtonTapped:(id)sender;
**SecondViewController.m**
- (IBAction)cancelButtonTapped:(id)sender
{
[self.delegate secondViewControllerDidCancel:self];
}
#end

I resolved my problem with this simple line:
[self performSegueWithIdentifier:#"begin" sender:self];

Related

segues in storyboard work perfectly but the prepare for segue is not being called

So I have a standard method that everyone uses in the prepare for segue.
When I think logically "prepare" means do this before the segue is called.
But I have set up 3 table cells that all have 1 segue to the SecondViewController.
When I test that it works perfectly no errors.
Now when I want to add to this app that when the user selects the first cell the label "labeltje" get another text value this does not happen.
Of course this code is in my TableViewController.m file and not in the DagenViewController, which is my second controller.
What am I not seeing?
Dagenviewcontroller is imported etc. no issues there.
This is the prepareforsegue bit of code:
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
DagenViewController *secondVC = (DagenViewController *)segue.destinationViewController;
if([segue.identifier isEqualToString:#"vrijdagSegue"])
{
NSString *vrijdag = #"vrijdag";
secondVC.labeltje.text = vrijdag;
}
else if([segue.identifier isEqualToString:#"zaterdagSegue"])
{
NSString *zaterdag = #"zaterdag";
secondVC.labeltje.text = zaterdag;
}
else {
NSString *zondag = #"zondag";
secondVC.labeltje.text = zondag;
}
}
Or is there a way to put something in the ViewDidLoad method of my SecondViewController that checks which segue was used?
Thank you for reading.
Try to do this way:
DagenViewController.h file
#property (strong, strong) NSString *preText
DagenViewController.m file
- (void) viewDidLoad
{
self.labeltje.text = preText;
}
In Your Method
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
DagenViewController *secondVC = (DagenViewController *)segue.destinationViewController;
if([segue.identifier isEqualToString:#"vrijdagSegue"])
{
secondVC.preText = #"vrijdag";
}
else if([segue.identifier isEqualToString:#"zaterdagSegue"])
{
secondVC.preText = #"zaterdag";
}
else {
secondVC.preText = #"zondag";
}
}
When prepareForSegue:sender: is called you are accessing a label that is nil since the view controller's view was not yet loaded. Create a string property(that you will set in prepareForSegue:sender:) and then in your DagenViewController viewDidLoad method set the label's text from that string property.

Xcode/Obj-c - Segue pushes new instance

I have seen similar questions a lot on Stackoverflow and I tried a lot of things but I can't seem to figure this out. I have multiple TableViewControllers and 1 MainViewController. The MainViewController has buttons calling the different TableViewControllers and on selecting a tablecell the tableViewController dismisses.
The problem is that im pushing a new instance of my MainViewController every time I push from either one of my tableViewControllers. I currently use Segues to push between these different controllers.
In short: When switching from TableViewControllers to ViewController I want to prevent the ViewController to get pushed as a new instance because this way its removing my previous data input.
Im pretty sure I have to use either:
[self dismissModalViewController: withCompletion:]
performSegue
prepareForSegue
Or set some global variables in a class and call those, but im not experienced enough yet to implement this correctly.
A simple example of end result would be: 3 textfields in VC. On clicking textfield1 it opens tableview1 and on clicking a cell it updates textfield1. Textfield2 opens tableview2, etc.
Hope im clear enough, could post sample code if needed.
Edit, posting code (keep in mind, segues are performed in storyboard):
TableViewExample.h:
#interface IndustryViewController : UIViewController <UITableViewDelegate, UITableViewDataSource> {
NSArray *tableViewArray;}
#property (nonatomic, strong) IBOutlet UITableView *tableViewIndustry;
TableViewExample.m:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"showIndustry"]) {
NSIndexPath *indexPath = [self.tableViewIndustry indexPathForSelectedRow];
ViewController *destViewController = segue.destinationViewController;
destViewController.industryText = [tableViewArray objectAtIndex:indexPath.row];
destViewController.industryTextName = [tableViewArray objectAtIndex:indexPath.row];
}}
Then in ViewController.m, viewDidLoad:
[industry setTitle:industryText forState:UIControlStateNormal];
These are the most important parts I think.
Is the segue of type "Push"? If so you should try dismissing the table view controllers using:
[self.navigationController popViewControllerAnimated:YES];
If the segue is of type "Modal" instead you should do something like this on your table view controller:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// your logic here
[self dismissModalViewControllerAnimated:YES];
}
As for the data exchange between controllers what I would personally do is creating a public property in the header file of the Table View Controller, like the following:
#property (nonatomic, weak) <Your_UIViewController_Subclass_Here> *mainController
Than, in the main controller, override the prepareForSegue:sender: method to set the newly created property to point to the main controller, like this:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
<Your_Subclass_Of_UITableViewController_Here> *destinationController = segue.destinationController;
destinationController.mainController = self;
}
Now the Table View Controller will have a pointer to the main controller to send the data basically all you have to do is to implement some public method or property in the Main Controller to be called when the user selects a table view row in the table view controller in order to update the text in the textfields or whatever data model you are using.

custom delegate being null iOS

I know this should be a simple thing to fix, but I can't see what's going wrong. May be extra pair will help. Here is what I am trying to do.
In my table view controller, there is an (+) button on the navigation controller to add new item.
I have a modal segue that takes it to the next view controller. User fills in a form and hit saves the table view controller reloads with the newly added record.
To do this, I implemented protocol with a delegate.
MyFormViewController.h
protocol MyCustomDelegate <NSObject>
#required
- (void)addNewRecord:(myFormViewController *)formViewController itemToAdd:(Item *)item;
#end
#property (nonatomic,weak) id<MyCustomDelegate> delegate;
MyFormViewController.m
#synthesize delegate;
- (IBAction)addItem:(id)sender {
Item *item = [[Item alloc]init];
item.name = itemName.text;
item.desc = itemDescription.text;
// I am having problem here, self.delegate is being null even though, it's being set in prepareForSegue.
if ([self.delegate respondsToSelector:#selector(addNewRecord:)]) {
[self.delegate addNewRecord:self itemToAdd:item];
}
else{
// delegate is getting set to null for some reason.
NSLog(#"Delegate method not getting called...%#",delegate);
}
}
in MyTableViewController.h
#interface MyTableViewController : UITableViewController
MyTableViewController.m
-(void)addItem:(myFormViewController *)formViewController itemToAdd:(Item *)item{
if(item)
{
MyClass *_itemClass = [[MyClass alloc]initWithPath:#"items/"];
[_itemClass addItemForUser:item];
}
[formViewController dismissViewControllerAnimated:YES completion:nil];
}
in my prepareForSegue method I am setting my tableviewcontroller as delegate.
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if ([segue.identifier isEqualToString:#"addItemSegue"]){
myFormViewController *_showaddTopic = [[myFormViewController alloc]init];
_showaddTopic.delegate = self;
}
After all this, my delegate in myFormViewController is being set to "null". I am not sure why it's not working. It's pretty basic stuff but giving me hard time.
Thank you
myFormViewController *_showaddTopic = [[myFormViewController alloc]init];
_showaddTopic.delegate = self;
There's your problem. You are creating a new MyFormViewController. But that's the wrong MyFormViewController; you want to use the one that is already the segue's destination controller. So you are setting the wrong object's delegate.
(PS Notice my use of a capital letter to start the name of a class? Always do that.)
maybe _showaddTopic.delegate = self; can not written here and shuold this object alloc after at once

UITableView prepareForSegue assigning indexPath to sender?

In the code below I am just trying out setting up a segue directly from the UIViewController to a DetailViewController. I usually do the segue from the UITableViewCell (which I think is clearer) but this time I just wanted to try going directly from the ViewController using -tableView:didSelectRowAtIndexPath:
My question is: I got to a situation where I needed to access the UITableViewCell indexPath from within -prepareForSegue:sender: my solution was to send the indexPath via sender. Usually I would set sender to self here, I have looked around and I can't find any reference to this, I am just curious if using sender to pass an indexPath is acceptable? I am pretty sure it is, and I am sure I have read that you can somewhere before, but I can't find any reference to it now.
// ------------------------------------------------------------------- **
// DELEGATE: UITableView
// ------------------------------------------------------------------- **
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#"%s", __PRETTY_FUNCTION__);
[self performSegueWithIdentifier:#"SEGUE_TWO" sender:indexPath];
}
// ------------------------------------------------------------------- **
// SEGUE: ViewController_ONE > DetailViewController
// ------------------------------------------------------------------- **
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
NSLog(#"%s", __PRETTY_FUNCTION__);
if([[segue identifier] isEqualToString:#"SEGUE_TWO"]) {
NSUInteger cellRow = [(NSIndexPath *)sender row];
DetailViewController *destinationController = [segue destinationViewController];
[destinationController setDataString:[[self dataList] objectAtIndex:cellRow]];
}
}
EDIT: What I was looking for in this case was
NSIndexPath *indexPath = [[self tableView] indexPathForSelectedRow];
essentially a way to get indexPath into -performForSegue:sender: without having to pass it via the sender parameter (in -performSegueWithIdentifier:sender:)
I typically avoid using the sender in prepareForSegue: because it could be anything. This makes asserting that your sender is what you are expecting more cumbersome and fragile. Also, I prefer to check for the class of the destinationViewController object rather than the segue name. Your functionality is tied to your object (or more specficially its interface), not the title of your segue, so checking your class makes it clear what you are trying to accomplish.
Below is the usual template I use in production when segueing from a UITableView. Note that you should always check if the destinationViewController is embedded in a nav controller and then check the class of the object as well to make sure you are handling it correctly. Finally, use an assert to ensure that somewhere down the line you haven't added some new segue that you forgot to handle.
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// unwrap the controller if it's embedded in the nav controller.
UIViewController *controller;
UIViewController *destVC = segue.destinationViewController;
if ([destVC isKindOfClass:[UINavigationController class]])
{
UINavigationController *navController = (UINavigationController *)destVC;
controller = [navController.viewControllers firstObject];
}
else
{
controller = destVC;
}
if ([controller isKindOfClass:[DetailViewController class]])
{
DetailViewController *vc = (DetailViewController *)controller;
NSIndexPath *ip = [self.tableView indexPathForSelectedRow];
[vc setDataString:[[self dataList] objectAtIndex:ip.row]];
}
else
{
NSAssert(NO, #"Unknown segue. All segues must be handled.");
}
}
You could use UITableView's method indexPathForCell. I hope you have a tableView instance variable.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if([sender isKindOfClass:[UITableViewCell class]]) {
NSIndexPath * indexPath = [self.tableView indexPathForCell:sender];
//Your code here
}
}

next view controller is not loaded when the segue is performed

I am still new to the storyboard stuff. I spent two days debugging this problem. It seems the destination view controller of a segue is not working properly when the -(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender is called.
I have a table view and when a cell is tapped, it calls for a segue
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
VAItem *item = [category itemAtIndex:indexPath.row];
[self performSegueWithIdentifier:#"SegueShowDetail" sender:item];
}
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"SegueShowDetail"]) {
VADetailViewController *detailViewController = segue.destinationViewController;
detailViewController.item = (VAItem*) sender; // <-- THIS ASSIGNMENT DOES NOT WORK
}
}
My debugging shows, the item is correctly passed down to prepareForSegue but the detailViewController.item is a wild pointer. It's not initialized and the = assignment does not have any effect.
I put a breakpoint in VADetailViewController's viewDidLoad and found out that the item variable is still the wild pointer address even though the assignment has taken place.
#interface VADetailViewController : UIViewController
// data
#property (nonatomic, retain) VAItem *item;
#end
item is also correctly synthesized.
Any help is much appreciated
Leo
If you're using a storyboard segue to transition to the next viewcontroller you don't need to use tableVeiew:didSelectRowAtIndexPath: in this situation. Depending how you have things set up that could be contributing to the problem.
In your storyboard, make sure you have drawn your push segue from your tableview's Prototype Cell to the detail view controller (i.e. from the cell, NOT from the tableViewController). If you have your storyboard set up that way your segue will be triggered as soon as the user selects a cell. A reference to the cell itself will be passed to prepareForSegue:sender: as the sender parameter. You can then inspect that object to find out which row was clicked in that method.
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"SegueShowDetail"]) {
// sender will be the tableview cell that was selected
UITableViewCell *cell = (UITableViewCell*)sender;
NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
VAItem *item = [category itemAtIndex:indexPath.row];
VADetailViewController *detailViewController = segue.destinationViewController;
detailViewController.item = item;
}
}
You really only want to use one of
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
to pass your data along to the next view controller. If you want to use the latter in your case, then you need to change your code to something along the lines of:
if ([segue.identifier isEqualToString:#"SegueShowDetail"]) {
VADetailViewController *detailViewController = segue.destinationViewController;
detailViewController.item = [catagory itemAtIndex:[self.tableView indexPathForSelectedRow].row];
}
I think you were getting an error because of what you assigned your sender. Here is the reference to the docs that explain what 'sender' should be.
https://developer.apple.com/library/IOs/#documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instm/UIViewController/performSegueWithIdentifier:sender:
Hope this helps.