I've been trying to make my pushed view controller dismiss or go back one once a confirm action has taken place. I read the many posts in stackoverflow on this subject (I've never done it before) e.g:
How to perform Unwind segue programmatically?
but had quite some problems. First of all, the ctrl drag from view controller to exit, didn't work though that seems to be a bug in Xcode 6, so I added the following workaround as advised and changed the class back and forth:
#interface RequestLessonViewController ()
- (IBAction)unwindToMyViewController: (UIStoryboardSegue *)segue;
#end
This allowed me to add in the segue from my action button to Exit. I also of course gave it an identifier (unwindSegue).
I then added the performWithSegueWithIdentifier line in my buttons code as follows:
- (IBAction)requestLessonAction:(UIButton *)sender {
// PUT CONFIRM POP UP IN HERE ???
NSLog(#"ADD A LESSON REQUEST TO LESSONS DATABASE");
UIAlertView *confRequest = [[UIAlertView alloc] initWithTitle:#"Lesson Request Submitted"
message:#"Congratulations"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[confRequest show];
[self performSegueWithIdentifier:#"unwindSegue" sender:self];
}
However my unwind is still not being kicked off.
Maybe this is still a problem due to xcode 6.4 and I need to use a different work around?
Anyway any help in this would be great
Thanks
I fixed this using this very useful and clear github from Bradley.
https://github.com/bradley/iOSUnwindSegueProgramatically
Basically I wasn't creating the following type of method on the viewcontroller I was returning too, but inside the one I was trying to exit from :-/ All clear now thanks.
- (IBAction)returnToStepOne:(UIStoryboardSegue *)segue {
NSLog(#"And now we are back.");
}
Related
That's the first time i post on this site.
I explain, i have to work on an already advanced project in ios.
I'm new in objective-c and it's a quite strange language when you come from java.
I have a strange issue.
In the app there is a login screen, you put mail and pass, click on a button and you go on the main view. It's work perfectly.
What i want to do is autologin. I use keychains for that, store it, retrieve it, populate my user and pass with. It's works perfectly.
If my user click on the login button it's also work perfectly.
But if i call the function myself with the code, it doesn't change the view. I can't understand why.
I put here the code where i think the change is called.
if ([result isEqualToString:#"1"]) {
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
[userDefaults setObject:Email.text forKey:#"email"];
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"Welcom back to FriendsCam!" message:#"Start sharing your video" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
//Email.text = nil;
//Password.text = nil;
UIStoryboard *MainStoryboard_iPhone=[UIStoryboard storyboardWithName:#"MainStoryboard_iPhone" bundle:nil];
self.view.window.rootViewController=[MainStoryboard_iPhone instantiateInitialViewController];
So this code is in a function who is called by the functions called when the button login is pressed if all field are correctly fill.
It work when a user manually click on the button but not when i call the button's function myself in code but the alert "welcome back" of good login show in both cases. it's only the jump in the storyboard who is broken.
Can someone explain why ? It will be very kind.
Ok i find the solution.
I was firing my method to quickly, something related with loading time of the view i think.
I delay my call with a nstimer and all work perfectly.
I have modal view controller displayed on rightBarButtonItem click. I'm using FbLoginView in this controller as in sample ios-Facebook SDK 3.0 Error 5 When Posting Status Update.
But i'm unable to show modal view controller more than one time.
I tried to release FBLoginView on ViewDidUnload but it always crashes on second atempt to open modal view controller.
Got the same problem and deal with it for couple days already. And finally this is my solution:
if (!FBSession.activeSession.isOpen) {
theLoginView = [[FBLoginView alloc] init];
theLoginView.frame = CGRectOffset(theLoginView.frame,
([[UIScreen mainScreen] bounds].size.width-theLoginView.frame.size.width)/2,
([[UIScreen mainScreen] bounds].size.height-theLoginView.frame.size.height)/2 -50);
theLoginView.delegate = self;
[self.view addSubview:theLoginView];
[theLoginView sizeToFit];
}
//Only close the session when application is terminating, this will save the token information:
- (void)applicationWillTerminate:(UIApplication *)application {
[FBSession.activeSession close];
}
//And keep the FBSession within the app until the user want to logout:
[FBSession.activeSession closeAndClearTokenInformation];
Right now for me its working completely fine. Hope this help.
The FB SDK doesn't seem to like you creating more than one FBLoginView. Maybe you can if you properly terminate the session, but I found it easier just to create the LoginView once and keep it around.
I did this as follows:
1) in my .m modal view controller file, I created a static variable
static FBLoginView* loginView;
2) When loading the modal view controller in my viewDidLoad, instead of
FBLoginView *loginview = [[FBLoginView alloc] initWithPermissions:
[NSArray arrayWithObject:#"status_update"]];
loginview.frame = CGRectOffset(loginview.frame, 10, 10);
I added a check to find if its already initialized, like this:
if (!loginView) {
loginView = [[FBLoginView alloc] initWithPermissions:
[NSArray arrayWithObject:#"status_update"]];
loginView.frame = CGRectOffset(loginView.frame, 10, 10);
}
Beyond that, I just followed the example of FB's HelloFacebook project.
Not pretty code, but it seems to work.
I had the same problem. Try to add something like this:
if(!yourFBLoginView)
{
yourFBLoginView = [FBLoginView alloc] init...];
}
And/or do not forget to close your active session when you dismissing your modalViewController.
if ([[FBSession activeSession] isOpen])
{
[[FBSession activeSession] close];
}
I think the answer for me (a variant of what was said) was only that I needed to have:
[FBSession.activeSession closeAndClearTokenInformation];
in the:
(void)applicationWillTerminate:(UIApplication *)application
function. The problem specifically for me was, while I was testing...I was constantly terminating the app without actually logging out the user without ever destroying the FBSession, so that when I went back into the app to test what I had changed - my Facebook user was still logged in, and thus some of the conditionals were being incorrectly met. I think this is very important for anyone who is testing (and I'm actually thinking that you should have that line in there anyway) to make sure to clear the session every time the application terminates to avoid this problem...I can imagine a scenario where my app just crashed on somebody and now they are reopening it and they experience the crash because the session was never cleared.
I am having a problem correctly implementing a UIActionSheet in an iPad 5.1 (XCode 4.3) project. I can populate it correctly with all the items I need. The list is longer than the window, but the scrollbars automatically come up, etc. However, the cancel button (which I presume is supposed to be at the end) is coming up half hidden behind my tab bar. Shown below:
(sorry, SO won't let me post images yet)
Here is my storyboard setup:
The entry point is that Tab Bar Controller on the left, which goes to another Navigation Controller (center), which has the View Controller on the right as the root view.
http://i854.photobucket.com/albums/ab103/srVincentVega/ScreenShot2012-06-28at52713PM.png
I have tried presenting the UIActionSheet in all sorts of ways, but this odd behavior persists, and I can't figure out how to address it
- (IBAction)cmdReason:(id)sender
{
NSArray *reasons = [AppState getInspReasons];
UIActionSheet *action = [[UIActionSheet alloc]
initWithTitle:#"Reason for Inspection"
delegate:self
cancelButtonTitle:#"Cancel"
destructiveButtonTitle:nil
otherButtonTitles:nil];
for (NSString *rsn in reasons)
{
[action addButtonWithTitle:rsn];
}
[action showInView:self.view];
}
I have tried the various methods to show "action" - showFromTabBar, showFromToolbar, etc - I am VERY new to this development environment, so I am not up to speed yet on how these items interact at this level. Does anyone have a suggestion for how I can present this correctly?
I am sorry if this has already been asked elsewhere. I have spent all day trying bits of code from all over the web, including SO. I don't know if it's something to do with my storyboard layout, or what.
One further thing - when I rotate the emulator, the action sheet does redraw, but the bit at the end there gets wonky looking, like it can no longer figure out how to draw it.
Many thanks!
EDIT:
I have put together a very small project that demonstrates this exact behavior. I don't have a good way to host the zip file, so I put on google docs and shared it. The link is below. If you click on that, there should be a download option under file that will give you the original zip file.
https://docs.google.com/open?id=0B7IYvy9_c_NLaEFneGc5bzc2S2c
Seems like there is not a real solution for this. It looks like it's a limitation with UIActionSheet if you add that amount of button titles and present that from a tab bar.
Beside that, the proper way to display an UIActionSheet from a tab bar is to use
[action showFromTabBar:self.tabBarController.tabBar];
instead of
// Taken from your example project
AppDelegate *d = [[UIApplication sharedApplication] delegate];
UIWindow *w = d.window;
UIViewController *vc = w.rootViewController;
UITabBarController *c = (UITabBarController *)vc;
UITabBar *t = c.tabBar;
[action showFromTabBar:t];
I would think if you got a reference to the tab bar controller then you should be able to present it from that. You can try showing it from the main window but I would think you shouldn't rely on that.
[action showInView:[[UIApplication sharedApplication] keyWindow]];
Try this:
CGRect r = CGRectMake(x, y, w, h); //change values to fit location of button
[actionSheet showFromRect:r inView:self.view animated:YES];
I used it on one of my apps with the same problem and the dismiss button showed up ok.
I have a working code from a tutorial but don't understand it completely.
Situation:
After a button was pressed in my iPhone App
an AlertView appears with three buttons.
Now I like to check what button the user pressed.
CODE FROM THE TUTORIAL:
- (IBAction)infoButtonPressed:(id)sender {
UIAlertView *myAlert1 = [[UIAlertView alloc]initWithTitle:#"My Alert View 1"
message:#"Here we go"
delegate:self
cancelButtonTitle:#"Cancel"
otherButtonTitles:#"Option1", #"Option2", nil];
[alert show];
}
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
NSLog(#"Button: %i, was pressed.", buttonIndex);
}
Code works, I see the correct output in the console as a NSLog but how is it possible
that the method:
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
NSLog(#"Button: %i, was pressed.", buttonIndex);
}
refers to the correct alert view. In this case: myAlert1.
What about with more than one alert view.
For example a second one calling myAlert2.
I know the following code is not correct but it would make more sense to me
if I'd write the method as follow:
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
NSLog(#"Button: %i, was pressed.", buttonIndex_FROM_myAlert1);
}
Hope you can help, drives me nuts.
Regards,
Marc
how is it possible that the method refers to the correct alert view?
For exactly that reason, the delegate method alertView:didDismissWithButtonIndex: actually tells you which alert view it refers to. Note that the method has two arguments. The second one tells you the button index and the first one points to the alert view this button index refers to.
If you have more than one alert view that share the same delegate, you will have to check against the first argument which alert view this is about. To be able to do that, you would have to store the alert views in an ivar/property or other data structure in order to remember them in the delegate method. (Or, since UIAlertView is a subclass of UIView, you could use the tag property to distinguish between multiple views).
i want to show the alert and when somebody click on OK they need to be send to the page before. How can i make this?
I use the following code:
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"BOOYAH!"
message:#"Saved" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
Considering you have 1 option on the alert view and the delegate is self. Use this method in the same .m file as the code above
- (void)alertView:(UIAlertView *)alertV didDismissWithButtonIndex:(NSInteger)buttonIndex
{
//go back a page
[alertV autorelease];
}
Don't forget to release the alert view. I added it in the delegate method, but you can choose to release it right after showing it (only 1 release though)
Assign the UIAlertViewDelegate to self and then implement the following method is called
- (void) alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
if (buttonIndex == buttonIndexForOK) { // Where buttonIndexForOK is the index for your ok button, in this case, that would be zero, but if you want an OK and a Cancel button this would be different.
// go back to the last page
}
}
UIAlertView follows the delegation design pattern that is extremely common in iOS development. You provide a delegate object, and when the object wants to tell you about something, it sends that delegate object a message.
In your code, you've provided self as the delegate. This means that this object needs to conform to the UIAlertViewDelegate protocol.
You will see that there are several methods you can implement to react to various events relating to the alert view. You should use the alertView:clickedButtonAtIndex: method, which provides an index parameter indicating which button was tapped.