I don't want to dismiss popover controller when i touch any view. Is it possible?
I am using following code for displaying popover controller.
UIPopoverController* popoverCamera;
popoverCamera= [[UIPopoverController alloc] initWithContentViewController:videoRecorder];
[popoverCamera presentPopoverFromRect:CGRectMake(cropRectangleButton.frame.origin.x,cropRectangleButton.frame.origin.y,0,0) inView:innerview permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
NSLog(#"start recording-->%d",[videoRecorder startVideoCapture]);
[videoRecorder startVideoCapture];
[self presentModalViewController:videoRecorder animated:YES];
[videoRecorder release];
Yes it is possible. Implement the following delegate method:
- (BOOL)popoverControllerShouldDismissPopover:(UIPopoverController *)popoverController
{
return NO;
}
Hope this might help you.
From the Link disable dismissal of uipopoverview controller
When displayed, taps outside of the popover window cause the popover to be dismissed automatically. To allow the user to interact with the specified views and not dismiss the popover, you can assign one or more views to the passthroughViews property. Taps inside the popover window do not automatically cause the popover to be dismissed. Your view and view controller code must handle actions and events inside the popover explicitly and call the dismissPopoverAnimated: method as needed.
implement the pop over delegate
/* Called on the delegate when the popover controller will dismiss the popover. Return NO to prevent the dismissal of the view.
*/
- (BOOL)popoverControllerShouldDismissPopover:(UIPopoverController *)popoverController;
func popoverShouldClose(_ popover: NSPopover) -> Bool {
return false
}
Try this where you dont want to dismiss the popUp:-
[popOverController dismissPopoverAnimated:NO];
Hope this helps :)
Related
I am an iOS rookie. I have a Table View embedded in a Navigation Controller. Another Table View is also embedded in a Navigation Controller. The first Table View, ChecklistsView, presents the second Table View, ItemDetailView. The ChecklistView's Navigation Controller '+' button opens the ItemDetailView scene. Tapping on the Cancel button of the ItemDetailView closes the ItemDetailView, but gives the message noted above. Here is the code for the Cancel method:
- (IBAction)cancel
{
[self.delegate itemDetailViewControllerDidCancel:self];
}
And here is the delegate method used in the cancel method:
- (void)itemDetailViewControllerDidCancel:(ItemDetailViewController *)controller
{
[self dismissViewControllerAnimated:YES completion:nil];
}
Any suggestions would be appreciated. I have reviewed other posts about this warning, but they are above my level of expertise.
You shouldn't have the delegate dismiss the viewController.
Rather you should dismiss it by using the .presentingViewController property on the presentedViewController.
Like so:
[self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
I disagree with AdamG. What you're doing is correct; Apple also uses this design, where the delegate dismisses the controller (check out MFMessageComposeViewController).
Back to the question, if I understand you correctly, and that you have the following structure (pardon the terms, but you'll get the gist):
A UINavigationController at the top
ChecklistsViewController is the navigation controller's root view controller
ItemDetailViewController as a modal view controller
ChecklistsViewController is the delegate for ItemDetailViewController
It's just the implementation details in your case.
- (void) itemDetailViewControllerDidCancel: (ItemDetailViewController*) controller
{
[controller dismissViewControllerAnimated: YES
completion: nil];
}
I know there's like 3-5 similar questions here, but non of the answers solves my problem.
I have a ViewController that opens a modal (table)view controller, which opens another one. Both modal view controllers are in fact table view controllers. I'm trying to dismiss both of them from the second one. I tried every accepted answer on similar question, none of them worked for me.
I tried
[self dismissModalViewControllerAnimated:true]
[self.parentViewController dismissModalViewControllerAnimated:true]
[self.parentViewController.parentViewController dismissModalViewControllerAnimated:true]
[self.presentingViewController dismissModalViewControllerAnimated:true]
[self.presentingViewController.presentingViewController dismissModalViewControllerAnimated:true]
When I try options 2, 3 and 5, nothing happens at all. When I use options 1, and 4, I see dismiss modal view animation and the underlying view itself for a moment, and then everything goes back to the second modal view (this time without animation).
I'm starting to think that this have something with the fact that I use tableViewControllers for modal views.
Btw, I'm dismissing modal views in didSelectRowAtIndexPath.
Try this:-
When you dismiss your SecondView set a BOOL flag variable in app delegate file and check that variable in your FirstView's viewWillAppear method whether SecondView was open and close or not. If so, then [self dismissModalViewControllerAnimated:true]
typical model view controller behavior would suggest that you dismiss the modal view controller from the calling view controller rather than from self. not a hard and fast rule, but good practice.
to accomplish this, create a protocol:
#protocol MyModalViewControllerDelegate
- (void)modalViewControllerDidFinish;
#end
and make both the parentViewController and FirstModalViewController be implemntors of this protocol.
#interface FirstModalViewController <MyModalViewControllerDelegate>
then in both FirstModalViewController.h and SecondModalViewController.h, add:
#property id<MyModalViewControllerDelegate> modalViewControllerDelegate
in both parentViewController and FirstModalViewController, right before calling presentModalViewController:... , set the following:
modalViewControllerAboutToAppear.modalViewControllerDelegate = self;
[self presentModalViewController:modalViewControllerAboutToAppear animated:YES];
next, in the SecondModalViewController, in the code where you determine that the item needs to be dismissed, call
[self.modalViewControllerDelegate modalViewControllerDidFinish];
now, in FirstModalViewController, implement the following:
- (void)modalViewControllerDidFinish:(MyModalViewController*)controller {
[self dismissModalViewControllerAnimated:YES]
[self.modalViewControllerDelegate modalViewControllerDidFinish];
}
and finally, in the parent view controller, you should be able to perform:
- (void)modalViewControllerDidFinish:(MyModalViewController*)controller {
[self dismissModalViewControllerAnimated:YES]
}
Since I don't use delegate files, I did the following:
To FirstView add field
BOOL mClose;
To FirstView add method
- (void)close
{
mClose = YES;
}
To FirstView method viewDidAppear add
if (mClose)
{
[self dismissModalViewControllerAnimated:YES];
}
To FirstView method which opens SecondView add
[secondView closeWhenDone:self];
To SecondView add field
FirstView *mParent;
To SecondView add method
- (void)closeWhenDone:(FirstView*)parent
{
mParent = parent;
}
To SecondView method which closes it add
[mParent close];
to show a modal uiview out of my mainView I use:
[self presentModalViewController:myController animated:YES];
and in MyController I close that view with:
[self dismissModalViewControllerAnimated:YES];
But how can I know in the mainView that the modal was finished (to redraw my table)?
Currently I set a local variable to YES in my mainView after starting the modal view an react on viewWillAppear:
[self presentModalViewController:myController animated:YES];
_reloadTableData = YES;
-(void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
if (_reloadTableData) {
_reloadTableData = NO;
[_tableView reloadData];
}
}
Is there a better way to do so ?
Generally speaking, it's not appropriate to dismiss the modal view by the modal view itself.
Instead, you should set your main view as the delegate of the modal view. When you modal view finishes its task, it can let its delegate know and let its delegate dismiss it. This is the very common so-called delegate design pattern in Objective-C.
btw, you may want to consult with some code samples to gain a better understanding of this delegate pattern. I suggest you take a look at one of Xcode's default templates - the Utility Application template. It has a very succinct and simple and straightforward delegate structure built inside.
I need to add this to my dismiss button :-
[self dismissModalViewControllerAnimated:YES];
[self release];
else
[self.view removeFromSuperview];
I thought
if( self.navigationController.modalViewController ) {
would work be it nevers true
A couple of things:
1) You shouldn't ever release yourself in an object. If you're presenting a modal view controller, you should perform the release there since the view controller will now be retained by the view controller's .modalViewController property:
(In the parent):
UIViewController *someViewController = [[UIViewController alloc] init];
[self presentModalViewController:someViewController animated:YES];
[someViewController release];
2) The parent will store its child modal view controller in .modalViewController. The child will have its .parentViewController property set in this case. If the view has been added as a subview, its .superview property will be set. These are not mutually exclusive, however, so be careful. Generally speaking, UIViewControllers are intended to host full-screen views, and if you're adding the view as a subview, you should ask yourself if the view should just be a UIView subclass, and move the logic into the parent view controller.
That said, I suppose you could check your case (assuming you don't present modal view controller and add as a subview simultaneously):
if (self.parentViewController) {
[self dismissModalViewControllerAnimated:YES];
} else if (self.view.superview) {
[self.view removeFromSuperview]
}
In the latter superview case, the view controller will still be hanging around, so you'd need to let the other view controller know via delegate method or something to release you. In the first case, if you have released the presented view controller already as I described above, it will be released automatically when the parent view controller sets its .modalViewController property to nil.
Normally for a "dismiss" button I would call a method in the controller that presented the modal controller (use a delegate), not try to dismiss the modal view controller from within itself. I don't quite get what youre trying to do though, but that [self release] looks bad. I don't think you ever want to release self like that.
Try this in you modal viewcontroller:
- (IBAction)close:(id)sender {
[self.parentViewController dismissModalViewControllerAnimated:YES];
}
Then just connect the button's action to that method.
I added a modalView to my App, everything working fine, but on closing the modal, the whole modalView jumps about 1-2 centimeters to left while it disappears.
I did not find any reason for it yet, so here is the code regarding modal:
AppController:
- (void) showNameModal:(Player *)player
{
namesModal = [[PlayerModalView alloc] init];
namesModal.delegate = self;
namesModal.player = player;
UINavigationController *navCon = [[UINavigationController alloc] initWithRootViewController:namesModal];
navCon.modalPresentationStyle = UIModalPresentationFormSheet;
[self presentModalViewController:navCon animated:YES];
[navCon release];
[namesModal release];
}
- (void)didDismissModalView
{
[self dismissModalViewControllerAnimated:YES];
}
ModalView:
- (void)dismissView:(id)sender
{
[delegate didDismissModalView];
}
called via navigation buttons as well ass via keyboard by
[self dismissView:nil];
As you can see, there is nothing special in it, could be taken from a manual actually.
What happens in detail:
Modal appears in center of screen, slides in from the bottom. centered all time.
i can handle some actions in the modalView, it stays centered.
now, dismissing the view makes it jumping to the left, than slides out.
Since it's a forced landscape-right app (currently), I was only able to notify the left-jump.
Any ideas how to get this jumping away?
Thanks
Try this,
- (void)didmissView:(id)sender
{
[self.navigationController didmissModelViewControllerAnimated:YES];
}
You are not modally presenting an instance of PlayerModalView but rather a UINavigationController. The left jerk you see is most likely the default animation of the navigation controller attempting a slide transform to the (non-existant) previous view.
It doesn't sound like you need a navigation controller for the PlayerModalView. Instead, you should create an ordinary view controller for it.
This solution seems to work well: Modal View Controller with keyboard on landscape iPad changes location when dismissed
To simplify resigning the first responder (if finding it is difficult), you can just call
[self.view endEditing:YES];
[self dismissModalViewControllerAnimated:YES];
The problem is that the UIViewController you're showing modally doesn't allow the orientation you're presenting it in, so when it disappears, it will do that in a direction that it considers "allowed".
Add this to the UIViewController for you modal view:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}