As you can see I'm trying to performSegue from Photo Action View Controller to Setting View Controller (UITableViewController).
So I'm performing from PhotoActionViewController directly (not using buttons etc.) because I want to perform this segue when user taps on one option from showing AlertView. Everything works like charm untill I set Class for the SettingsViewController. The segue performs but I can't see any UITableViewCell. How can I get this wor form me?
Here is my code:
- (IBAction)imageViewTapped:(UITapGestureRecognizer *)sender
{
BlockAlertView *alert = [BlockAlertView alertWithTitle:#"New Photo" message:#"Decide what you would like to do with this photo"];
[alert addButtonWithTitle:#"Create New Project" block:^{
// Pushing to New Project Settings Controller
[self performSegueWithIdentifier:#"NPSSegue" sender:self];
}];
[alert addButtonWithTitle:#"Add To Existing Project" block:^{
NSLog(#"Add to existing");
}];
[alert setCancelButtonWithTitle:#"Cancel" block:nil];
[alert show];
}
I'm not posting prepareForSegue as it is empty for this moment and I don't know if anything should be there.
whenever using segue programmatically we need to connect segue through one scene to another scene(viewcontroller) so create a button make it invisible and connect it to the destination scene and in uialertview delegate make button setEnabled:true and before pls set the segue Idetifier thanks and sorry for poor english.......
Related
I have a modally presented view controller which I want to unwind. I have it set up that if I press "cancel", it will execute an unwind segue. But, I want to make a confirmation button using UIAlertView. As in, "Are you sure you'd like to cancel?". How can I use the UIAlertView buttons to trigger an unwind segue?
In your .h file, declare UIAlertViewDelegate. And then in your .m file, you can write code in cancel button action method:
- (IBAction)confirmationButtonPressed:(id)sender{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Warning" message:#"Are you sure you'd like to cancel?" delegate:self cancelButtonTitle:#"Yes" otherButtonTitles:#"No",nil];
[alert show];
}
And then you can add UIAlertView Delegate method in your .m file:
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
if(buttonIndex == 0){
[self dismissViewControllerAnimated:YES completion:nil];
}
}
Declare a manual unwind segue from the storyboards by selecting the whole view controller and ctrl dragging the mouse to exit.
Give that segue an identifier and fire the segue from delegate of the UIAlertView using performSegueWithIdentifier method
iPhone app with a storyboard setup. Button on the initial view that links through to another view. I have added an alert to that button click so that when it is tapped the view changes and immediately the alert appears asking 'Do you want to continue? Yes No'
If they click yes the alert disappears, if they click no the storyboard should go back to the start.
This is what I've got so far and it doesn't work, nothing happens. I've tried multiple various solutions touted on SO but nothing is working so far. Removing the buttonindex check doesn't do anything.
I'd actually prefer this alert to appear even before the view changes but at the moment I have it displaying after the segue occurs which isn't ideal but if I could get it to segue back it would still be acceptable.
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex==1) {
[self.navigationController popViewControllerAnimated:YES];
}
}
any ideas?
I'm guessing you've linked the button on your first view to the second view using a segue on the storyboard. To get it so that the UIAlertView pops up on the first view and then the segue is triggered depending on whether Yes or No is clicked you'll need to delete that segue and instead create it again by Ctrl-dragging from the first view (not the button) to the second view.
Create an IBAction for your button (if you haven't already) by Ctrl-dragging from your button to the views .h file and selecting Action. This should automatically create the method in the .m file - in that method you'll need to call your UIAlertView.
- (IBAction)buttonPressed:(id)sender
{
[myAlertView show];
}
Then the clickedButtonAtIndexMethod should be similar to what you had before. Instead of popping a controller (because the segue hasn't automatically happened) you'll want to call your segue using performSegueWithIdentifier.
- (void)alertView (UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
// They clicked Yes
if (buttonIndex==1)
{
[self performSegueWithIdentifier:#"YourSegueName" sender:self];
}
}
In regards to the clickedButtonAtIndex method not being called have you made the view a delegate of UIAlertView? So in your views .h file you need to have UIAlertViewDelegate like this:
#interface MyViewController : UIViewController <UIAlertViewDelegate>
I am trying to change where a button leads to depending on the selected row of a picker view. I am trying to display data depending on a certain year and I can make the picker display the available years and change a label to the corresponding year, but how can i make the "go" button I;ve created lead to the correct view controller?
Maybe you haven't had time to figure this out, maybe you have, but this is what I would do. You have a text field that you will populate with a picker, call this the "yearTextField." Then you have a button that you want to change the action depending on the year in question. Call this "myChangableButton." This is just for an example, you can call them anything you like. I put my initial view controller in a navigation view controller to have better control of the views. For this example I made two different years 1942, and 1971. They each have their own view controller that I named "FourtyTwoViewController" and "SeventyOneViewController" in my first view controller you will need to import these into the .m file. Like this..
#import "ViewController.h"
#import "FourtyTwoViewController.h"
#import "SeventyOneViewController.h"
Also, make sure when you drag out the new view controllers in the storyboard, that you name them as such. And don't forget to use that name as the Storyboard ID, found under the Identity inspector. Now for myChangableButton I made an action that will bring up whichever view controller you want based on the text in the yearTextField like this..
- (IBAction)myChangableButton:(id)sender
{
if ([_yearTextField.text isEqual: #"1942"])
{
FourtyTwoViewController *ftvc = [self.storyboard instantiateViewControllerWithIdentifier:#"FourtyTwoViewController"];
//[self presentViewController:ftvc animated:YES completion:nil];
[self.navigationController pushViewController:ftvc animated:YES];
}
else if ([_yearTextField.text isEqual: #"1971"])
{
SeventyOneViewController *sovc = [self.storyboard instantiateViewControllerWithIdentifier:#"SeventyOneViewController"];
//[self presentViewController:sovc animated:YES completion:nil];
[self.navigationController pushViewController:sovc animated:YES];
}
else
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Watch Out!" message:#"Put in valid date" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alert show];
}
}
The line of code that I commented out will bring up a modal transition, but I prefer a push since that gives you a great back button. That's it. I hope this helps you on your project. Make a comment if you have any questions, and good luck. And WELCOME! to SO!!
EDIT #1
Here is a sample of how I set the initialUrl in a viewcontroller that I pushed.
VideoViewController *vvc = [self.storyboard instantiateViewControllerWithIdentifier:#"VideoViewController"];
vvc.initialUrlString = urlString;
vvc.descriptionString = descriptionString1;
[self.navigationController pushViewController:vvc animated:YES];
I imported VideoViewController into the first view controller. And VideoViewController has two properties called initialUrlString and descriptionString. In the first view controller I have two properties called urlString and descriptionString1, these are set in the first view controller during another method and then passed into the second.
I have tried a few answers on this site, but none of them seem to relate to my problem
I have a MasterDetail app which has a two types of segues that I am using. When you press a button on the detail view, it uses a push segue and pushes another detail view onto that. In the new detailview (the one that was just pushed on) there is a button which calls up another UIView (form sheet) using a modal segue.
What I am trying to do is when the user selects a row, a UIAlertView will show up displaying a message, while at the same time (doesn't have to be at the same time) it dismisses the UIViewcontroller (modal) and goes back from the Viewcontroller that was pushed on. Basically, I need to be able to dismiss all viewcontrollers, one modal and one push (nav) so that the view returns to the original main screen that they started with.
I have the UIAlertView working fine and I can get the modal viewcontroller to dismiss by using [self.dismissViewControllerAnimated:YES completion:nil]; but I don't know how to dismiss the next Viewcontroller (which is in a navigation controller). Using this: [self.navigationController popToRootViewControllerAnimated:NO]; does not work.
Here is where I want to call the function to remove all views:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:urlWithIDAndChallenge];
NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];
UIAlertView *message = [[UIAlertView alloc] initWithTitle#"Started" message:#"The challenge has begun!" delegate:nil cancelButtonTitle:#"OK!" otherButtonTitles:nil];
[message show]
//right here is where I would normally dismiss the modal VC
//here is where I would like to dismiss all VC
}
If you want, in iOS 6.0 (and later) projects you can use an unwind segue. For example, you can:
In your top level view controller (the one you want to unwind to, not the controller you're going to unwind from), write an unwind segue method, in this case called unwindToTopLevel (personally, I find it useful if the segue bears some indication as to what the destination of the segue is, for reasons that will become apparent when we get to step 3, below):
- (IBAction)unwindToTopLevel:(UIStoryboardSegue *)segue
{
NSLog(#"%s", __FUNCTION__);
}
In the Interface Builder scene from which you will initiate the unwind, control ⌘-drag from the view controller icon to the exit icon to create the unwind segue:
Generally you'd define the segue from a button to the exit outlet (and you're done), but if you want to invoke the segue programmatically, you might want to create it between the controller and the unwind outlet, like shown above.
You'll get a little pop up that includes the name of your unwind segues (from the presenting controllers ... it's like magic):
If you're going to invoke that segue programmatically, you have to select that unwind segue in the document outline on the left side of the IB window and once you've done that, you can give the unwind segue a storyboard id:
I generally use the name of the the unwind segue for the storyboard id, but you can use whatever you want.
Now, having done that, your alert view can invoke the segue:
- (IBAction)didTouchUpInsideButton:(id)sender
{
[[[UIAlertView alloc] initWithTitle:nil message:#"go home" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"OK", nil] show];
}
#pragma mark - UIAlertViewDelegate
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex != [alertView cancelButtonIndex])
{
[self performSegueWithIdentifier:#"unwindToTopLevel" sender:self];
}
}
From the class you presented your modal view
call dismiss of modal and then perform selector after some delay and then do the
here is the sample code
//Write this in the class from where you presented a modal View.
//Call the function from modal class when you want to dismiss and go to root.
- (void) dismissAndGoToRoot {
[self dismissViewControllerAnimated:YES completion:nil];
[self performSelector:#selector(gotoRoot) withObject:nil afterDelay:0.50];
}
- (void)gotoRoot {
[self.navigationController popToRootViewControllerAnimated:NO];
}
Here you will call the function
//right here is where I would normally dismiss the modal VC
//here is where I would like to dismiss all VC
[self.parentViewController dismissAndGoToRoot];
If this does not work then take an instance variable of ParentViewController in modal class and assign when presenting modal view controller.
You could try replacing [self.dismissViewControllerAnimated:YES completion:nil]; with
self dismissViewControllerAnimated:YES completion:^{
[parentViewController.navigationController popToRootViewControllerAnimated:YES];
}
I believe parentViewController will point to the presenting view controller, and the block will cause the parent view controller's navigation controller to pop to the root view controller.
Following are the code for displaying alert in a view controller
-(void)saveProducts {
pData = [[JsonModel sharedJsonModel] prodData];
if ([pData count] == 0 && [self respondsToSelector:#selector(alertView:clickedButtonAtIndex:) ] ) {
alert = [[UIAlertView alloc]initWithTitle:#"Alert" message:#"No products against this category" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
}
[self.tblView reloadData];
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex == 0) {
[self.navigationController popViewControllerAnimated:YES];
[actInd stopAnimating];
}
}
But in slow network, alert will come slowly. If we click on back button of navigation bar at the mean time, pop the navigation controller and displaying alert in new view controller. But when i clicks on OK, app suddenly crashes with EXC_BAD_ACCESS error.
I also tried
didDismissWithButtonIndex
function instead of
clickedButtonAtIndex
But same error occurs. Please help me
It works normally if we didn't click on back bar button. Problem only arises when first view controllers alert displays in second view controller
EDIT
This is the error report
* -[ProductsListing alertView:didDismissWithButtonIndex:]: message sent to deallocated instance 0x8478280
EDIT
I understand the problem. When I click on back button, my alert delegate deallocates and delegate calling results error. How can I overcome this?
My best guess is that either 'self.navigationController' or 'actInd' have already been released. Also, your 'UIAlertView' leaks memory (unless you're using ARC). Profile the app using Instruments, selecting the "Zombies" tool and see what it comes up with.
I believe you have to change
[alert show];
to
if(self.view.window){
[alert show];
}
This way the alert appears only if the controller(the view) is still on screen.(why let the user see an alert from a previous screen?)
If you want the alert to appear anyway....then the "old" controller must inform the "new" one that a problem occurred...and now its the new controller's job to inform the user.
Or you can try changin this part
[self.navigationController popViewControllerAnimated:YES];
[actInd stopAnimating];
to
if(self.view.window){
[self.navigationController popViewControllerAnimated:YES];
[actInd stopAnimating]; // im not sure where the animation is...so not sure if this shoulb be in here or not
}
From what you described the problem here may be this(a wild guess)
[actInd stopAnimating];
called after the viewController is removed(popped).the actInd may not have a valid memory and hence it crashes
change the method content like this and check
if (buttonIndex == 0) {
[actInd stopAnimating];
[self.navigationController popViewControllerAnimated:YES];
}