am creating a application which is support all type of orientation, i added one UIView on the UIWindow.but on rotating the device the view which is added on the Window is not rotating. the view always showing default (Portrait). please help me to fix this problem ...
Thanks in advance
You need to add a UIViewController on your UIWindow.
UIView doesn't handle rotations, UIViewController does.
So, all you need is to create a UIViewController, which implements shouldAutorotateToInterfaceOrientation and sets this controller as a rootViewController to your UIWindow
Something like that:
- (void) makeWindow
{
UIViewController * vc = [[[MyViewController alloc] init] autorelease];
UIWindow * window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[window setRootViewController:vc];
[window makeKeyAndVisible];
}
#interface MyViewController : UIViewController
#end
#implementation MyViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor redColor];
//your view initialization here
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
return YES;
}
#end
Related
Using XCode 4.5 & iOS6
I created a UINavigationController with a UITabBar (NIBs) and the tab vertical positioning for the first launch is incorrect. When you click the second tab and again the first tab the vertical positioning is OK.
So ... How can I have the first tab properly positioned when the first run is done?
See wrong positioning:
http://img231.imageshack.us/img231/2159/badbf.png
My code:
AppDelegate.h
#interface bib_AppDelegate : UIResponder <UIApplicationDelegate, UITabBarControllerDelegate>
#property (strong, nonatomic) UIWindow *window;
#property (strong, nonatomic) UINavigationController *mainControllercode;
#property (strong, nonatomic) UITabBarController *tabBarController;
in the AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// change defaul selected icon tabbar color to orange
[[UITabBar appearance] setSelectedImageTintColor:[UIColor orangeColor]];
// Override point for customization after application launch.
UIViewController *viewController1 = [[agendaViewController alloc] initWithNibName:#"agendaViewController" bundle:nil];
UIViewController *viewController2 = [[messagesViewController alloc] initWithNibName:#"messagesViewController" bundle:nil];
self.tabBarController = [[UITabBarController alloc] init];
self.tabBarController.viewControllers = #[viewController1, viewController2];
self.mainControllercode = [[UINavigationController alloc] initWithRootViewController:self.tabBarController];
self.window.rootViewController = self.mainControllercode;
[self.window makeKeyAndVisible];
return YES;
}
agendaViewController.h
#import <UIKit/UIKit.h>
#interface agendaViewController : UIViewController
#end
agendaViewController.m
#import "agendaViewController.h"
#interface agendaViewController ()
#end
#implementation agendaViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
self.title = NSLocalizedString(#"Agenda", #"Agenda");
self.tabBarItem.image = [UIImage imageNamed:#"83-calendar"];
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
EDIT 1:
I created a sample project with Storyboards that you can see. I would like to have the same features without Storyboards, download this here:
http://www.freefilehosting.net/atestsb
Thanks
You are going about this the wrong way.
A UITabBarController should have a collection of UINavigationControllers which then have their root controller set to the primary Nib. Each tab then handles its own navigation stack.
You are currently putting the UITabBarController inside the root of the UINavigationController. This will cause issues as well as remove the tab bar when you move through the navigation stack.
Check out this link for more details to handle it programmatically :
http://www.xdracco.net/howto-implement-uinavigationcontroller-uitabbarcontroller-programmatically/
my app doesn't support rotation. But I want to present a QLPreviewController that supports rotation.
I present the QLPreviewController like this:
[self presentModalViewController:thePrevController animated:NO];
How can I do this?
Enable all rotations in your application plist file. This will make all views rotate irrespective of the settings in the view controller.
Then subclass your root UINavigationController as below, adding the rotation control code for iOS5 and 6 depending on your requirements:
I was updating an old app with MainWindow.xib, so I changed the class of the navigation controller in the xib file to CustomNavigationController. But in a more modern app with say a main menu, you'd instantiate the nav controller like this:
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
MainMenuVC *masterViewController = [[MainMenuVC alloc] initWithNibName:#"MainMenuVC" bundle:nil];
self.navigationController = [[CustomNavigationController alloc] initWithRootViewController:masterViewController];
self.window.rootViewController = self.navigationController;
[self.window makeKeyAndVisible];
Subclass UINavigationController
#import <UIKit/UIKit.h>
#interface CustomNavigationController : UINavigationController
#end
#import "CustomNavigationController.h"
#interface CustomNavigationController ()
#end
#implementation CustomNavigationController
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
-(BOOL)shouldAutorotate
{
return NO;
}
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
#end
Then subclass the QLPreview controller so you can override the rotation code which will enable rotation for the QLPreviewController only. The rest of the app with views pushed from your CustomNavContoller will not rotate as the CustomNavigationController is locked.
I added this interface and implementation at the top of the view controller where I wanted to present the QLPreviewController.
#interface RotatingQLPreviewController : QLPreviewController
#end
#implementation RotatingQLPreviewController
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskAllButUpsideDown;
}
-(BOOL)shouldAutorotate
{
return YES;
}
#end
Then present your QLPreviewController using your subclass.
RotatingQLPreviewController *preview = [[RotatingQLPreviewController alloc] init];
preview.dataSource = self;
[self presentViewController:preview
animated:YES
completion:^(){
// do more stuff here
}];
This method should work for other modal views that you want to rotate, but I haven't tried it.
I implemented this method in the latest app I'm working on and works in both iOS5 and 6.
Hope it helps.
I'm a beginner with Xcode and Objective-C, i want to make a view controller in code without a nib file and shape it how i want. Currently with this very simple code I can't seem to even change the background color because of EXC_BAD_ACCESS.
I read on internet it is something with memory management but I can't seem to find the fix for this. Pieces of my code:
AppDelegate.h
#import <UIKit/UIKit.h>
#import "DefaultViewController.h"
#class DefaultViewController;
#interface AppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
UIViewController *rootViewController;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet UIViewController *rootViewController;
#end
AppDelegate.m
#synthesize window = _window;
#synthesize rootViewController = _rootViewController;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UIViewController *rvc = [[DefaultViewController alloc] init];
self.rootViewController = rvc;
[rvc release];
[self.window addSubview:self.rootViewController.view];
// Override point for customization after application launch.
[self.window makeKeyAndVisible];
return YES;
}
- (void)dealloc
{
[_window release];
[_rootViewController release];
[super dealloc];
}
The view controller I made via, right click -> new file and UIViewController subclass without xib! In the loadView I only try this:
self.view.backgroundColor = [UIColor redColor];
The problem could be that the rootViewController doesn't have an initialized view. Hard to tell, since you don't show the code of the DefaultViewController. It could also be another error in DefaultViewController.
FWIW, you have two obsolete ivars:
#interface AppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
UIViewController *rootViewController;
}
You can delete these, since you synthesize _window and _rootViewController and never use the above.
There are a few issues with your code. But first the key problem you are getting EXC_BAD_ACCESS is because you are calling self.view.backgroundColor inside the loadView. If you override loadView, you must construct your view hierarchy inside the method. By not creating a view hierarchy in that method you are calling backgroundColor on a view that does not exist. Instead completely remove the loadView method or comment it out and move self.view.backgroundColor into the viewDidLoad method. (Remember even an empty loadView method will be a problem, you need to remove it or comment it out)
Second.. change your code to
self.rootViewController = rvc; to self.window.rootViewController = rvc;
BTW, once you add a view controller you don't need to add the view of the rootViewController as a subview to the window again. Assigning a view controller to the rootViewController property installs the view controller's view as the content view of the window.
Third. When you are initializing DefaultViewController you do
UIViewController *rvc = [[DefaultViewController alloc] init];
dont do that, instead do
DefaultViewController *rvc = [[DefaultViewController alloc] init];
Change the code so it's
self.window.rootViewController = rvc;
[self.window makeKeyAndVisible];
return YES;
What's inside your DefaultViewController? If you are not using a nib file, did you implement -(void)loadView ?
You should call:
UIViewController *rvc = [[DefaultViewController alloc]
initWithNibName:#"yournib" bundle:nil];
to load the NIB view. Otherwise, your rvc.view will be nil.
Sorry, I overlooked.
The answer is: you should not call self.view.backgroundColor = [UIColor redColor]; within - (void)loadView since self.view is nil firstly at this stage. He has to show that he has correctly created at least self.view = [[UIView alloc] init] in loadView.
I've been trying to understand View Controllers and Views and even after watching some of the classes on iTunesU, I'm still having some trouble implementing them programmatically. I'm hoping someone can clarify a bit.
So I'm trying to create a UIViewController which in turn creates its view.
The program is broken up in the following classes:
ProgramNameAppDelegate.h and .m
ApplicationRootViewController.h and .m
From the AppDelegate, I create the UIWindow and UIViewController. Partial code goes like this:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
_window = [ [UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
if (!_window)
{
[self release];
return NO;
}
_rootViewController = [ [ApplicationRootViewController alloc] init];
if (!_rootViewController)
{
NSLog(#"No _rootViewController");
[self release];
return NO;
}
[_window addSubview:[_rootViewController view]];
[_window makeKeyAndVisible];
return YES;
}
In the ApplicationRootViewController I call init. My UIView is created in loadView as such:
- (void)loadView
{
NSLog(#"In loadView");
[super loadView];
CGRect _frame = [[UIScreen mainScreen] applicationFrame];
UIView* _rootView = [[UIView alloc] initWithFrame:_frame];
[_rootView setBackgroundColor:[UIColor redColor]];
self.view = _rootView;
return;
}
The problem I'm having is apparently the program is creating the view, however, it is never displaying the view that I created until the app resigns active. Once I go out of the app and come back in, the view is there. I have tried several other things, but it always behaves the same.
I would eventually like to for the controller to create the view from a subclassed UIView.h and .m file.
Thanks,
Kevin
From the docs:
Your custom implementation of loadView
method should not call super.
So, get rid of [super loadview] and it should work;)
Also, if you want to use a custom view (Subclass of UIView). Alloc/Init using initWithFrame: and when referring self.view from uiviewcontroller you will have to cast it like so:
[(MyView *)self.view myMethod];
As simple as that ;)
EDIT:
Suppose you make a class like this:
//MyView.h
#interface MyView : UIView{
...
}
- (void) doSomething:(NSString *)string;
#end
//MyView.m
#import MyView.h
#implementation MyView
... write your implementation here
#end
then in the UIViewController,
in loadView
do:
//don't forget to #import "MyView.h"
-(void) loadView{
MyView *myView = [[MyView alloc] initWithFrame:CGRectMake(...)];
self.view = (UIView *)myView;
[myView release];
}
then when referring your view somewhere else in the controller:
- (void) viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
[(MyView *)self.view doSomething:#"something"];//1
[self.view setBackgroundColor:[UIColor greenColor]];//2
}
In //1 you should cast because your are calling doSomething: method (or it could be a property as well), which is declared/defined in MyView and not in UIView. If you don't cast you will get a warning but it will work.
In //2 you don't need to cast since setBackgroundColor: is a method defined in UIView class ;)
Objective-C is very flexible and will allow to cast many things, so you have to be careful because casting is like telling the compiler: "trust me, is not a UIView, is MyVIew" and the compiler will obey you. But if you were wrong your app will crash when attempting to call doSomething: because it does not exist in UIView.
I'm attempting to load a Modal View Controller (1st) from a Modal View Controller (2nd). While it sounds complicated, it probably isn't.
The 1st controller is actually a UIWebView which is initialized in the loadView method of the .m file:
- (void)loadView {
// Initialize webview and add as a subview to LandscapeController's view
myWebView = [[[UIWebView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]] autorelease];
//CGRect forceframe = CGRectMake(0, 0, 480, 320);
//myWebView = [[[UIWebView alloc] initWithFrame:forceframe] autorelease];
myWebView.scalesPageToFit = YES;
myWebView.autoresizesSubviews = YES;
myWebView.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
myWebView.delegate = self;
self.view = myWebView;
}
Then in viewDidLoad:
- (void)viewDidLoad {
[super viewDidLoad];
// Load HTML file as an NSURL request
[self.myWebView loadHTMLString:updated_html baseURL:nil];
// Invoke the covering modal view on condition
if (some_condition) {
landscapeCoverController = [[UIViewController alloc] initWithNibName:#"LandscapeCoverController" bundle:[NSBundle mainBundle]];
[self presentModalViewController:landscapeCoverController animated:YES];
[landscapeCoverController release];
}
The intended 2nd Modal View Controller (landscapeCoverController) is initialized with a NIB that I set up in IB.
My intended objective, is to conditionally cover up the UIWebView with the "LandscapeCoverController" view, which will have some buttons and interactivity which will result in the 2nd Modal View being dismissed.
Why isn't my landscapeCoverController loading? Any thoughts greatly appreciated!
Also...the 1st Modal View controller (LandscapeViewController) .h looks like:
#class LandscapeCoverController;
#interface LandscapeViewController : UIViewController <UIWebViewDelegate> {
UIWebView *myWebView;
LandscapeViewController *landscapeCoverController;
}
#property (nonatomic, retain) UIWebView *myWebView;
#property (nonatomic, retain) LandscapeViewController *landscapeCoverController; // Modal view controller
and...the 2nd Modal View controller (landscapeCoverController) viewDidLoad does nothing:
// NIB initialized in LandscapeViewController.m viewDidLoad:
- (void)viewDidLoad {
[super viewDidLoad];
}
as I think the
landscapeCoverController = [[UIViewController alloc] initWithNibName:#"LandscapeCoverController" bundle:[NSBundle mainBundle]];
[self presentModalViewController:landscapeCoverController animated:YES];
[landscapeCoverController release];
statement should handle initialization and loading of the controller...
You are declaring landscapeCoverController as an instance of LandscapeViewController, and allocating it as a UIViewController. This is most likely your problem (probably the first one, as you aren't calling any methods specific to LandscapeViewController). Also, since landscapeCoverController is an instance variable, you don't really need to release it after presentModalViewController. Try to pick more dissimilar class names. It will save you from confusion like this in the future.