Someone gave me this code, is it correct? if so how do i use it? I am a noob so can you explain in simpler terms for me? Thanks guys :)
- (IBAction)OpenActionSheetButton:(id)sender {
UIActionSheet *actionsheet = [[UIActionSheet alloc]initWithTitle:#"There is no going back,
are you sure???" delegate:self cancelButtonTitle:#"Cancel"
destructiveButtonTitle:#"Continue" otherButtonTitles:nil, nil];
[actionsheet showInView:self.view];}
-(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:
(NSInteger)buttonIndex
{
if(buttonIndex == 0)
{
UIViewController *controller = [self.storyboard
instantiateViewControllerWithIdentifier:#"storyboardViewIdentifier"];
//storyboardViewIdentifier is the ViewController identifier you specify in the
storyboard
//PUSH
[self.navigationController pushViewController:controller animated:YES];
//Modal
[self presentViewController:controller animated:YES completion:Nil];
}
}
I'm not sure with the case with storyboard, but with the case of XIB, I need to set UINavigationController object as rootviewcontroller, so that I can push from one viewcontroller to another, I think in storyboard it may be the same, if so, see these answers, first and second to set navigation controller as rootviewcontroller in storyboard environment.
Related
I have a plus button in my primary view controller of a UISplitViewController and i want to present something modally in my detail view, just like apple does when adding a new contact in address book in iPad. I have tried everything but nothing. I managed to do it but when i am trying to embed my presented view controller into a UINavigation controller then my presented controller covers the full screen. Any suggestions? Here is my code:
UINavigationController *navController = [self.splitViewController.viewControllers lastObject];
DetailTableViewController *controller = (DetailTableViewController *)navController.topViewController;
controller.definesPresentationContext = YES;
controller.providesPresentationContextTransitionStyle = YES;
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
EditTableViewController *etvc = (EditTableViewController *)[storyboard instantiateViewControllerWithIdentifier:#"EditTableViewController"];
UINavigationController *nav = [[UINavigationController alloc]initWithRootViewController:etvc];
etvc.patient = patient;
if (IDIOM == IPAD)
{
etvc.modalPresentationStyle = UIModalPresentationCurrentContext;
[controller presentViewController:nav animated:YES completion:nil];
} else {
[self presentViewController:nav animated:YES completion:nil];
}
I just successfully solved this problem by creating a custom segue whose implementation is:
- (void)perform
{
UIViewController *ctrl = self.sourceViewController;
UIViewController *dest = self.destinationViewController;
dest.modalPresentationStyle = UIModalPresentationCurrentContext;
[ctrl presentViewController:dest animated:YES completion:nil];
}
I'm seeing the behavior I want by invoking this segue from my detail view controller on the modal view I want to overlay it.
I think where your code is going haywire is here:
etvc.modalPresentationStyle = UIModalPresentationCurrentContext;
I think it should be:
nav.modalPresentationStyle = UIModalPresentationCurrentContext;
Though I haven't tested it.
Note that the Apple docs suggest that modalPresentationStyle is ignored on the iPhone (or on "horizontally compact devices"), so your "IS_IPAD" check may be redundant.
Hope this helps!
I have the following code to load a UIImagePickerController which works fine.
UIImagePickerController *mediaUI = [[UIImagePickerController alloc] init];
mediaUI.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
mediaUI.mediaTypes = [[NSArray alloc] initWithObjects: (NSString *) kUTTypeMovie, nil];
mediaUI.delegate = self;
[controller presentModalViewController: mediaUI animated: YES];
return YES;
I would like to load a modal view with some help information on how to use the UIImagePickerController:
UIStoryboard *storyboard = self.storyboard;
HelpViewController *svc = [storyboard instantiateViewControllerWithIdentifier:#"HelpViewController"];
[self presentViewController:svc animated:YES completion:nil];
How can I display the UIImagePickerController after the user dismisses the HelpViewController view?
Don't be tempted to move directly from HelpViewController to UIImagePickerController, you need to get there via your mainViewController.
Let's put your code into a method...
- (void) presentImagePicker {
UIImagePickerController *mediaUI = [[UIImagePickerController alloc] init];
mediaUI.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
mediaUI.mediaTypes = [[NSArray alloc] initWithObjects: (NSString *) kUTTypeMovie, nil];
mediaUI.delegate = self;
[controller presentModalViewController: mediaUI animated: YES];
return YES;
}
(Note that presentModalViewController:animated is depracated since ~iOS5, and you should really replace it with
[controller presentViewController:mediaUI animated:YES completion:nil];)
Let's call your viewControllers mainVC, helpVC and imageVC. There are two ways you can implement this.
method 1 - performSelector
The quick-and-slightly-dirty solution is to do this in your helpVC's dismiss button method:
- (IBAction)dismissHelpAndPresentImagePicker:(id)sender
{
UIViewController* mainVC = self.presentingViewController;
[mainVC dismissViewControllerAnimated:NO completion:
^{
if ([mainVC respondsToSelector:#selector(presentImagePicker)])
[mainVC performSelector:#selector(presentImagePicker)];
}];
}
It's slightly dirty because you need to ensure that presentImagePicker is implemented in mainVC - the compiler will give you no warnings if it is not. Also you are running a completion block after it's object has been dismissed, so there's no certainty it's going to work (in practice, it does, but still...)
Note that you have to assign the pointer self.presentingViewController's to a local variable (mainVC). That's because when helpVC is dismissed, it's presentingViewController property is reset to nil, so by the time you get to run the completion block you cannot use it. But the local variable mainVC is still valid.
method 2 - protocol/delegate
The clean way to do this is to use a protocol in helpVC to declare a delegate method, and make mainVC the delegate. This way the compiler will keep track of everything and warn you if it is not correctly implemented.
Here are the steps to do that:
In helpVC.h add this protocol above the #interface section:
#protocol helpVCDelegate
- (void) dismissHelpAndPresentImagePicker;
#end
In helpVC.h interface section declare a property for its delegate:
#property (nonatomic, weak) id <helpVCDelegate> delegate;
(the <helpVCDelegate> tells the compiler that the delegate is expected to conform to the protocol, so it will have to implement dismissHelpAndPresentImagePicker)
In helpVC.m your method can now look like this:
- (IBAction)dismissHelpAndPresentImagePicker:(id)sender
{
[self.delegate dismissHelpAndPresentImagePicker];
}
In MainVC, when you create HelpVC (=svc in your code), set MainVC as it's delegate:
HelpViewController *svc = [storyboard instantiateViewControllerWithIdentifier:#"HelpViewController"];
svc.delegate = self;
[self presentViewController:svc animated:YES completion:nil];
And be sure to implement the delegate method dismissHelpAndPresentImagePicker
- (void) dismissHelpAndPresentImagePicker
{
[self dismissViewControllerAnimated:NO completion:^{
[self presentImagePicker];
}];
}
Personally I would always use method 2. But I offered up a that solution earlier today to a similar question, and the questioner seemed to think protocol/delegate was overcomplicated. Maybe my answer just made it seem so, I have tried to simplify it here.
I have a button in my interface declared in .h file
#interface UserProfileVC : UIViewController <UIImagePickerControllerDelegate>{
IBOutlet UIButton *camera;
}
#property (nonatomic,retain) IBOutlet UIButton *camera;
-(IBAction)cameraPress:(id)sender;
And in my .m file i have:
-(IBAction)cameraPress:(id)sender{
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
// [picker setDelegate:self];
[picker setAllowsEditing:YES];
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
[self presentModalViewController:picker animated:YES];
[picker release];
}
But I have this error:
*** -[UserProfileVC performSelector:withObject:withObject:]: message sent to deallocated instance 0x7bc2a40
Can someone help me? I can't understand what is the mistake.
Thanks
As per the code from ur last comment,
-(void)showDetails:(id)sender{
NSLog(#"Annotation Click");
details= [[UserProfileVC alloc] initWithNibName: #"Details" bundle:nil ];
details.Nome=note.title;
addNavigationController = [[UINavigationController alloc] initWithRootViewController:details];
[self.navigationController presentModalViewController:addNavigationController animated:YES];
}
I can suggest you following.
If you look at the UIViewController class reference document, you will find below notes
presentModalViewController:animated:
Presents a modal view managed by the given view controller to the user. (Deprecated. Use presentViewController:animated:completion: instead.)
So I would suggest you to use presentViewController:animated:completion. I dont find it relevant to error "message sent to deallocated instance" but still check if u could solve your problem.
Also I dont know Why u wrote this line
addNavigationController = [[UINavigationController alloc] initWithRootViewController:details];
If you simply want to show UserProfileVC in the current UINavigationController then I would suggest you to remove addNavigationController line & write only
[self.navigationController presentViewController:details animated:YES completion:NULL];
i wanted to display the detail view after tapping the right button on the annotation of mapview in xcode but i could not get the view to display ,
my code:
- (void)showDetails:(id)sender
{
[self.navigationController setToolbarHidden:YES animated:NO];
[self.navigationController pushViewController:self.detailViewController animated:YES];
}
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
static NSString* BridgeAnnotationIdentifier = #"bridgeAnnotationIdentifier";
MKPinAnnotationView* customPinView = [[[MKPinAnnotationView alloc]
initWithAnnotation:annotation reuseIdentifier:BridgeAnnotationIdentifier] autorelease];
customPinView.pinColor = MKPinAnnotationColorPurple;
customPinView.animatesDrop = YES;
customPinView.canShowCallout = YES;
UIButton* rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
NSLog(#"%#",rightButton);
[rightButton addTarget:self
action:#selector(showDetails:)
forControlEvents:UIControlEventTouchUpInside];
customPinView.rightCalloutAccessoryView = rightButton;
return customPinView;//[kml viewForAnnotation:annotation];
}
The showDetails method gets called but cannot push the detailViewController to the top ,
[self.navigationController pushViewController:self.detailViewController animated:YES];
this code should have pushed detail view to the top and displayed the detailView but it does not please ,
any help would be greatly appreciated , what i wanted to do is when anybody taps on the right button of annotation on the mapview ,i wanted to display a detail view , thanking you in advance..
There is no target/action required, there is a delegate method that gets called when the callout accessory view is tapped: mapView:annotationView:calloutAccessoryControlTapped:
Thank you , for your help i am able to open the detailViewController by changing my showDetails method
- (void)showDetails:(id)sender
{
detailViewController *dvController = [[detailViewController alloc] initWithNibName:nil bundle:nil];
[self presentModalViewController:dvController animated:YES];
[dvController release];
dvController = nil;
}
My DetailView of a SplitView has a Map with Annotations. Upon clicking an Annotation the entire window (and not just the DetailView) should go to another view. Unfortunately that doesn't work.
This is how I'm creating my NavigationController in my AppDelegate
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:self.viewController];
[self.window addSubview:navigationController.view];
This is how I'm creating the SplitView
left = [[MapSplitViewLeft alloc] initWithStyle:UITableViewStylePlain];
right = [[MapViewController alloc] init];
splitViewController = [[UISplitViewController alloc] init];
splitViewController.viewControllers = [NSArray arrayWithObjects:left,right, nil];
self.view = splitViewController.view;
left.right = right;
[left release];
[right release];
And that's what's being called when clicked on an Annotation:
- (void)showDetails:(id)sender {
NSLog(#"Yes it works");
VenueViewController *vviewcontroller = [[VenueViewController alloc]
initWithNibName:#"VenueViewController" bundle:[NSBundle mainBundle]];
AppDelegate *del = (AppDelegate *)[UIApplication sharedApplication].delegate;
[del.navigationController pushViewController:vviewcontroller animated:YES];
}
When I click on the Annotation I only get "Yes it works" but nothing else is happening.
Thanks so much for any advise.
Every UIViewController has the property "navigationController". Try with your current ViewController to push the new Viewcontroller.
[self.navigationController pushViewController:vviewcontroller animated:YES];
edit: Sorry, you mean the entire window! I think that would not work.
edit2: Maybe this answer can help you how to add a view over window in uiviewcontroller But i think thats that view is not on your navigationController-Stack