SFSafariViewController done button not working - ios

I have a test ViewController which is embedded in a NavigationController. In test ViewController I have a WebView button. When I click on that button it navigates to SafariViewController and it's loading given URL. In that WebView when I click on "Done" button it's calling delegate method called safariViewControllerDidFinish. But that SafariViewController is not being dismissed.
Here is my code.
- (IBAction)bannerWebviewAction:(id)sender {
NSURL *urls = [NSURL URLWithString:#"http://www.google.com"];
SFSafariViewController safariVC = [[SFSafariViewController alloc] initWithURL:urls];
[self showViewController:safariVC sender:nil];
safariVC.delegate = self;
}
#pragma SFSafariViewControllerDelegate
-(void)safariViewControllerDidFinish:(SFSafariViewController *)controller {
// Done button pressed
[controller dismissViewControllerAnimated:YES completion:nil];
}
Done button is calling, view is not dismissing. I checked log for the self and controller, both are correct.

You should not say
[self showViewController:safariVC sender:nil];
You should say
[self presentViewController:safariVC animated:YES completion:nil];
SFSafariViewControllers are meant to be presented modally and will dismiss itself when done is pressed.

Related

PushViewController doesn't pushes after dismissingViewController

I am developing iPhone app, where i got stuck at one point.
The error i am facing is, i have one presentViewController on which i have one button, on click of that button i am dismissing my presentViewController and after dismissing i want to push My view controller but it doesn't pushes.
Code on PresentViewController:
- (IBAction)ButtonClick:(id)sender {
[self dismissViewControllerAnimated:YES completion:^{
[Obj MethodCall];
}];
}
after dismissing PreviousViewController:
-(void) MethodCall
{
NSLog(#" -- MethodCall Success --");
[self.navigationController pushViewController:[[NewViewController alloc] init] animated:YES];
}
My log shows -- MethodCall Success -- but it does not pushes my view.
Where i am doing mistake ?
Please help and thanks for reading.
The problem with you is I think you are not having UINavigationController as a rootViewController of the viewController from which you have to navigate. So please try to add a UINavigationController as a parent view or rootView of the vieController from which you want to push another viewController.
- (IBAction)ButtonClick:(id)sender {
NewViewController *newView = [[NewViewController alloc] init]
[self presentViewController:newView animated:YES completion:nil];
}

Push to ViewController without back button

I am developing an iOS app which contains login/authentication functionality - basically first time a user logins, in they need to enter relevant login details - then they are passed to main app screens - subsequent visits to the app they will be automatically authenticated.
All above works fine - the issue I have is with the Navigation bar - it appears in the main screen in the main part of the app with a back button - I don't want this to be displayed as they should not be able to return to the login screen once authenticated. I guess it's using the root navigation controller which explains the logic, but is there a way to ignore the navigation controller of the login section so the back button is not displayed in the main app.
Below is a screenshot of the structure to help my explanation - left hand group of screens are the login process right hand is the main app structure.
The code used to switch screens is as follows -
SWRevealViewController *swRevealController = (SWRevealViewController *)navVC;
swRevealController.managedObjectContext = self.managedObjectContext;
[self.navigationController pushViewController:controller animated:YES];
Don't push view controller. Create new hierarchy with:
Objective-C
[self.navigationController setViewControllers:#[controller] animated:YES];
Swift
navigationController.setViewControllers([controller], animated:true)
In the Screen which implements after login, the ViewDidLoad method add the line to hide back bar button.
self.navigationItem.hidesBackButton = YES;
Additionally you can add an 'Logout' option as
UIBarButtonItem *backBarButton = [[UIBarButtonItem alloc] initWithTitle:#"Logout" style:UIBarButtonItemStyleBordered
target:self
action:#selector(LogoutClick)];
self.navigationItem.leftBarButtonItem = backBarButton;
-(void)LogoutClick {
[self showLogoutAlert];
}
-(void)showLogoutAlert {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#""
message:#"Do you want to Logout ?"
delegate:self
cancelButtonTitle:#"Cancel"
otherButtonTitles:#"Logout", nil];
[alert show];
}
- (void)alertView:(UIAlertView *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex == 1) {
[self.navigationController popToRootViewControllerAnimated:YES];
}
}
Use a modal view controller for the login screen so its not part of your navigation controller hierarchy within your navigation root probably in view did load - sample code below:
- (void) viewDidLoad {
......
LoginVC *loginViewController = [LoginVC alloc] init];
loginViewController.parent = self;
[self presentViewController: loginViewController animated:YES completion:NULL];
return;
}
You may or may not dismiss the modal view from the root - if you do, you will need to be able to call the dismiss routine from loginViewController but there are other ways as well and you can put the dismiss inside the modal view (loginViewController)
(void) login_exit:(BOOL)success {
[self dismissViewControllerAnimated:YES completion:NULL];
if !(success) {
.... send message (UIAlertview and ask if he or she wants to try again)
}
else {
}
return;}
Very simple.. Just navigate to rootviewcontroller
SWRevealViewController *swRevealController = (SWRevealViewController *)navVC;
swRevealController.managedObjectContext = self.managedObjectContext;
//-- I think above lines not needed as per your question
[self.navigationController popToRootViewControllerAnimated:YES];
You need to hide the Navigation Bar in the ViewController before you push the SWRevealViewController by using the below line in viewDidLoad
Objective C
self.navigationController.navigationBarHidden = true;
Swift
self.navigationController?.navigationBarHidden = true;
It will not show the back button in the next view controller pushed
2022 answer
#IBAction func SomeScreen() {
let s = UIStoryboard ...
navigationController?.isNavigationBarHidden = true;
navigationController?.pushViewController(s, animated: true)
}
It's that easy.
Write this in viewDidLoad method
self.navigationItem.hidesBackButton = YES;
This will hide the back button for the first view.
ClassA* controller = [storyboard instantiateViewControllerWithIdentifier:#"ClassAIdentifier"];
if (controller != nil) {
[self.navigationController pushViewController:controller animated:YES];
[controller.navigationItem setHidesBackButton:YES animated:NO];
}
You MUST hide the navigationItem after push, otherwise it will be nil.

Presenting UIImagePickerController from modal UIViewController

I am trying to have it so a user can choose a photo from their album into an imageview. It seems to work fine if I'm using a push segue to that viewcontroller that has the button to perform the action, but when I change it to modal segue, nothing happens when I click the button to run the function. What is the cause of this exactly?
Method:
- (IBAction)choosePhotoFromAlbum:(id)sender {
UIImagePickerController *imgPicker = [[UIImagePickerController alloc] init];
imgPicker.delegate = self;
imgPicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
[self.navigationController presentViewController:imgPicker animated:YES completion:nil];
}
You're trying to present it from the navigation controller, but your view controller is modal. Change
[self.navigationController presentViewController:imgPicker animated:YES completion:nil];
to
[self presentViewController:imgPicker animated:YES completion:nil];.
you're trying to present it from the navigation controller, but your view controller is modal. so just write
[self presentViewController:YourImagePickerController animated:YES completion:nil];.

remove ViewController from parent screen stays black

I'm having trouble with removing a modal view.
I want to show (after pressing a button) a my own SendMailViewController which it self shows a MFMailComposeViewController. Then and after pressing cancel of send, in my own SendMailView controller in didFinishWithResult i do a [self dismissModalViewControllerAnimated:YES] and that works. The MFMailComposeView goes away.
But then the screen stays black....it think i also have to remove my SendMailViewController from it's parent. That's where i pushed the button...even after [self removeFromParentViewController] it still stays black...
Where do i go wrong?
And yes i would like the extra viewcontroller (SendMailViewController) because that controller will become the delegate of MFMailComposeViewController. Otherwise my caller (controller with the button) get's to much responsibility. Or do i also go wrong here?
Thanks,
/jr00n
- (IBAction)tapExportButton:(id)sender
{
SendMailViewController *sendMailController = [[SendMailViewController alloc]init];
[self presentViewController:sendMailController animated:YES completion:^() {[sendMailController openMailDialog];}];
[sendMailController release];
}
SendMailViewController:
- (void)openMailDialog
{
if ([MFMailComposeViewController canSendMail])
{
MFMailComposeViewController *mailer = [[MFMailComposeViewController alloc] init];
mailer.mailComposeDelegate = self;
...
[self presentModalViewController:mailer animated:YES];
}
}
- (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error
{
....
// Remove the mail view
// first i did this:
// [self dismissModalViewControllerAnimated:YES];
[self dismissViewControllerAnimated:YES completion:^{[self removeFromParentViewController];}];
}
The problem is with the [self dismissViewControllerAnimated:YES completion:^{[self removeFromParentViewController];}]; in your didFinishWithResult method.
Remove that line and add the following line,
[controller dismissViewControllerAnimated:YES completion:^{[self dismissViewControllerAnimated:YES completion:nil]}];
That make sure we dismiss the controller after dismissing the MailController

how to dismissModalViewControllerAnimated: YES

I read a lot of documentation about this before i decided to ask.
So I have navigationController in my app. When user enters the first time in my app I do this
RegViewController *opr = [[RegViewController alloc] init];
self.regController = opr;
[self.navigationController presentModalViewController:self.regController animated:NO];
[opr release];
And it works fine. But when I click OK button in RegViewController I call this method
-(IBAction)btn_regPressed:(id)sender
{
NSLog(#"start to dissmis modal");
[self.navigationController dismissModalViewControllerAnimated:YES];
//[self.navigationController.parentViewController dismissModalViewControllerAnimated:YES];
}
But this code doesn't want to dismissModalViewController
Can somebody help me with thios issue please. Thanks
try to change your call to (remove the navigationController):
[self presentModalViewController:self.regController animated:NO];
and in your button (remove the navigationController):
[self dismissModalViewControllerAnimated:YES];
You are telling to your navigationController dismiss your modal, but your viewcontroller should do it.
Navigation controllers are used to navigation (go and back) purposes. And probably, your navigationController is nil.
In your RegViewController, try to dismiss self like so:
-(IBAction)btn_regPressed:(id)sender
{
NSLog(#"start to dissmis modal");
[self dismissModalViewControllerAnimated:YES];
}

Resources