I have already created UI alert and call a function.
UIAlertView *alertView1 = [[UIAlertView
alloc]initWithTitle:#"Test"message:#"Working 1!!"delegate: self
cancelButtonTitle:#"OK"otherButtonTitles:nil];
[alertView1 show];
Method for call newView viewController
- (void)alertView:(UIAlertView *)alertView
didDismissWithButtonIndex:(NSInteger) buttonIndex
{
if (buttonIndex == 0)
{
NSLog(#"Cancel Tapped.");
}
else if (buttonIndex == 1)
{
// NSLog(#"OK Tapped. Hello World!");
UIViewController *newView = [[UIViewController alloc] init];
[self presentViewController:newView animated:YES completion:nil];
}
}
I have created a new class named "newView" and also add "UIAlertViewDelegate" in present view controller.
But my problem is, I couldn't connect the newView viewcontroller with my present view controller.
Here you are creating object in memory so that's why you can now only access properties and public methods of newView. Can not make presentation of newView.
You can achieve this by 2 ways.
Either you can make this possible by calling Segue or you have to create newView object from Storyboard.
ViewController *entryController = [self.storyboard instantiateViewControllerWithIdentifier:#"go"];
[self.navigationController pushViewController:entryController animated:YES];
Related
I'm looking to have multiple segues through a single UIBarButtonItem button, and depending on the response through the UIActionSheetDelegate, the correct UIViewController would load through a push segue. This is my current code in for the UIActionSheetDelegate.
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex == 0)
{
// rate this app
}
else if (buttonIndex == 1)
{
[self performSegueWithIdentifier:#"bugReportSegue" sender:self];
}
else if (buttonIndex == 2)
{
[self performSegueWithIdentifier:#"featureRequestSegue" sender:self];
}
}
The problem with this is that I cannot link the same button to multiple views through Storyboard segues. I'm wondering if there's a workaround.
EDIT
This is what my code looks like now: (minus the Storyboard)
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex == 0)
{
// rate this app
}
else if (buttonIndex == 1)
{
[self.storyboard instantiateViewControllerWithIdentifier:#"bugReportIdentifier"];
}
else if (buttonIndex == 2)
{
[self.storyboard instantiateViewControllerWithIdentifier:#"featureRequestIdentifier"];
}
}
Instead of using a segue with performSegueWithIdentifier
Consider using the StoryboardID along with instantiateViewControllerWithIdentifier:
To do so, in the Storyboard, simply create a view controller and don't connect any segues to it. In the third tab in the properties inspector, assign it a Storyboard ID:
Then, in your code, you can create an instance like this:
[self.storyboard instantiateViewControllerWithIdentifier:#"ImagePicker"]
This will create a new instance every time though, so you should still save it and re-use it whenever possible.
EDIT: After you get the view controller, you need to present it yourself.
If you are using a NavigationViewController call:
UIViewController * newController = [self.storyboard instantiateViewControllerWithIdentifier:#"ImagePicker"];
[self.navigationController pushViewController:newController];
If not you can use:
UIViewController * newController = [self.storyboard instantiateViewControllerWithIdentifier:#"ImagePicker"];
[self presentViewController:newController animated:YES completion:nil];
Edit 2:
Here is what your final code should look like:
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex == 0)
{
// rate this app
}
else if (buttonIndex == 1)
{
UIViewController * controller = [self.storyboard instantiateViewControllerWithIdentifier:#"bugReportIdentifier"];
[self presentViewController:controller animated:YES completion:nil];
}
else if (buttonIndex == 2)
{
UIViewController * controller = [self.storyboard instantiateViewControllerWithIdentifier:#"bugReportIdentifier"];
[self presentViewController:controller animated:YES completion:nil];
}
}
my application story board is as following
it is a tab bar controller based application with one of the tabs embedded in a navigation controller. when the user click on the first tab (view1) and click a button inside this view, he will be moved to view2. instead of using the back button to return to view1, I want the user to click on the tab item in order to return to view1 which works fine. However, I want to view an alert when the user clicks on the tab and he is in View2. I am using shouldSelectViewController and didSelectViewController delegate methods to check what tab is clicked and view the alert. The problem is that I can't reach View2 from these methods in the delegate to inform the application to view the alert only when user is in view2 and clicks the tab.
I tried to use this code inside shouldSelectViewController
if (tabBarController.selectedIndex == 0) {
NSLog(#"Delegate nav title: %#", tabBarController.selectedViewController.navigationItem.title);
}
these lines always return the title of view1
As they are in the same navigation controller, they have the same navigation item. Each view can configure this navigation item but it is generally the same object. That is why it returns the same title. Try setting up the navigation item title in second view controller's viewDidLoad method.
I finally found a solutino to my problem
first I added a static variable to View2 and called it inView2 as following
in View2.h
#interface
{}
+ ( BOOL ) isInQuizViewController;
+ ( void )setInQuizViewController:(BOOL)inQuizVal;
//...
#end
in View2.m
#implementation
static BOOL inView2 = NO;
+(BOOL)isInView2
{
return inView2;
}
+ ( void )setInView2:(BOOL)Val
{
inView2 = val;
}
these two methods are for setting and getting the value of inView2 which tells me whether or not the user is currently in View2
in View1.h create an IBAction associated with the button that will transmit from View1 to View2 and connect it to your storyboard
- (IBAction)GoToView2:(id)sender;
go to View1.m and import
#import "View2.h"
and implement your IBAction method to set the InView2 to YES
- (IBAction)GoToView2:(id)sender {
[View2 setInView2:YES];
}
then in the delegate.m
#import "View2.h"
#implementation AppDelegate
UITabBarController * _tabBarController;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
_tabBarController = (UITabBarController *)_window.rootViewController;
_tabBarController.delegate = self;
// Override point for customization after application launch.
return YES;
}
I defined a global _tabBarController and set it to _window.rootViewController and set its delegate to this delegate and remember to import "View2.h"
going to the ShouldSelectViewController method (note that this method is called before the transition to the selected tab ViewController, hence it is perfect for decision making of whether or not the selected tab viewController should be displayed to the user).
so in ShouldSelectViewController method I did the following
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController {
if(tabBarController.selectedIndex == 2)
{
if ([View2 isInView2]) {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"alert"
message:#"are you sure you want to exit?"
delegate:self
cancelButtonTitle:#"Cancel"
otherButtonTitles:#"Yes",nil];
[alertView show];
return NO;
}
}
return YES;
}
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if(buttonIndex == 1)
{//ok button pressed
// NSInteger destinationTabIdx = 2;
// UIView * fromView = tabBarController.selectedViewController.view;
// UIView * toView = [[[[[tabBarController.viewControllers objectAtIndex:destinationTabIdx] navigationController] viewControllers] objectAtIndex:0] view];
UINavigationController *nav = (UINavigationController *)_tabBarController.selectedViewController;
NSLog(#"vc title: %#",nav.title);
// [UIView transitionFromView:fromView toView:toView duration:0.8
// options: UIViewAnimationOptionTransitionNone
// completion:^(BOOL finished) {
// if (finished) {
// tabBarController.selectedIndex = destinationTabIdx;
// }
// }];
[nav popViewControllerAnimated:YES];
[QuizViewController setInQuizViewController:NO];
NSLog(#"app delegate transistion done");
}
}
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.
I'm developing an app in which I need to show a ViewController when I press the "OK" button in an UIAlertView. How I can do that?
I found on here this solution: iOS Dev: Segue by pressing a button in an Alert?, but it didn't work.
xCode says:
the method: presentModalViewController is deprecated
and I found on the web that I should use the method presentViewController.
I tried to do that but it shows me a black screen without any interaction, what's wrong?
I paste here my code, maybe you can help me.
-(void) alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex != alertView.cancelButtonIndex)
{
PromoViewController *pvc = [[PromoViewController alloc] init];
[self presentViewController:pvc animated:YES completion:nil];
}
}
Thank you
In order to use a segue programatically you need to called performSegueWithIdentifier.
First make sure your segue has an identifier in the storyboard.
Then use this code instead...
-(void) alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex != alertView.cancelButtonIndex)
{
[self performSegueWithIdentifier:#"YourSegueIdentifier"];
}
}
This will do what you want.
See this: Make button it UIAlertView perform Segue
It will show you how to create a manual segue and call it.
Well another approach is to get the instance and do it programatically as
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"MainStoryboard"
bundle: nil];
PromoViewController *controller = (PromoViewController*)[mainStoryboard
instantiateViewControllerWithIdentifier: #"<Controller ID>"];
[self presentViewController:controller animated:YES completion:nil];
Note controller ID is the storyboard id you set for the scene via attribute inspector
I need to change to another scene after clicking an alert view button.
Here is my code:
(IBAction)confirmar {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Confirmar"
message:#"Confirma que desea recibir notificaciones en su teléfono móvil"
delegate:self
cancelButtonTitle:#"Cancelar"
otherButtonTitles:#"Si quiero participar", nil];
[alertView show];
}
(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:
(NSInteger)buttonIndex {
if (buttonIndex == 1) {
inscrito *cambia = [[inscrito alloc] initWithNibName:#"inscrito" bundle:nil];
[cambia setTitle:#"inscrito"];
cambia.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
// [self.navigationController pushViewController:cambia animated:YES];
[self.navigationController presentModalViewController:cambia animated:YES];
[cambia release];
NSLog(#"Boton 1");
}
}
I'm trying to change to the UIViewController called "inscrito".
I also added: #import "inscrito.h" at top of the file...
I usually use UIViewController, but it appears you might want to push the new viewcontroller
http://developer.apple.com/library/ios/#documentation/uikit/reference/UINavigationController_Class/Reference/Reference.html
Pushing and Popping Stack Items
– pushViewController:animated:
– popViewControllerAnimated:
– popToRootViewControllerAnimated:
– popToViewController:animated:
I think the first code is right, but you need to change this :
[self.navigationController presentModalViewController:cambia animated:YES];
with this :
[self presentModalViewController:cambia animated:YES];
If you don't have navigationController, it won't work.Hope it help