I am new to iOS development, but have had an extensive crash course recently (BNR guid to iOS Programming). I am working on modally adding views to an app. I currently do not have a View Controller, so my AppDelegate's application:didFinishLaunchingWithOptions method looks as follows:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
MyUIView *map = [[MapSurface alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
//this one does not work: MyUIView *map = [[MapSurface alloc] initWithFrame:CGRectMake(0, 0, 256, 256)];
[map setBackgroundColor:[UIColor grayColor]];
[[self window] addSubview:map];
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}
After the view loads, I make a call to add a subview, but I cannot set the frame size using CGRectMake. It doesn't show up on screen. The only thing I have found to work is using the screen size, but this is not what I want. Here is the code for adding this subview:
UIImage *image = [[UIImage alloc] initWithCGImage:img];//img is a CGImageRef
UIImageView *view = [[UIImageView alloc] initWithImage:image];
CGRect b = CGRectMake(0, 0, 256, 256);
//[view setFrame:b];//nothing shows on screen
//[view setBounds:b];//nothing shows on screen
//[view setBounds:[[UIScreen mainScreen] bounds]];//shows the tan area in the graphic below
[view setFrame:[[UIScreen mainScreen] bounds]];//fills the screen
[map addSubView:view];
CGImageRelease(img);
I was setting the bounds attribute, when I should have been setting frame. Making this change fixed the issue.
Related
Note: Everything worked fine on the older screen sizes however on the new iphone screens (640x1136) things are way to far down
here is the App Delegate initing and showing myRootViewController
myRootViewController = [[RootViewController alloc] initWithNibName:#"RootViewController" bundle:[NSBundle mainBundle]];
[myRootViewController.view setFrame:[[UIScreen mainScreen] applicationFrame]];
//NSLog(#"rootviewcontroller1 frame %#", NSStringFromCGRect(myRootViewController.view.frame));
//OUTPUTS: {{0, 0}, {320, 460}}
[window addSubview:myRootViewController.view];
The RootViewController sets the frame for the 'navigationController' and a few other views before adding them to its view.
//NSLog(#"ogtest rootviewcontroller frame2 %#", NSStringFromCGRect(self.view.frame));
//OUTPUTS: {{0, 20}, {320, 548}}
[navigationController.view setFrame:CGRectMake(0, 0, 320,528)];
//I have tried multiples variations including not setting it.
loadingView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
[loadingView setBackgroundColor:[UIColor clearColor]];
UILabel *_loadingLable = [[UILabel alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 80.0f, 20.0f)];
_loadingLable.backgroundColor = [UIColor clearColor];
_loadingLable.textColor = [UIColor whiteColor];
_loadingLable.text = #"Loading...";
[_loadingLable setCenter:CGPointMake(181.0f, 240.0f)];
activityIndicatior = [[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
[activityIndicatior setCenter:CGPointMake(120.0f, 240.0f)];
RoundedView *_roundedRectangle = [[RoundedView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 140.0f, 50.0f) roundedCorner:RoundedCornersTypeALL];
_roundedRectangle.center = CGPointMake(160.0, 240.0);
_roundedRectangle.rectColor = [UIColor blackColor];
_roundedRectangle.alpha = 0.7;
[loadingView addSubview:_roundedRectangle];
[loadingView addSubview:activityIndicatior];
[loadingView addSubview:_loadingLable];
[_loadingLable release];
[_roundedRectangle release];
[loadingView setHidden:YES];
[self.view addSubview:[navigationController view]];
[self.view addSubview: loadingView];
You can see from the image below that the grey bar is there for the nav bar. The text "Tuesday 30 Apr...." with the arrow buttons should occupy that grey area and not 2 cells from the top.
If you find yourself setting the frame of your navigation controller / navigation bar, you're doing something wrong.
Most of the time, you don't even need to set the frame of your view controller's view either.
Your app delegate needn't be any more complicated than this:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[self setWindow:[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]];
[[self window] setRootViewController:[[UINavigationController alloc] initWithRootViewController:[[RootViewController alloc] init]];
[self.window makeKeyAndVisible];
return YES;
}
It will most likely be a setting in your RootViewController nib. For the first view in the "Objects" list on the left, you have probably set the Top Bar property.
I ended up creating separate xib files with
_iPhone_Retina
at end of the file name
Which also called for statements like this
if (IS_IPHONE_RETINA) {
View = [[View alloc] initWithNibName:#"View_iPhone_Retina" bundle:[NSBundle mainBundle]];
}else{
View = [[View alloc] initWithNibName:#"View" bundle:[NSBundle mainBundle]];
}
and IS_IPHONE_RETINA is defined in the projectname.pch file as
#define IS_IPHONE_RETINA ([[UIScreen mainScreen] bounds].size.height == 568 )
Hi when using autolayout on iOS 6, my "rootView" of my rootViewController doesnt seem to resize properly if at all.
My rootViewController is loaded from a nib and i am adding it to the view-hierarchy like this:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
RootVC *rootVC = [[RootVC alloc] initWithNibName:#"RootVC" bundle:nil];
self.window.rootViewController = rootVC;
return YES;
}
But when i rotate the simulator the view of rootVC doesnt resize. Since you cant set any constraints to the "rootview" in a xib, I also tried this but without any effect:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
RootVC *rootVC = [[RootVC alloc] initWithNibName:#"RootVC" bundle:nil];
self.window.rootViewController = rootVC;
NSArray *vConst = [NSLayoutConstraint constraintsWithVisualFormat:#"V:|[view]|" options:0 metrics:nil views:#{#"view" : rootVC.view}];
NSArray *hConst = [NSLayoutConstraint constraintsWithVisualFormat:#"H:|[view]|" options:0 metrics:nil views:#{#"view" : rootVC.view}];
[self.window addConstraints:vConst];
[self.window addConstraints:hConst];
return YES;
}
When i log-out the frame-size of the rootvc's view, it's always the portrait-format (w:768, h:1024)
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation{
NSLog(#"%f, %f", self.view.frame.size.width, self.view.frame.size.height);
}
could someone please tell me what i'm missing here? i've wasted hours with this problem and got nowhere^^
thx
It seems that a lot of things can go wrong with the autolayout feature iOS 6. Ambiguities in the constraints and failing to disable the translatesAutoresizingMaskIntoConstraints in your view controllers can cause much conflict. So ensure there is no ambiguities in the constraints by calling the autolayoutTrace method in lldb: po [[UIWindow keyWindow] _autolayoutTrace]
If there are ambiguities, you must resolve them.
I am making an app in which I have put a default.png in the areas provided and added sleep(5); to my app delegate and currently it runs fine.
What I need to do is add more than one image when the app starts, so that I get one splash screen for 2.5 seconds and another one for 2.5 seconds.
How can I show 2 splash screens at start up?
Two splash screens are not possible. Create a viewcontroller with UIImageView filled with second image and show it for 2.5 seconds.
Just simply add your image to your view controller and after 2.5 second, remove it from your view.
You can easily implement your view on top of the main view but in your appDelegate. For example, if you want a splash image that fades out to the main view: (or a default image that seems to fade out: just put the same image on the splash screen and the default screen). This gives you also the right orientation as long as it is the main view's.
Just add it in your
application:(UIApplication *)application didFinishLaunchingWithOptions:
method:
UIImageView*imageView=[[UIImageView alloc]initWithImage:[UIImage imageNamed:#"your_default_image_or_First.png"]];
[[firstViewController view] addSubview:imageView];
[[firstViewController view] bringSubviewToFront:imageView];
[NSThread SleepForTimeInterval:(2.5)];
[imageView setImage:[UIImage imageNamed:#"your_default_image_or_Second.png"]]
// as usual
[self.window makeKeyAndVisible];
//now fade out splash image
[UIView transitionWithView:self.window duration:1.0f options:UIViewAnimationOptionTransitionNone animations:^(void){imageView.alpha=0.0f;} completion:^(BOOL finished){[imageView removeFromSuperview];}];
Hi please try with following code its really hwlp full for you dear i suggested to use this one.....
-(BOOL)application:(UIApplication )application didFinishLaunchingWithOptions:(NSDictionary)launchOptions
{
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
// Override point for customization after application launch.
MasterViewController *masterViewController = [[[MasterViewController alloc] initWithNibName:#"MasterViewController" bundle:nil] autorelease];
self.navigationController = [[[UINavigationController alloc] initWithRootViewController:masterViewController] autorelease];
UIImageView *imageView = [[[UIImageView alloc] initWithFrame:self.window.bounds] autorelease];
UIImage *image = [UIImage imageNamed:#"Welcome.png"];
if (!image)
{
NSLog(#"Something went wrong trying to get the UIImage. Check filenames");
}
imageView.image = image;
[self.window addSubview:imageView];
[self.window makeKeyAndVisible];
[self performSelector:#selector(removeFirstSplash:) withObject:imageView afterDelay:3];
return YES;
}
-(void)removeFirstSplash:(UIImageView *)oldImageView
{
UIImageView *imageView = [[[UIImageView alloc] initWithFrame:self.window.bounds] autorelease];
UIImage *image = [UIImage imageNamed:#"Splash.png"];
imageView.image = image;
[self.window addSubview:imageView];
[self performSelector:#selector(removeSecondSplash:) withObject:imageView afterDelay:3];
[oldImageView removeFromSuperview];
}
-(void)removeSecondSplash:(UIImageView *)oldImageView
{
[self.window addSubview:self.navigationController.view];
[oldImageView removeFromSuperview];
}
So, I am trying to achieve having a fixed top banner on Application UIWindow and a working navigation of multiple view controllers. I know there are other ways of performing this but for my project requirements I need to use xibs.
The code below allows to achieve this:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.headerView = [[UIImageView alloc] init];
self.headerView.frame = CGRectMake(0.0f, 20.0f, 320.0f, 44.0f);
self.headerView.image = [UIImage imageNamed: #"header-banner-background.png"];
[self.window addSubview:self.headerView];
self.viewController = [[ViewController alloc] initWithNibName:#"ViewController" bundle:nil];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:self.viewController];
self.window.rootViewController = navigationController;
[self.window makeKeyAndVisible];
return YES;
}
Then in each ViewController viewWillAppear method I have resized both self.view and self.navigationController.navigationBar.frame in order to show themselves below the banner:
self.navigationController.navigationBar.frame = CGRectMake(0, 64, 320, 44);
self.view.frame = CGRectMake(0, 64, 320, 396);
This is fine, works exactly the way I wanted.
But if the user presses the home button and the application resigns active, when it becomes active again the last viewController seen get's displayed but without the UIWindow banner, and the self.view and navigationBar are displayed on top.
Of course the current UIViewController viewWillAppear method is not called when the application returns active, but even if I put the resize code in another function and call it through a notification it does not work. But when the user presses a bar item and moves in the navigation stack, then everything works again and UIWindow displays the headerView.
Anyone understands why the UIWindow headerView disappears when application returns active?
EDIT 1: Possible solution?
#interface RootViewController ()
{
ViewController *viewController;
UINavigationController *navigationController;
}
#end
#implementation RootViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
viewController = [[ViewController alloc] initWithNibName:#"ViewController" bundle:nil];
navigationController = [[UINavigationController alloc] initWithRootViewController:viewController];
}
return self;
}
- (void)loadView
{
// Implement loadView to create a view hierarchy programmatically, without using a nib.
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 88)];
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
[imageView setImage:[UIImage imageNamed:#"header"]];
[view addSubview:imageView];
navigationController.navigationBar.frame = CGRectMake(0, 44, 320, 44);
[view addSubview:navigationController.navigationBar];
self.view = view;
}
EDIT 2: Second possible solution, still not working
- (void)loadView
{
NSLog(#"loadView root");
// Implement loadView to create a view hierarchy programmatically, without using a nib.
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 88)];
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
[imageView setImage:[UIImage imageNamed:#"banner"]];
[view addSubview:imageView];
navigationController = [[UINavigationController alloc] init];
navigationController.navigationBar.frame = CGRectMake(0, 43, 320, 44);
[view addSubview:navigationController.navigationBar];
[self addChildViewController:navigationController];
self.view = view;
[self.view setBackgroundColor:[UIColor yellowColor]];
}
This is the result, which seems fine, without the push of the viewController1 (note the yellow background is from the rootViewController):
This instead is the result of adding:
- (void)viewDidLoad
{
viewController1 = [[ViewController1 alloc] initWithNibName:#"ViewController1" bundle:nil];
[navigationController pushViewController:viewController1 animated:YES];
}
The new view controller is not pushed (the background should be black) and the navigation bar has disappeared.
EDIT 3: Olloqui solution, still not working
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[self.window setBackgroundColor:[UIColor redColor]];
UIView *bannerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
[self.window addSubview:bannerView];
UIView *navigationView = [[UIView alloc] initWithFrame:CGRectMake(0, 44, 320, 416)];
ViewController1 *viewController1 = [[ViewController1 alloc] initWithNibName:#"ViewController1" bundle:nil];
self.navigationController = [[UINavigationController alloc] initWithRootViewController:viewController1];
self.navigationController.navigationBar.frame = CGRectMake(0, 0, 320, 44);
[navigationView addSubview:self.navigationController.navigationBar];
[self.window addSubview:navigationView];
self.window.rootViewController = self.navigationController;
self.window.autoresizesSubviews = YES;
[self.window makeKeyAndVisible];
return YES;
}
Result is I have only the banner, viewController1 is pushed but no navigation bar is displayed. I really need to figure this out, anyone has a different approach?
The window expects to have a root view controlled by its rootViewController property. When returning from the background the window only asks for the rootViewController to restore the appearance of that view controller's view. It doesn't ask all subviews to refresh.
To fix this I would create a new root view controller. This would have the banner and the navigation controller. That navigation controller would then hold your normal view controllers and manage the navigation. The banner will appear properly upon the app returning from the background. Your banner will be stationary while navigation occurs within the navigation controller.
Edit: I whipped up a little example program.
I started with a simple single view app template. I added two view controllers for the content. The just have labels for differentiation, and one has a button that loads the second view.
All the magic happens in the main view controller's viewDidLoad method:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
OneViewController *oneVC = [[OneViewController alloc] initWithNibName:#"OneViewController" bundle:nil];
self.navController = [[UINavigationController alloc]initWithRootViewController:oneVC];
self.navController.view.frame = CGRectMake(0.0, 64.0, 320.0, 416.0);
[self.view addSubview:self.navController.view];
[self addChildViewController:self.navController];
}
The nib for this view loads the image view for the banner.
The example project in on Bitbucket.
I have never tried it before but I would take a shot to create 2 views in the UIWindow, one for the banner and the other one for the navigation + content. Then, insert the navigationBar view in this second view, that will be sized properly. I am not sure if the navigation is going to try to take the full window are, but resizing the navigation controller on each viewWillAppear doesnt look a good solution to me. Try it and comment the result!
I think you can try to workaround this problem by adding the banner view to window.rootViewController.view like this:
[window.rootViewController.view addSubview:bannerView]
Ok, I really needed to solve this ASAP, therefore I opted for a solution I was lucky enough to find here. I still have to solve the management of the UITabBarController added on bottom but the rest seems to be working fine. Thanks everyone for help and additional hints.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[self.window setBackgroundColor:[UIColor redColor]];
// Create a view for the banner add the banner to this view
UIImageView *bannerImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320, 45)];
bannerImageView.image = [UIImage imageNamed:#"banner"];
// put this banner above the nav bar
UIView *bannerView = [[UIView alloc] initWithFrame:CGRectMake(0, -44, 320, 44)];
[bannerView addSubview:bannerImageView];
//add the tabBarController as a subview of the view
UITabBarController *tabBarController = [[UITabBarController alloc] init];
[tabBarController.view addSubview:bannerView];
// Move the root view to show status bar & banner
tabBarController.view.frame = CGRectMake(0, 20+44, 320, 480-20-44);
//add the modified logo view to window
[self.window addSubview:tabBarController.view];
ViewController1 *viewController1 = [[ViewController1 alloc] initWithNibName:#"ViewController1" bundle:nil];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:viewController1];
tabBarController.viewControllers = [NSArray arrayWithObjects:navigationController, nil];
//tabBarController.tabBar.hidden = YES;
[self.window setRootViewController:tabBarController];
[self.window makeKeyAndVisible];
return YES;
}
HI,
I develop an application in which I want to implement the splash screen, on that splash screen I want to bind the scrollView and UIImage. My code as follow,
-(void)splashAnimation{
window = [[UIWindow alloc] initWithFrame:CGRectMake(0, 0, 320, 420)];
//scrollView = [[UIScrollView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
scrollView = [[UIScrollView alloc] initWithFrame:[window bounds]];
scrollView.pagingEnabled = NO;
scrollView.bounces = NO;
UIImage *image = [UIImage imageNamed:#"splash.png"];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
imageView.userInteractionEnabled = NO;
[scrollView addSubview:imageView];
[scrollView setDelegate:self];
//[scrollView release];
}
- (void)applicationDidFinishLaunching:(UIApplication *)application {
[self splashAnimation];
[self initControllers];
[window addSubview:[mainTabBarController view]];
[window makeKeyAndVisible];
}
On my given code the one blank window comes up and stay on.
I want to on that blank screen bind my splash.png.
****The Above problem is solved****
My current code is
scrollView.pagingEnabled = NO;
scrollView.bounces = NO;
UIImage *image = [UIImage imageNamed:#"splash.png"];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
imageView.userInteractionEnabled = NO;
[scrollView addSubview:imageView];
scrollView.maximumZoomScale = 4.0f;
scrollView.minimumZoomScale = 1.0f;
CGRect rect = CGRectMake(119, 42, 208, 166);
[scrollView zoomToRect:rect animated:YES];
[scrollView setDelegate:self];
[window addSubview:scrollView];
[window makeKeyAndVisible];
I want to zoom the particular part of scrollView.
RajB - for your zooming of the scrollView do this:
CGRect zoomRect = CGRectMake(119, 42, 208, 166);
[scrollView zoomToRect:zoomRect animated:YES];
Hope this helps!
You create a UIScrollView but never add it to the view hierarchy, therefore it will never get displayed. Call [window addSubview:scrollView], and then don't forget to release it.
If you are using a MainWindow.xib in your project, your window is created for you, you do not need to create your own.
Use [[UIScreen mainScreen] instead of CGRect(0, 0, 320, 420) <- I also believe you meant "480"
After setting up your splash animation, you call [window addSubview:[mainTabBarController view]]. Even after adding your scrollview as previously mentioned, this will then become the topmost and therefore visible view.
Delay the [window addSubview:[mainTabBarController view]] until after your splash animation completes.