ok, i cant find the method called by UIViewController that presents a new view.
i have an app based on UINavigationController. Once i come to a view showing details of the object, i have 1 toolBar at the bottom so i can give some options to user.
When he press on barButtomItem, i want to show a new view but not changing the navigationbar, so if i press back button he goes back from detail view and not from new option.
i know method pushViewController but does not work as i want.
thx in advance!
edit: just to be a more bit more clear if i call
[[self navigationController]pushViewController:loteCompraViewController animated:YES];
i get a new view, related to the new controller but it also changes the navigationbar and that is not good for me.
Give your view controller of the "view showing details of the object" two methods: isShowingOverlayView and dismissOverlayView. In isShowingOverlayView, return YES if you're showing the "new view" because "he press on barButtomItem". In dismissOverlayView, hide the "new view".
Then make your own subclass of UINavigationController. In your subclass, override popViewControllerAnimated: to use those methods of your object-detail view controller, like this:
- (UIViewController *)popViewControllerAnimated:(BOOL)animated
{
if ([self.topViewController respondsToSelector:#selector(isShowingOverlayView)]
&& [(id)self.topViewController isShowingOverlayView])
{
[(id)self.topViewController dismissOverlayView];
return nil;
} else {
return [super popViewControllerAnimated:YES];
}
}
Use this subclass instead of the standard UINavigationController.
Related
This questions look repeated, but I din't got proper solution for my problem. In my case, Once I clicked back button I want to hide the navigation bar. For e.g. View1 pushed view2, view2 will have navigation bar,once I clicked back it brings me back to view 1 it should not contain navigation bar I need to hide it. I tried with viewWillDisappear method in view 2 to hide, it worked but if I have more view and I'm pushing each view from view1 if I click back button,navigation bar should hide in view1. So is anyway is there to know in view 1 itself that other view is popped. I tried viewwillappear method in view1 its not called. What can I do here.?
This method got called once I initially load view1, not after popping view2..
- (void) viewWillAppear : (BOOL)animated
{
[root_obj.navigationController setNavigationBarHidden:YES animated:YES];
}
This is how I am pushing view 2..
[root_obj.navigationController pushViewController:view2 animated:NO];
thanks in Advance
i think, u have forgot to call viewWillAppear: method of super class.
-(void) viewWillAppear : (BOOL)animated
{
[super viewWillAppear:animated];
[root_obj.navigationController setNavigationBarHidden:YES animated:YES];
}
Why don't you hide the NavigationBar in View1's ViewDidAppear method
Edit
I am not sure what the problem with your code but you can do these kind of things in ViewWillAppear or ViewDidAppear methods for more information UIViewController Class Reference and check ViewWillAppear or ViewDidAppear
How can I manage the user selection on the "more" view of a UITabBar? I have this code to manage the UITabBarItems selections:
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController {
if (!(viewController == tabBarController.moreNavigationController)) {
int index = tabBarController.selectedIndex;
[[DataManager sharedInstance] setCurrentTabbarIndex:index];
}
}
It works fine for the visible UITabBarItems, but when the user select some item from the "more" view I never get informed about that. Is there some way to catch the user item selection of the "more" view? Thanks!
The "more" view of a UITabBarController is handled separately from the other views. Apple's discussion on this subject says the following:
[The 'moreNavigationController'] property always contains a valid More navigation controller, even if a More button is not displayed on the screen. You can use the value of this property to select the More navigation controller in the tab bar interface or to compare it against the currently selected view controller.
Do not add the object stored in this property to your tab bar interface manually. The More controller is displayed automatically by the tab bar controller as it is needed. You must also not look for the More navigation controller in the array of view controllers stored in the viewControllers property. The tab bar controller does not include the More navigation controller in that array of objects.
Judging from that I would think that you can do something like:
int index = tabBarController.selectedIndex;
if (tabBarController.selectedViewController ==
tabBarController.moreNavigationController) {
index = -1; //assign some placeholder index for the "More" controller
}
A very late answer for a very old question, but here it is anyway, in case someone stumbles upon this.
The solution is to assign yourself as the delegate of the "more" navigation controller. You already have a class that adopts the UITabBarControllerDelegate protocol, so the .h file might look like this:
#interface MyDelegate : NSObject <UITabBarControllerDelegate, UINavigationControllerDelegate>
{
}
Wherever you are assigning your class as delegate, do this:
- (void) assignDelegate:(MyDelegate)myDelegate toTabBarController:(UITabBarController*)tabBarController
{
tabBarController.delegate = myDelegate;
tabBarController.moreNavigationController.delegate = myDelegate;
}
And finally, in your delegate class add this method:
- (void) navigationController:(UINavigationController*)navigationController didShowViewController:(UIViewController*)viewController animated:(BOOL)animated
{
// add code to handle the event
}
Note that none of your delegate methods are invoked when you change tabs programmatically.
The best approach I've found for this problem is to become the delegate for the UITableView which is the topViewController in the UITabBarController.moreViewController.
Implementing the didSelectRowAtIndexPath should solve the problem!
The best (and most secure) implementation for this is described by Stuart Sharpe in his blog: http://initwithstyle.net/2014/02/making-more-of-the-more-view/
Whatever view is being selected will receive viewWillAppear:animated:
Provide this in every view that's controlled by your tab bar, and you can thus extract the identity of the user's selection even when made from a "More" controller.
You can save the tab bar state right in this method, or you can provide your views with a reference back to the tab bar and notify it.
basically I want to know if the view controller I'm in is the root view controller or not.
If its not I want to put a button in the nav bar that says "back" (as if it were a proper back button - this bit I know how to do).
Before you ask, I have removed all the titles from my view controllers - I didn't want them to show up on my navigation bar... its very complicated - but this means that when I go through my navigation stack none of the pushed view controllers have a back button. :/
Thanks
Tom
if ( self != [self.navigationController.viewControllers objectAtIndex:0] )
{
// Put Back button in navigation bar
}
You can also try:
if (self.navigationController.viewControllers.count == 1) {
NSLog(#"self is RootViewController");
}
Here's a swift version:
// Only works if checking from within the NavigationController:
navigationController?.viewControllers.first == self
// Works if you only have a reference to the NavigationController:
navigationController?.topViewController == navigationController?.viewControllers.first
In my Main Window IB file I have a TabBarController and the first controller is a Navigation Controller. When I push my detail view (after pressing a cell in a table view) I want to push my detail view and display a tool bar instead of the tab bar. The problem is that when I try
tabBar.hidden = visible;
in my detail view controller (viewDidLoad) the tabbar dissapears before the animation between the first view and the detail view is done.
What i want to achieve can be seen in the native photo app when pressing on one of the images from a gallery. There the tabbar moves out with the animation of the first view.
How do I achieve this?
Thanks in advance
check out the 'hidesBottomBarWhenPushed' property on your detail's page subclass of UIViewController
either override this method
- (BOOL)hidesBottomBarWhenPushed
{
return YES;
}
or i'm guessing this would work the same:
self.hidesBottomBarWhenPushed = YES;
as far as showing the toolbar try:
- (void)viewWillAppear:(BOOL)animated
{
[self.navigationController setToolbarHidden:NO animated:YES];
}
and on the way out
- (void)viewWillDisappear:(BOOL)animated
{
[self.navigationController setToolbarHidden:YES animated:YES];
}
So I have a modal view displaying in my app that has a little info for the user to fill out. The problem is that when the device is rotated, some animation occurs, but only in the frame. The form itself does not rotate. All the autorotate options are set to YES. I am displaying it when the user clicks on a field in a popover. This makes me suspect it has something to do with that but I am not sure. It is bizzare because if the device is in either view and then the modal window is displayed, it is fine. It only happens when the device is rotated in the modal view. Does anyone have any idea what may be causing this behavior when the device is rotated? Thanks!
Here is a snippet that is handled in the popover view controller:
if (currentLevel == 1 && businessOrLocation == 0){
if(tbsViewController == nil)
tbsViewController = [[BusinessFilteredViewController alloc] initWithNibName:#"BusinessFilteredView" bundle:[NSBundle mainBundle]];
NSMutableArray *tempBusiness = [[NSMutableArray alloc] init];
for (id theKey in appDelegate.groupedBusiness) {
NSMutableArray *tempArr = [appDelegate.groupedBusiness objectForKey:theKey];
[tempBusiness addObject:tempArr];
}
tbsViewController.businessOrLocation = businessOrLocation;
tbsViewController.modalPresentationStyle = UIModalPresentationFullScreen;
tbsViewController.modalTransitionStyle = UIModalPresentationFullScreen;
[self presentModalViewController:tbsViewController animated:YES];
}
I ran into this problem as well. The fundamental problem is that popover controllers cannot present modal views—it seems that case wasn’t properly considered or designed for. In my situation, it was easy enough to work around. I just extended the delegate protocol for my popover-hosted view controller. The main view sets itself up as the delegate to the popover view, and takes responsibility for displaying and dismissing the modal views the user requests from within the popover.
Since I already had a delegate protocol to cleanly dismiss the popover view when the user clicks “done” it was only a small stretch to get autorotation working the way I wanted it to. Here are some snippets:
#protocol InfoViewControllerDelegate <NSObject>
#optional
// Implement this to close the info view once the user clicks done.
- (void)infoViewDidFinish:(InfoViewController *)view;
// Implement this method if the delegate launched us as a popup view and must therefore
// take responsibility for diplaying help.
- (void)infoViewDidRequestHelp:(InfoViewController *)view;
#end
And in my main iPad view which presents this popup view:
#pragma mark - InfoViewControllerDelegate methods
- (void)infoViewDidFinish:(InfoViewController *)view {
[self hideInfo:self];
}
- (void)infoViewDidRequestHelp:(InfoViewController *)view {
[self hideInfo:self]; // Close the info view first
HelpViewController *help = [[HelpViewController alloc] init];
help.delegate = self;
[self presentModalViewController:help animated:YES];
[help release];
}
To make life simple for cases where I am launching the info view outside of a popup view (for example, on the iPhone, it is a simple modal view), it checks to see if the delegate handles the modal subviews, and if not, handles them itself. That way I didn’t need to change the iPhone base controller at all, since autorotation already worked fine there. Here’s the “Help” button action in the info view controller, showing how I did that:
- (IBAction)help:(id)sender {
if ([delegate respondsToSelector:#selector(infoViewDidRequestHelp:)]) {
[delegate infoViewDidRequestHelp:self];
} else {
HelpViewController *help = [[HelpViewController alloc] init];
help.delegate = self;
[self presentModalViewController:help animated:YES];
[help release];
}
}
With this code in place, my entire interface autorotates smoothly on both devices, whether or not popup views were involved.
Just so i understand correctly... You are displaying a popover and inside that popover if the user taps a certain element then you are displaying a full screen modal view controller? Vie never tried that before and it seems odd for two reasons.
First it seems jarring to the user in my opinion. The popover gives you a nice, integrated UI and the modal takes you away.
More importantly though, your popover view controller doesn't really have authority over the whole screen so presenting a full screen modal from a popover just seems inherently wrong.
I would suggest you display a nav controller in the popover controller and instead of presenting the new view controller modally over the whole screen just push it on to the nav controller in the popover and keep the user inside the popover.
If that doesn't really work for you, then I would suggest reviewing your UI needs and redesigning the layout.
I am guessing that you implemented - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation in BusinessFilteredViewController and returns YES
Could you check that you add more than 1 subviews to application window . If so, try to create container UIViewController for all viewControllers that you want to add to window.