In my app, there are different buttons that trigger different alert views. Each one has an option to click "More Information" which directs to the same UIWebView. I want to load a different url in the webview depending on which alert directed it to the webview.
I tried creating different segue identifiers and have attached that code. But the webview is blank/doesn't load the url. Is there a way to make this work using different segue identifiers? Or is there a better way to do this where I can use the same segue for all of the alerts but still load different urls in the webview? How do I tell the webview which one to load?
HomeViewController.m
-(void) alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
if (buttonIndex == 1){
if (alertView.tag==1) {
[self moreInfo];
}
}
}
-(void) moreInfo{
[self performSegueWithIdentifier:#"morebainfo" sender:nil];
}
-(void)ftmoreinfo{
[self performSegueWithIdentifier:#"moreftinfo" sender:nil];
}
- (IBAction)bainfo:(id)sender {
UIAlertView *baAlert =[[UIAlertView alloc] initWithTitle:#"Bacillus anthracis"
message:#"This is the message."
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:#"More Information", nil];
baAlert.tag=1;
[baAlert show];
}
- (IBAction)ftinfo:(id)sender {
UIAlertView *ftAlert =[[UIAlertView alloc] initWithTitle:#"Francisella tularensis"
message:#"This is the message."
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:#"More Information", nil];
[ftAlert show];
}
WebViewController.m
#interface MoreInfoViewController ()
#end
#implementation MoreInfoViewController
#synthesize MoreInfoWeb;
#synthesize loadUrl;
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if ([segue.identifier isEqualToString: #"morebainfo"]){
MoreInfoViewController *webview = [segue destinationViewController];
webview.loadUrl = #"http://example.com/";
}
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
NSURL *urlToLoad = [NSURL URLWithString:self.loadUrl];
[self.MoreInfoWeb loadRequest:[NSURLRequest requestWithURL:urlToLoad]];
}
Here's how I ended up fixing it:
I moved the prepare for segue method to the initial view controller:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
NSLog(#"prepareForSegue: %#", segue.identifier);
if ([segue.identifier isEqualToString: #"morebainfo"]){
MoreInfoViewController *webview = [segue destinationViewController];
webview.loadUrl = #"http://www.cdc.gov/anthrax/";
}
and then I gave each alert it's own tag:
- (IBAction)bainfo:(id)sender {
UIAlertView *baAlert =[[UIAlertView alloc] initWithTitle:#"Title"
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:#"More Information", nil];
baAlert.tag=1;
[baAlert show];
}
Each tag called a different method:
-(void) alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
if (buttonIndex == 1){
if (alertView.tag==1) {
[self moreInfo];
}
}
The methods performed the segues:
-(void) moreInfo{
[self performSegueWithIdentifier:#"morebainfo" sender:nil];
}
Fianlly, in the viewdidLoad of the webviewcontroller, I added:
NSURL *WebUrl = [NSURL URLWithString:self.loadUrl];
NSURLRequest *WebRequest = [NSURLRequest requestWithURL:WebUrl];
[MoreInfoWeb loadRequest:WebRequest];
And that worked! the main thing that helped was moving the prepare for segue method to the initial view controller instead of the webview controller
Related
I have two different view controllers, one for a dashboard and one for registration. I do not want the user to be able to interact with anything on the dashboard until the user logs in through an alertview. So every time the user navigates back to the dashboard or presses cancel and they are not logged in, I want the login alert to popup.
This works perfectly in all cases, including when the user hits the back button on the navigation bar in the registration view, but does not work when the user clicks OK on the alert in the registration page.
the dashboard view contains this code:
#property(strong) UIAlertView * alert;
//...
-(void)viewWillAppear:(BOOL)animated
{
user_email = [[NSUserDefaults standardUserDefaults] stringForKey:#"email"];
if ( user_email==nil ){
[self auto_login];
} else //...
}
-(void)auto_login
{
alert = [[UIAlertView alloc] initWithTitle:#"Login" message:nil delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"Login",#"Forgot Password",#"Register",nil];
alert.alertViewStyle = UIAlertViewStyleLoginAndPasswordInput;
[alert show];
}
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
switch (buttonIndex) {
case 0:
{
self.debug.text = #"Cancel";
[self auto_login];
break;
}
//...
default:
{
self.debug.text = #"Register";
[self nav_register];
break;
}
}
}
-(void)nav_register
{
RegisterProfileController *rvc = [[RegisterProfileController alloc] init];
[self.navigationController pushViewController:rvc animated:YES];
}
The registration view controller contains this code:
-(void)catch_registration
{
NSString *response = [[NSString alloc] initWithData:self.httpdata encoding:NSASCIIStringEncoding];
if( [response isEqualToString:#"OK"] ){
UIAlertView *successAlert = [[UIAlertView alloc] initWithTitle:#"Success" message:#"..." delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
successAlert.alertViewStyle = UIAlertViewStyleDefault;
[successAlert show];
}
else //...
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if ([alertView.title isEqualToString:#"Success"])
[self.navigationController popViewControllerAnimated:TRUE];
}
After debugging, I know that after clickedButtonAtIndex runs in the registration view controller, [alert show] runs in the dashboard view controller, and clickedButtonAtIndex does NOT run in the dashboard view controller, but no alert shows up.
Why isn't the alert showing or how can I debug this further?
If clickedButtonAtIndex "does NOT run" as you said, then the delegate might not be set correctly. In addition, you should likely move the code from viewWillAppear: to viewDidAppear: because the view is not in the view hierarchy at that point. Your solution might be a combination of these two issues.
I need help , googling also put me at no clue thus i'll post here for guidance and assist.
My situation is that I want the app delegate.m after when you press Ok, I want a simple redirect back to another view . Is that possible?
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
UIApplicationState state = [application applicationState];
if (state == UIApplicationStateActive) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Daily Vibes"
message:notification.alertBody
delegate:self cancelButtonTitle:#"Okay"
otherButtonTitles:nil];
[alert show];
}
Is it possible to do ?? After they click the cancel button Okay then they'll just be redirect back to the apps a specific page???
Try this:
Make your app delegate conforms to the UIAlertViewDelegate protocol, and add this code:
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
NSString *title = [alertView buttonTitleAtIndex:buttonIndex];
if([title isEqualToString:#"Okay"])
{
NSLog(#"Okay was selected.");
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
MyViewController *vc = [storyboard instantiateViewControllerWithIdentifier:#"MyViewController"];
[(UINavigationController*)self.window.rootViewController pushViewController:vc animated:NO];
}
else if([title isEqualToString:#"Hello"])
{
NSLog(#"Hello was selected.");
}
}
The delegate captures the selected button, checks the title, and acts accordingly. In this case, since you are in the app delegate, you have to do a manual push of the view controller (you aren't in a view controller, so theres no pushing allowed)
I have 2 view controllers, ViewController 1(VC1) and 2(VC2). In VC2 I have a back and done button. On clicking back button it goes directly to VC1 and on done it makes an api call and when it gets a response it shows an alert view and clicking ok goes back to VC1. Now when I make a api call a loading bar shows up and disappears when I get response and shows the AlertView. But if during that fraction of second when the loading disappears and AlertView is going to be popped up if I click on back and the view changes to VC1, the alert appears on VC1 and results in a crash.
This is a rare case as no user will purposely try for it but I was wondering if that crash can be managed without disabling the back button. I think there can be other instance such cases like if we are making an asynchronous calls and if the user is allowed to use UI while waiting for response and if any error alert that was suppose to show on one ViewController shows up in another may result in crash since the delegate that alert is referring to is that of the previous view controller. So is there any way to handle this kind of crash efficiently?
//Alert View sample
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:[[message objectAtIndex:1] capitalizedString] message:[message objectAtIndex:0] delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil] ;
[alert setTag:701];
[alert show];
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if ([alertView tag] == 701)
if (buttonIndex == 0)
{
[self.navigationController popViewControllerAnimated:YES];
}
}
The proper way to fix this problem is to use an instance variable to keep a reference to the alert view.
This instance variable should be set to nil in the alertView:didDismissWithButtonIndex: delegate method.
In the view controller's dealloc method, you call dismissWithClickedButtonIndex:animated: if the instance variable is still set.
Assume _alertView is the instance variable.
Create the alert:
_alertView = [[UIAlertView alloc] initWithTitle:[[message objectAtIndex:1] capitalizedString] message:[message objectAtIndex:0] delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil] ;
[_alertView setTag:701];
[_alertView show];
Update your existing alertView:clickedButtonAtIndex: method:
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if ([alertView tag] == 701) {
_alertView.delegate = nil;
_alertView = nil;
if (buttonIndex == 0) {
[self.navigationController popViewControllerAnimated:YES];
}
}
}
Add:
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex {
_alertView = nil;
}
Add:
- (void)dealloc {
if (_alertView) {
_alertView.delegate = nil;
[_alertView dismissWithClickedButtonIndex:_alertView.cancelButtonIndex animated:NO];
_alertView = nil;
}
}
I create Login page include (username & password & login button)
I want when to fill text field username and password if right user and password go on another page else if to be wrong give me one alert.
this is my code:
#import "Detail.h"
#implementation ViewController
{
NSString *name;
}
#synthesize Username,Password;
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (IBAction)Login:(id)sender {
NSString *a = [[NSString alloc]initWithFormat:#"http://192.168.1.102/mamal/login.php?u=%#&p=%#",Username.text,Password.text];
NSString *url = [[NSString alloc]initWithContentsOfURL:[NSURL URLWithString:a]];
NSLog(#"%#",url);
if ([url isEqualToString:#"0"]) //this is wrong user & password
{
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"ERROR" message:#"WRONG" delegate:nil cancelButtonTitle:#"Dissmis" otherButtonTitles: nil];
[alert show];
}
else
{
name = #"Mohammad";
}
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([name isEqualToString:#"Mohammad"] , [[segue identifier] isEqualToString:#"Segue"]) {
Detail *det = segue.destinationViewController;
}
}
but dosent work!!! I want only right user & password go on next page
You have to make triggerless segue to perform this operation. Make triggerless segue from storyboard and fire it when your username and password is right.
To create a triggerless segue, start control+dragging the segue from the containing view controller icon in the scene dock at the bottom of the scene. Drag to the destination scene like normal, and pick the segue type. Select the segue, and in the inspector, choose a segue identifier.
Then call the method [self performSegueWithIdentifier:#"Identifier" sender:nil];
when your condition is true
If you want to use segues I think you are missing the call to actually perform the segue after the line where you set the name
name = #"Mohammed"
[self performSegueWithIdentifier:#"mySegue" sender:self]
Being "mySegue" the identifier of your segue in storyboard.
And then, you probably want to send the new View Controller the name.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"mySegue"]) {
Detail *det = segue.destinationViewController;
det.name = name;
}
}
Here AuditViewController is segue name
you need to call class like this in storyboard
[self performSegueWithIdentifier:#"AuditViewController" sender:self];
Edit
Check Condition
- (IBAction)Login:(id)sender {
NSString *a = [[NSString alloc]initWithFormat:#"http://192.168.1.102/mamal/login.php?u=%#&p=%#",Username.text,Password.text];
NSString *url = [[NSString alloc]initWithContentsOfURL:[NSURL URLWithString:a]];
NSLog(#"%#",url);
if ([url isEqualToString:#"0"]) //this is wrong user & password
{
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"ERROR" message:#"WRONG" delegate:nil cancelButtonTitle:#"Dissmis" otherButtonTitles: nil];
[alert show];
}
else
{
name = #"Mohammad";
if([name isEqualToString:#"Mohammad"])
[self performSegueWithIdentifier:#"Segue" sender:self];
//else
//NSLog(#"Can not Login");
}
}
prepareForSegue method call
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"Segue"])
{
Detail *det = segue.destinationViewController;
}
}
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