I am trying to use this code inside an UINavigationController :
http://developer.apple.com/library/ios/#samplecode/PhotoScroller/Introduction/Intro.html
In storyboard :
I embed PageViewController in Navigation Controller.
I change Topbar to "NavigationBar".
I add a title : "ImageView" to NavigationBar.
I add a storyboard id to PageViewController and NavigationController.
In ImageViewScrollView.m :
- (void)displayTiledImageNamed:(NSString *)imageName size:(CGSize)imageSize
I change this line :
_zoomView = [[UIImageView alloc] initWithFrame:(CGRect){CGPointZero, imageSize }];
By these :
CGPoint navPoint = CGPointMake(0, 45);
_zoomView = [[UIImageView alloc] initWithFrame:(CGRect){navPoint, imageSize}];
And I change these lines too :
- (CGPoint)minimumContentOffset
{
return CGPointZero;
}
By these :
- (CGPoint)minimumContentOffset
{
CGPoint navPoint = CGPointMake(0, 45);
return navPoint;
}
And I don't see navigationBar when I use iOS Simulator. Replacing CGPointZero is not enough.
What's wrong ?
I found an easier way to put photoscroller inside UINavigationController.
I just added in appdelegate.h :
#property (nonatomic, retain) UINavigationController *navController;
and in appdelegate.m :
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// kick things off by making the first page
PhotoViewController *pageZero = [PhotoViewController photoViewControllerForPageIndex:0];
if (pageZero != nil)
{
// assign the first page to the pageViewController (our rootViewController)
UIPageViewController *pageViewController = (UIPageViewController *)self.window.rootViewController;
pageViewController.dataSource = self;
[pageViewController setViewControllers:#[pageZero]
direction:UIPageViewControllerNavigationDirectionForward
animated:NO
completion:NULL];
self.navController = [[UINavigationController alloc] initWithRootViewController:pageViewController];
[[self window] setRootViewController:_navController];
}
return YES;
}
Related
I had a viewController which contains video view and UITabBarController. UITabBarController contains 3 viewControllers with UINavigationController. The problem is that the frame of first UINavigationController is good (0,20,width,height), but the other two navigationController has wrong frame (0,0,width,height). Status bar is showing, so I don't know what's wrong with them.
Here i create TabBarController :
#interface EEMenuTBC ()
#end
#implementation EEMenuTBC
- (void)viewDidLoad {
[super viewDidLoad];
EEFavoritesVC *favotiteVC = [[EEFavoritesVC alloc] initWithNibAsClassName];
UINavigationController *favotiteNC = [[UINavigationController alloc] initWithRootViewController:favotiteVC];
[favotiteVC.tabBarItem setImage:[UIImage imageNamed:#"favoritesMenuDisabled"]];
[favotiteVC.tabBarItem setTitle:#"Favourites"];
EESearchTVC *searchVC = [[EESearchTVC alloc] initWithNibAsClassName];
UINavigationController *searchNC = [[UINavigationController alloc] initWithRootViewController:searchVC];
[searchVC.tabBarItem setImage:[UIImage imageNamed:#"searchMenuDisabled"]];
[searchVC.tabBarItem setTitle:#"Search"];
EESettingsTVC *settingsVC = [[EESettingsTVC alloc] initWithNibAsClassName];
UINavigationController *settingsNC = [[UINavigationController alloc] initWithRootViewController:settingsVC];
[settingsVC.tabBarItem setImage:[UIImage imageNamed:#"settingsMenuDisabled"]];
[settingsVC.tabBarItem setTitle:#"Settings"];
self.viewControllers = #[favotiteNC, searchNC, settingsNC];
self.tabBar.items[0].selectedImage = [UIImage imageNamed: #"favoritesMenuEnabled"];
self.tabBar.items[1].selectedImage = [UIImage imageNamed: #"searchMenuEnabled"];
self.tabBar.items[2].selectedImage = [UIImage imageNamed: #"settingsMenuEnabled"];
for(UIView *temp in self.tabBar.subviews) {
[temp setExclusiveTouch:YES];
}
}
-(BOOL)prefersStatusBarHidden {
return NO;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
- (void)goToRootVC {
if (_delegateMenuTBC && [_delegateMenuTBC respondsToSelector:#selector(EEMenuTBCDelegateGoToRootVC)]) {
[_delegateMenuTBC EEMenuTBCDelegateGoToRootVC];
}
}
#end
In other ViewController i doing
_menuTBC = [[EEMenuTBC alloc] initWithNibName:#"EEMenuTBC" bundle:nil];
_menuTBC.view.frame = self.view.frame;
And in favotiteVC navigation look's good, and all other's 2 navigations has no spacing from status bar
P.S
First of all, I added my UITabBarController as a child to UIViewController. The first UINavigationController from UITabBarController has right frame (0,20,width,height) , but others 2 UINavigationsControllers, has wrong frame (0,0,width, height). I think they don't have status bar, and I checked that method -prefersStatusBarHidden isn't call from all UIViewControllers which contains in UITabBarController
Setup: 'VC1' creates 'NavigationVC' with a root view controller 'VC2' and presents it modally with presentation style UIModalPresentationFormSheet. 'VC2' shows up inside the nav controller in the middle of the screen with the correct size.
Issue: As I continue to push view controllers onto the modal NavVC I would like them to resize. NSLog of my preferredContentSize in each view controller that is pushed verifies that my constraints are correct and the sizes are in fact different. However I have experimented extensively and have not figured out how to change the size of the modal after it has been presented.
#implementation VC1()
- (void) viewDidLoad{
VC1* vc1 = [self getNextVC];
NavVC* navVC = [[UINavigationViewController alloc] initWithRootViewController:vc1];
[navVC setModalPresentationStyle:UIModalPresentationFormSheet];
[self presentViewController:navVC animated:YES completion:nil];
}
#end
#implementation NavVC()
- (CGSize) preferredContentSize{
CGSize size = [[self topViewController] preferredContentSize];
return size;
}
#end
#implementation VC2()
- (CGSize) preferredContentSize{
CGSize size = [[self view] systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
return size;
}
#end
I’ve spent some time dealing with the same problem. Pushing the view controller on modal navigation controller for iOS8 resulted in having the view controller with the same size as the root view controller, while for iOS7 this second view controller had the default size of modal form sheet (540.f, 620.f). The only working solution, I could come up with so far, for both iOS7 and iOS8 is as follows:
ViewController1.m
#interface ViewController1 ()
#end
#implementation ViewController1
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
self.navigationController.view.superview.bounds = CGRectMake(0, 0, VC1_WIDTH, VC1_HEIGHT);
}
- (void)nextTapped:(id)sender {
ViewController2 *vc2 = [storyboard instantiateViewControllerWithIdentifier:#"ViewController2"];
[self.navigationController pushViewController:vc2 animated:NO];
// call after push
self.navigationController.view.superview.bounds = CGRectMake(0, 0,VC2_WIDTH,VC2_HEIGHT);
}
#end
Presenting ViewController1:
ViewController1 *vc1 = [storyboard instantiateViewControllerWithIdentifier:#"ViewController1"];
UINavigationController *navVC = [[UINavigationController alloc] initWithRootViewController:vc1];
navVC.modalPresentationStyle = UIModalPresentationFormSheet;
[self presentViewController:navVC animated:NO completion:nil];
ViewController2.m
#import "ViewController2.h”
#interface ViewController2 ()
#end
#implementation ViewController2
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
self.navigationController.view.superview.bounds = CGRectMake(0, 0, VC2_WIDTH, VC2_HEIGHT);
}
- (void)nextTapped:(id)sender {
ViewController3 *vc3 = [storyboard instantiateViewControllerWithIdentifier:#"ViewController3”];
[self.navigationController pushViewController:vc3 animated:NO];
self.navigationController.view.superview.bounds = CGRectMake(0, 0,VC3_WIDTH,VC3_HEIGHT);
}
- (void)backTapped:(id)sender {
self.navigationController.view.superview.bounds = CGRectMake(0, 0,VC1_WIDTH,VC1_HEIGHT);
[self.navigationController popViewControllerAnimated:NO];
}
#end
ViewController3.m
#import "ViewController3.h”
#interface ViewController3 ()
#end
#implementation ViewController3
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
self.navigationController.view.superview.bounds = CGRectMake(0, 0, VC3_WIDTH, VC3_HEIGHT);
}
- (void)backTapped:(id)sender {
self.navigationController.view.superview.bounds = CGRectMake(0, 0,VC2_WIDTH,VC2_HEIGHT);
[self.navigationController popViewControllerAnimated:NO];
}
#end
Please note, if you’re adding text input fields to those view controllers pushed on modal navigation controller, for iOS8, keyboard presentation and dismissal will automatically resize them to the wrong size. Unfortunately I still don’t have proper fix for this issue.
I know this question has been asked before here iOS 6 shouldAutorotate: is NOT being called. But my scenario is a bit different.
Initially, on application launch I load a viewController like
self.window.rootViewController = self.viewController;
and When this view is loaded I am using a custom tabBar view (inherited from UIView) which has 5 UINavigationController for each tab. The code of this viewController Class is:
\\\ .h File
#protocol tabbarDelegate <NSObject>
-(void)touchBtnAtIndex:(NSInteger)index;
#end
#class tabbarView;
#interface ViewController : UIViewController <tabbarDelegate>
#property(nonatomic,strong) tabbarView *tabbar;
#property(nonatomic,strong) NSArray *arrayViewcontrollers;
#property(nonatomic,strong) UINavigationController * navigation1;
#property(nonatomic,strong) UINavigationController * navigation2;
#property(nonatomic,strong) UINavigationController * navigation3;
#property(nonatomic,strong) UINavigationController * navigation4;
#property(nonatomic,strong) UINavigationController * navigation5;
#end
and m file is
- (void)viewDidLoad
{
[super viewDidLoad];
CGFloat orginHeight = self.view.frame.size.height- 60;
_tabbar = [[tabbarView alloc]initWithFrame:CGRectMake(0, orginHeight, 320, 60)];
_tabbar.delegate = self;
[self.view addSubview:_tabbar];
_arrayViewcontrollers = [self getViewcontrollers];
[self touchBtnAtIndex:0];
}
-(void)touchBtnAtIndex:(NSInteger)index \\This delegate method is called on every custom tabBar button clicked.
{
UIView* currentView = [self.view viewWithTag:SELECTED_VIEW_CONTROLLER_TAG];
[currentView removeFromSuperview];
UINavigationController *viewController = [_arrayViewcontrollers objectAtIndex:index];
viewController.view.tag = SELECTED_VIEW_CONTROLLER_TAG;
viewController.view.frame = CGRectMake(0,0,self.view.frame.size.width, self.view.frame.size.height- 50);
[self.view insertSubview:viewController.view belowSubview:_tabbar];
}
-(NSArray *)getViewcontrollers
{
FirstViewController *firstController = [[FirstViewController alloc]initWithNibName:#"FirstViewController" bundle:nil];
SecondViewController *secondController = [[SecondViewController alloc]initWithNibName:#"SecondViewController" bundle:nil];
ThirdViewController *thirdController = [[ThirdViewController alloc]initWithNibName:#"ThirdViewController" bundle:nil];
ForthViewController *forthController = [[ForthViewController alloc]initWithNibName:#"ForthViewController" bundle:nil];
FifthViewController *fifthController = [[FifthViewController alloc]initWithNibName:#"FifthViewController" bundle:nil];
navigation1 = [[UINavigationController alloc] initWithRootViewController:firstController];
navigation2 = [[UINavigationController alloc] initWithRootViewController:secondController];
navigation3 = [[UINavigationController alloc] initWithRootViewController:thirdController];
navigation4 = [[UINavigationController alloc] initWithRootViewController:forthController];
navigation5 = [[UINavigationController alloc] initWithRootViewController:fifthController];
NSArray* tabBarItems = [[NSArray alloc] initWithObjects:navigation1,navigation2,navigation3,navigation4,navigation5, nil];
return tabBarItems;
}
I have also implemented UINavigationController's category for rotation as:
#implementation UINavigationController (autoRotation)
-(BOOL)shouldAutorotate {
return [[self.viewControllers lastObject] shouldAutorotate];
}
-(NSUInteger)supportedInterfaceOrientations {
return [[self.viewControllers lastObject] supportedInterfaceOrientations];
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
return [[self.viewControllers lastObject] preferredInterfaceOrientationForPresentation];
}
My Problem is that only supportedInterfaceOrientations method is called and shouldAutorotate is never called. The main Window's rootViewController is ViewController class, not any UINavigationController or UITabBarController. What I am doing wrong? Please help me.
If you add these to your root view controller:
- (BOOL)shouldAutorotate
{
NSLog(#"ViewController shouldAutorotate super=%d", [super shouldAutorotate]);
return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
NSLog(#"ViewController supportedInterfaceOrientations");
return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight;
}
you will see that the system is constantly sending both of these messages. Your code there can query the active Navigation Controller to see what values to return if you wish.
Also, I'm no fan of using a category to override these on a UINavigation Controller - that it works is somewhat of a fluke and importing some other library that does the same could cause unexpected consequences later on. Just create a really simple subclass and over ride both of these. I've been doing that with both UITabBarController and UINavigationController since iOS4 and never had an issue.
I want to create a UIView for a UITabBarController
Here is my code for the .h file :
#interface TE : UIViewController <UITabBarControllerDelegate>{
UITabBarController *tabBarController;
}
#property (nonatomic,retain) UITabBarController *tabBarController;
#end
The viewDidLoad method:
UIViewController *testVC = [[T1 alloc] init];
UIViewController *otherVC = [[T2 alloc] init];
NSMutableArray *topLevelControllers = [[NSMutableArray alloc] init];
[topLevelControllers addObject: testVC];
[topLevelControllers addObject: otherVC];
tabBarController = [[UITabBarController alloc] init];
tabBarController.delegate = self;
[tabBarController setViewControllers:topLevelControllers animated:NO];
tabBarController.selectedIndex = 0;
self.view = tabBarController.view;
This creates the tab bar controller, but when I click on a tab bar item, I get an error:
Thread1:Program receive signal: SIGABRT
Edit: I solved the problem by downloading and modifying the version of http://www.iphonedevcentral.com/create-uitabbarcontroller/
You say above that you don't want to create the tabBarController in the appDelegate. Why not? Where else would you create it? The tabBarController has to be the root view controller and cannot be a child of any other view controller.
Btw, make sure you implement:
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController {
NSUInteger tabIndex = [tabBarController.viewControllers indexOfObject:viewController];
if (viewController == [tabBarController.viewControllers objectAtIndex:tabIndex] ) {
return YES;
}
return NO;
}
Subclass UITabBarController
Override the - (void) loadView method and include the following code
MyCustomViewControllerOne* ctrl1 = [[[MyCustomViewControllerOne alloc] initWithNibName#"MyViewControllerOne" bundle: nil] autorelease];
UIViewController* ctrl2 = [[[UIViewController alloc] init] autorelease];
MyCustomControllerTwo* ctrl3 = [[[UIViewController alloc] initWithObject: myObj] autorelease];
ctrl1.title = #"First tab";
ctrl2.title = #"Second tab";
ctrl3.title = #"Third tab";
ctrl1.tabBarItem.image = [UIImage imageNamed:#"tab_image1.png"];
ctrl2.tabBarItem.image = [UIImage imageNamed:#"tab_image2.png"];
ctrl3.tabBarItem.image = [UIImage imageNamed:#"tab_image3.png"];
[self setViewControllers: #[ctrl1, ctrl2, ctrl3]];
That's pretty much it.
Change self.view = tabBarController.view; to
[self.view addSubview:tabBarController.view]; And it works correctly
Trying changing
self.view = tabBarController.view;
to
[self.view addSubview:tabBarController.view];
See if that helps.
Also try placing this in your -(void)loadView method
- (void)loadView {
UIView *mv = [[UIView alloc] initWithFrame:CGRectMake(0.0, 100.0, 320.0, 480.0)];
self.view = mv;
[mv release];
}
The reason you probably are experiencing a black screen is because you haven't initialized your UIView properly.
#Mehdi, just make your TE a UITabBarController instead of a UIViewController which then has a TabBarController in it. Makes it all the more easy to manage your TabBarController. To respond to some others who have indicated that you can have only one TabBarController as the window's rootViewController. That is not the case. A UITabBarController can be instantiated in multiple places where you need a second level menu navigation. Have a TabBar within a TabBar would not make sense, but having a left Navigation Menu and then having a TabBar on each menu item would make sense.
I'm trying to develop an app (game) with this architecture:
Main view is a naviagtioncontroller based with navbar hidden
in Main view I need a light info
button to show a options/credits
flipsideview
this flipsideview must have another
navigationcotroller with a right bar
button to a "Done" system button
The problem is that the flipsideview doesn't show the done button and it seems to show the Main navigation controller...
This is the code.
AppDelegate:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
self.window.rootViewController = self.navigationController;
[self.window makeKeyAndVisible];
return YES;
}
Main View (loaded from a XIB). Extract only of showInfo:
-(IBAction) showInfo:(id)sender {
FlipSideViewController *controller = [[FlipSideViewController alloc] initWithNibName:#"FlipSideView" bundle:nil];
controller.delegate = self;
controller.title = #"Info";
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:controller];
navController.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
navController.navigationBar.barStyle = UIBarStyleBlackOpaque;
UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonItemStyleDone
target:controller action:#selector(done:)];
navController.navigationItem.rightBarButtonItem = doneButton;
controller.navController = navController;
[self presentModalViewController:navController animated:YES];
[doneButton release];
[controller release];
[navController release];
}
- (void)flipsideViewControllerDidFinish:(FlipSideViewController *)controller {
[self dismissModalViewControllerAnimated:YES];
}
FlipSideView. In the XIB I've only a blank view with outlet linked to the UIViewController view.
#protocol FlipsideViewControllerDelegate;
#interface FlipSideViewController : UIViewController {
id <FlipsideViewControllerDelegate> delegate;
UINavigationController *navController;
}
#property (nonatomic,assign) id <FlipsideViewControllerDelegate> delegate;
#property (nonatomic,retain) UINavigationController *navController;
-(IBAction)done;
#end
#protocol FlipsideViewControllerDelegate
- (void)flipsideViewControllerDidFinish:(FlipSideViewController *)controller;
#end
}
Implementation file...
- (void)viewDidLoad
{
[super viewDidLoad];
self.navController.navigationItem.title = #"Pippo";
}
#pragma mark - User Methods
- (IBAction)done {
[self.delegate flipsideViewControllerDidFinish:self];
}
The result is:
Main View showing without navigation
bar
Click on info button
Flipsideview showing with animation
and navigation bar with title "Info" and not "pippo
and not "Done" button on the right...
Where am I wrong??
Don't you get two navigationBar with navigationItems on FlipsideViewController? I am fighting with this bug now.