I've been trying to create a full screen view. I plan on using core graphics for rendering. I am new to iPhone development so please forgive this basic question.
Here's my setup code;
- (void)loadView
{
CGRect rect = [[UIScreen mainScreen] bounds];
GameView *main_view;
main_view = [[GameView alloc] initWithFrame:rect ];
main_view.clearsContextBeforeDrawing = NO;
self.view = main_view;
[main_view release];
}
Yet when I run this I get a thin status bar at the top with the time and battery level.
I tried looking for some samples yet all the samples were opengles.
Could someone please tell me where I'm going wrong? And just how to create a full screen view.
Thanks
There are two methods;
In the info.plist for your application add a boolean key UIStatusBarHidden and set it to true.
At runtime you can call setStatusBarHidden on your application to show/hide the status bar. E.g.
[[UIApplication sharedApplication] setStatusBarHidden:YES animated:NO]
Since I just found the answer I was looking for here, I may as well add that the above method is now depreciated. The modern method is:
- (void)setStatusBarHidden:(BOOL)hidden withAnimation:(UIStatusBarAnimation)animation
Thanks!
You may also want to make your rect = [[UIScreen mainScreen] applicationFrame]
Add below method in respective view controller
-(BOOL) prefersStatusBarHidden
It worked for me.
This works and it is the easiest
UIViewControllerBasedStatusBarAppearance : NO in the .plist
Related
I have a UIView as a XIB in Portrait mode.
This view is added programmatically to the viewcontroller like this:
NSArray *nibObjects = [[NSBundle mainBundle] loadNibNamed:#"InputView" owner:self options:nil];
InputView *inputView = (InputView*)[nibObjects objectAtIndex:0];
[self.view addSubview:inputView];
This view has autoresizing masks set up properly and rotates fine when the orientation changes from Portrait to landscape.
However, if the orientation is already landscape and I create the view after the orientation change, it has its initial portrait orientation.
Is there a way to tell the view to initialize or resize itself to portrait by using its masks?
Thanks in advance for any reply!
EDIT:
Using the suggestions of occulus and Inder Kumar Rathore (thanks guys!), I altered the code to this:
InputView *inputView = (InputView*)[nibObjects objectAtIndex:0];
[self.view addSubview:inputView];
[self.view setNeedsLayout];
[self.view layoutSubviews];
[self.view layoutIfNeeded];
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
[self shouldAutorotateToInterfaceOrientation:orientation];
Unfortunately, there is no change at all.
I think I found someone asking the same question:
When adding a sub view the view does not resize if the app is in landscape mode
The answer identifies the problem correctly, but is not very encouraging...
Sure, I could create two nibs or resize the frame, but this seems so contrary to the idea of auto-resizing.
I find it hard to believe that there is no way to tell a nib after awakening and adding it to a view to use its autoresize features...something that works flawless when the device rotates.
EDIT 2:
The solution of idz works:
InputView *inputView = (InputView*)[nibObjects objectAtIndex:0];
[self.view addSubview:inputView];
inputView.frame = self.view.bounds;
[inputView show];
Thanks!
Often a NIB/XIB file contains a UIViewController that takes care of all of this. In this case, since their is no view controller (in the NIB/XIB) you need to take over its post-load duties.
Calling layoutSubviews directly, or indirectly via setNeedsLayout or layoutIfNeeded won't do you much good because the default implementation does nothing.
Assuming you want input view to fill the bounds of self.view you do the following:
InputView *inputView = (InputView*)[nibObjects objectAtIndex:0];
[self.view addSubview:inputView];
inputView.frame = self.view.bounds;
[inputView show];
All the resize masks of the sub-views must be correctly set for this to work and, obviously, if you don't want to fill the full bounds you may want to adjust the frame.
[self.view addSubview:viewSpinner];
viewSpinner.frame = self.view.frame;
[viewSpinner setNeedsLayout];
This works for me (Y)
I don't know if you still have this issue.
Let's say you have the following architecture:
window
subviewcontroller
(you implemented shouldautorotate correct to answering the wanted orientations)
Into this subviewcontroller you want to add the views of new UIViewControllers by just calling the addSubview function.
Instead of implementing the bounds manipulation in shouldautorotate, you should implement it in
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation{
self.newUIViewController.view.frame = self.view.bounds;
}
didRotateFromInterface... is called after shouldRotate. In this function the bounds are already setup correctly.
This way you don't need so much manipulation by code.
See this related question:
When do autoresizing masks take effect in iOS?
So after loading your new view from the nib, and adding as a subview to self.view, try calling setNeedsLayout.
Using this method to hide the status bar:
[[UIApplication sharedApplication] setStatusBarHidden:YES animated:YES];
When setting "hidden" back to NO, the tap-to-scroll-to-top (in UIWebView, UITableView, whatever) doesn't work any more, and requires a restart of the app to get the functionality back.
Is this a bug (I filed a rdar anyhow) or have I missed a step? Should I perhaps expect this behavior since the statusBar "loses touch" somehow with the respective view?
You could try setting the ScrollsToTop property to true again after re-showing it:
[currentView setScrollsToTop:YES];
If that's not working, are you definitely only showing one view? If there is more than one scrolling view a scrollViewDidScrollToTop message is ignored...
In iOS 5.0 you can access the scrollview property of the UIWebView
webView.scrollView.scrollsToTop = YES;
The following fix by Alex worked for me. Thanks!
((UIScrollView *)[[webView subviews] objectAtIndex:0]).scrollsToTop = NO;
Being in a hurry this fix worked great, however given more time I might've subclassed the UIWebView and accessed the protected UIScrollView member directly.
The worry I have with Alex' method is that it assumes that UIScrollView is at index zero of the subviews (encapsulation allows private members to change). Which suggests another solution still:
for (UIView* v in [webView subviews])
{
if ([v isKindOfClass:[UIScrollView class]])
{
(UIScrollView *)v.scrollsToTop = NO;
}
}
I was having a similar problem where the scroll-to-top functionality was lost. Turns out this will only work when you have only one active view at a time (within the same scroll view). In my case I had a table view and another view which would fade in/out. Adding a removeFromSuperview at the end of the animation did the trick.
The answer was in the UIScrollView.h file comments:
/*
this is for the scroll to top gesture. by default, a single scroll visible scroll view with this flag set will get the call. if there is more than one visible with this
flag set or the delegeat method returns NO, the view isn't scrolled
*/
#property(nonatomic) BOOL scrollsToTop; // default is YES. if set, special gesture will scroll to top of view after consulting delegate
You can use the following code to have the UIWebView ignore scrollToTop without the extra UIScrollView:
((UIScrollView *)[[webView valueForKey:#"_internal"] valueForKey:#"scroller"]).scrollsToTop = NO;
I had a similar problem after playing a Youtube video within my app. scrollsToTop was still set to YES but tapping the status bar had no effect.
I finally realised that my app window was no longer the key window. After adding the following line to a UIWindow subclass (which I already had for other reasons) everything worked as it should again:
if (![self isKeyWindow]) [self makeKeyWindow];
I just ran across a similar behavior in the app I'm currently working on. In its case, if you load a YouTube video from within a UIWebView, scroll to top stops working for the rest of the application's life cycle. I kind of assume this might happen after loading the movie player as well, but haven't confirmed. That functionality has been around a lot longer and probably has fewer bugs.
When there are multiple scrollview, you can also set scrollUpToTop to NO for the others scrollview. cf:
setScrollsToTop with multiple UIScrollView classes and/or subclasses(UITableView)
I want to add my case, I add an UIWebView on an UIScrollView, as h4xxr had answered on the top:
If there is more than one scrolling view a scrollViewDidScrollToTop message is ignored
So, I get a simply way to make it work on webView: just set the scrollView·s scrollsToTop property false.
And when tap the status bar, it won`t got intercepted by the scrollView, and the webView scrolls to the top!
UIScrollView *scrollView = [[UIScrollView alloc] init];
scrollView.frame = self.view.bounds;
scrollView.scrollsToTop = false; //igore scrollView`s scrollsToTop
[self.view addSubview:scrollView];
UIWebView *webView = [[UIWebView alloc] init];
webView.frame = scrollView.bounds;
[scrollView addSubview:webView];
My app is landscape. I would like to launch the in-app email composer in landscape and restrict it as such. Can anyone advise how to do this? I created a view controller with the proper auto-rotate settings to keep my app in landscape but am unsure how to tell the MFMailComposeViewController to please launch in landscape and stay there (and stop making the keyboard rotate).
Help?
This is answering his comment and not the original question.
I had this problem as well and this snippet seems to work for me:
[[UIApplication sharedApplication] setStatusBarOrientation: UIInterfaceOrientationLandscapeLeft];
First Add following property in info.plist file
Supported interface orientations
"Landscape (right home button)"
than use presentModalViewController
-(void)displayComposerSheet
{
MFMailComposeViewController *picker4 = [[[MFMailComposeViewController alloc]init]autorelease];
picker4.mailComposeDelegate = self;
[picker4 setSubject:result];
CGRect rect = CGRectMake(0,0,480,320);
UIGraphicsBeginImageContext(rect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
[view.layer renderInContext:context];
// Fill out the email body text
[self presentModalViewController:picker4 animated:NO];
}
This is probably a really basic question, but when I make my ABPeoplePickerNavigationController instance (addBookViewer)visible by running,
[self presentModalViewController:addBookViewer animated:YES]
the contact view pops up, but is cut off by the top most bar of the display (the bar showing the AT&T signal strength, clock and battery charge). Is there a way to programatically change the addBookViewer so that it is not cut off by the static status bar?
Thanks,
Dave
It looks like ABPeoplePickerNavigationController inherits from UIViewController. Perhaps you could try editing the view's frame before presenting it:
addBookViewer.view.frame = CGRectMake(0, 20, [[UIScreen mainScreen] bounds].size.width, [[UIScreen mainScreen] bounds].size.height - 20);
I suspect it is because the view controller that you are calling presentModalViewController:animated: on has a frame that is also being covered, but you don't notice, probably have plenty of head room, make sure you have the status bar in your nib file so that it is laid out correctly.
I am wondering if there is some way to rotate a created ABPeoplePickerNavigationController. I am creating the ABPeoplePickerNavigationController like this:
ABPeoplePickerNavigationController *addressBook = [[ABPeoplePickerNavigationController alloc] init];
addressBook.peoplePickerDelegate = self;
[self presentModalViewController:addressBook animated:YES];
My application is in landscape mode, and I am wondering how I can get this created controller to rotate like the rest of the application. As the Address Book application does this without any problems, I assume it is a pretty easy fix.
Thanks for any help!
I would look int possibly overriding - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation and making sure it returns YES for landscape.
Hope this may work , but try out atleast
[addressBook.view setTransform : CGAffineTransformMakeRotation( 90 * M_PI/ 180)];
The idea is to rotate the ABPeoplePickerNavigationController's view by transformation.