in my iOS project I use InAppSettings. This is missing a delegate in the modal view controller for willDismiss.
So when the modal view gets dismissed I want a method to be called in my main view controller. How can I do this? Is there a method in a view controller that gets triggered whe the view is in focus again?
You could try something like this
BOOL settingsLaunched = NO;
-(void)presentInAppSettingsViewController
{
//Show the settings modal view controller here
//Set our flag
settingsLaunched = YES;
}
-(void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
if(settingsLaunched)
{
//Your code here
}
}
these will get called on the view after dismissing a modal dialog it presents
- (void) viewWillAppear
- (void) viewDidAppear:(BOOL)animated
Related
I have implemented SidebarDemo project from Appcode and then modified Storyboard with Login screen, now when I start my application Login Screen come which is correct and I dont want Pan Gesture on Login screen and I am trying to remove it from code below
- (void)viewDidLoad
{
[super viewDidLoad];
[self.navigationController.view removeGestureRecognizer:self.revealViewController.panGestureRecognizer];
}
- (void) viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
for (UIGestureRecognizer *recognizer in self.navigationController.view.gestureRecognizers) {
[self.navigationController.view removeGestureRecognizer:recognizer];
}
self.revealViewController.panGestureRecognizer.cancelsTouchesInView = NO;
// NSArray* gestureRecognizers = [self.navigationController.navigationBar gestureRecognizers];
// for (UIGestureRecognizer *gestureRecognizer in gestureRecognizers) {
// if ([gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]]) {
// gestureRecognizer.enabled = YES;
//
// break;
// }
// }
//[self.revealViewController.panGestureRecognizer removeTarget:self action:#selector(revealToggle:)];
}
But Pan Gesture is still swiping on Login but when I go to internal screen and comes on Login Screen so it get remove, but why isnt it removing from the first time of application start
My Storyboard Image as below
As I understood, your login screen shouldn't be the front view of SWRevealViewController, cause you don't need a sidebar in it. Create a modal segue from your login view controller to the reveal view controller and perform it when user has logged in successfully. Delete the segue from reveal view controller to login's navigation controller, but create one from reveal to survey choice (don't forget to set it's identifier to sw_front and embed survey choice controller in navigation controller). Create segues from sidebar's logout button to login's navigation view controller and perform it when user wants to logout.
To be more clear, I add photo of my own app, that has similar thing.
http://i.stack.imgur.com/f3nWe.png
I have this code which works fine except for if you enter the view controller from portrait then it stays in portrait. I need it once it goes to the view controller to go to landscape and stay in landscape.
- (NSUInteger)supportedInterfaceOrientations {
if (self.isFlexiGram) {
return UIInterfaceOrientationMaskLandscape;
} else {
return UIInterfaceOrientationMaskAll;
}
}
- (BOOL)shouldAutorotate {
return YES;
}
I'm changing my container view controller with the following methods
#pragma mark - Container Controller Methods
- (void)presentDetailController:(UIViewController*)detailVC{
//0. Remove the current Detail View Controller showed
if(self.currentDetailViewController){
[self removeCurrentDetailViewController];
}
//1. Add the detail controller as child of the container
[self addChildViewController:detailVC];
//2. Define the detail controller's view size
detailVC.view.frame = [self frameForDetailController];
//3. Add the Detail controller's view to the Container's detail view and save a reference to the detail View Controller
[self.containerView addSubview:detailVC.view];
self.currentDetailViewController = detailVC;
//4. Complete the add flow calling the function didMoveToParentViewController
[detailVC didMoveToParentViewController:self];
}
- (void)removeCurrentDetailViewController{
//1. Call the willMoveToParentViewController with nil
// This is the last method where your detailViewController can perform some operations before neing removed
[self.currentDetailViewController willMoveToParentViewController:nil];
//2. Remove the DetailViewController's view from the Container
[self.currentDetailViewController.view removeFromSuperview];
//3. Update the hierarchy"
// Automatically the method didMoveToParentViewController: will be called on the detailViewController)
[self.currentDetailViewController removeFromParentViewController];
}
I've tried the preferredInterfaceOrientationForPresentation but that doesn't get called because I'm not using presentViewController.
I've tried the following questions
Forcing UIInterfaceOrientation changes on iPhone
IOS 6 force device orientation to landscape
I've also gone through apple documentation
https://developer.apple.com/library/ios/featuredarticles/ViewControllerPGforiPhoneOS/RespondingtoDeviceOrientationChanges/RespondingtoDeviceOrientationChanges.html
I'm trying to make a modal view controller in my app delegate (I created a function called showLoginView). But whenever I try to call it I get a warning in XCode:
Warning: Attempt to present <PSLoginViewController: 0x1fda2b40> on <PSViewController: 0x1fda0720> whose view is not in the window hierarchy!
Here's the method code:
- (void)showLoginView
{
PSLoginViewController *loginViewController = [[UIStoryboard storyboardWithName:#"MainStoryboard" bundle:NULL] instantiateViewControllerWithIdentifier:#"PSLoginViewController"];
[self.window.rootViewController presentViewController:loginViewController animated:NO completion:nil];
}
How can I add the view to the window hierarchy? Or maybe I'm doing something very wrong?
You can't display a modal view controller from the appDelegate. You need to display a modal ViewController from whichever viewController is currently displaying full-screen. In other words, you need to put that code into your root view controller, or whichever one you want to display the modal vc from...
Also, you'll want to use the method "presentModalViewController" to present the modal. You can set properties on the modal vc such as:
vC.modalPresentationStyle = UIModalPresentationFormSheet;
vC.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self presentModalViewController:vC animated:YES];
You can actually present a modal view Controller from the AppDelegate as long as you detect the current visible viewController and take care of the case where you current controller is a navigationController.
Here is what I do:
UIViewController *activeController = [UIApplication sharedApplication].keyWindow.rootViewController;
if ([activeController isKindOfClass:[UINavigationController class]]) {
activeController = [(UINavigationController*) activeController visibleViewController];
}
[activeController presentModalViewController:loginViewController animated:YES];
UIViewController *activeController = [UIApplication sharedApplication].keyWindow.rootViewController;
if ([activeController isKindOfClass:[UINavigationController class]])
{
activeController = [(UINavigationController*) activeController visibleViewController];
}
else if (activeController.modalViewController)
{
activeController = activeController.modalViewController;
}
[activeController presentModalViewController:vc animated:YES];
I ran into this problem on iOS 7 - the key to making any of the proposed solutions work was to call
[self.window makeKeyAndVisible];
in your AppDelegate.
After that call, presenting a modal view from the window's rootViewController worked.
Another reason for that warning can be that you want to present a view controller from an instance which is not the top most view controller.
So first you have to get the topmost UIViewController and using this instance to call presentViewController:
UIViewController *root = [UIApplication sharedApplication].keyWindow.rootViewController;
while (root.presentedViewController) {
root = root.presentedViewController;
}
You can NSLog(#"%#", self.window.rootViewController), and see what the rootViewController really is.
I came into this problem, when the rootViewController is a normal UIViewController.
Replace it with a UINavigationController, wish it will help.
Faced this issue while trying to present controller from the call of delegate of other controller . i.e : show search filter with delegate , once done back to my controller and receive data via the delegate then present controller , all I had to do is to dispatch the present code cause while in a delegate you're in another thread , that's why you're presenting on your view from main thread another controller from that other thread , so have to go back to main thread , just put the presenting code like this :
dispatch_async(dispatch_get_main_queue(), ^{
[self presentViewController:searchVC animated:true completion:nil];
});
Hope this helps !
I have a Master-Detail application. Both master and detail are UITableViewControllers. In detail scene I created a button and call to it action
- (IBAction)completeTaskButtonPressed:(id)sender {
[[self delegate] removeCompletedTask:self.indexFromRow controller:self];
}
In Master VC implementation I have method
- (void) removeCompletedTask:(NSInteger)index controller:(DetailViewController *) controller {
[self.dataController.masterTasksList removeObjectAtIndex:index];
[self.tableView reloadData];
[self dismissViewControllerAnimated:YES completion:NULL];
}
These method must delete selected row and go back to the Master View. The problem is that it removes the row but DONT dismiss detail view. Any help will be usefull.
Sounds like your master-detail setup involves a navigation controller. If you want to dismiss the detail view in the same manner as would tapping the Back button, use [self.navigationController popViewControllerAnimated:YES].
try
[self dismissModalViewControllerAnimated:YES];
or you could try:
[self.navigationController popViewControllerAnimated:YES].
You are popping the view controller which is the opposite of pushViewController:
This may sound a newbie question, however I'm new t iOS dev.
I've a view pushed in navigationController, let say it is the 3rd pushed view.
In that view I set self.navigationController.delegate = self;. I've changed delegate because I need to handle case when user goes to previous view i.e. pops from current view.
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
if ([[viewController class] isEqual:[MainViewController class]]) {
...
}
}
It works OK, but when I pop the current view and press navigation back button again (i.e. switching to first pushed view) I'm getting bad access error.
So what I'm missing ?
What is the correct way to handle navigation back button press ?
It's because navigation controller sends a message to popped and deallocated view controller, you have to set the delegate each time you do the popping and pushing. Also add self.navigationController.delegate = nil; to dealloc method of your viewController.
Place below in the Viewcontroller in which you assigning self.navigationController.delegate = self
-(void) viewWillDisappear:(BOOL) animated
{
[super viewWillDisappear:animated];
if ([self isMovingFromParentViewController])
{
if (self.navigationController.delegate == self)
{
self.navigationController.delegate = nil;
}
}
}