All,
The Done button in MPMoviePlayerController dismisses the control in portrait mode.
However, both the Done and Toggle full screen button become unresponsive when i rotate to landscape.
My app is a very very simple app and just has didRotatefromInterfaceOrientation method where i change the movie frame width and height to landscape and change the origin to match landscapemode.
`- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
// Update the frame of the view.
CGRect newFrame = [[UIScreen mainScreen] applicationFrame];
newFrame.origin.x = - (newFrame.size.width / 2);
newFrame.origin.y = - (newFrame.size.height / 2);
[[self view] setBounds:newFrame];
[[self view] setCenter:CGPointMake( [[self view] bounds].size.width / 2, [[self view] bounds].size.height / 2)];
[self view].userInteractionEnabled = YES;
// Update the frame of the movie player.
newFrame = [[UIScreen mainScreen] applicationFrame];
if( fromInterfaceOrientation == UIInterfaceOrientationPortrait || fromInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown)
{
newFrame.size.width = newFrame.size.height;
newFrame.size.height = [[UIScreen mainScreen] applicationFrame].size.width;
}
newFrame.origin.x = - (newFrame.size.width / 2);
newFrame.origin.y = - (newFrame.size.height / 2);
[[[self moviePlayer] view] setFrame:newFrame];
[[[self moviePlayer] view ] setUserInteractionEnabled:YES ];
}`
Well the problem here was that i was rotating the view and resizing it in `- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation.
You are not required to do that as the movie player automatically does that for you.
Resizing and rotating the frame actually got the button confused and hence did not receive touch events when tapped.
Related
I've got a tabbed application and in one tab there is a UIWebView. When I rotate the device to landscape I've made the UIWebView full screen while hiding the status and tab bar.
I've got it working in iOS 6 - originally when rotating and hiding the tab bar it would leave a black space where the tab bar was, so the fHeight code fixes this. However, on iOS 6 it worked perfectly, but now it actually creates the black bar problem iOS 6 was having!! Any ideas for a workaround to this?
Please see my edit below this
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration;
{
if(toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft || toInterfaceOrientation == UIInterfaceOrientationLandscapeRight) {
[self hideTabBar:self.tabBarController];
[[UIApplication sharedApplication] setStatusBarHidden:TRUE withAnimation:UIStatusBarAnimationSlide];
}
else
{
[self showTabBar:self.tabBarController];
[[UIApplication sharedApplication] setStatusBarHidden:FALSE withAnimation:UIStatusBarAnimationSlide];
}
}
- (void) hideTabBar:(UITabBarController *) tabbarcontroller
{
CGRect screenRect = [[UIScreen mainScreen] bounds];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
float fHeight = screenRect.size.height;
if( UIDeviceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation) )
{
fHeight = screenRect.size.width;
}
for(UIView *view in self.tabBarController.view.subviews)
{
if([view isKindOfClass:[UITabBar class]])
{
[view setFrame:CGRectMake(view.frame.origin.x, fHeight, view.frame.size.width, view.frame.size.height)];
}
else
{
[view setFrame:CGRectMake(view.frame.origin.x, view.frame.origin.y, view.frame.size.width, fHeight)];
view.backgroundColor = [UIColor blackColor];
}
}
[UIView commitAnimations];
}
- (void) showTabBar:(UITabBarController *) tabbarcontroller
{
CGRect screenRect = [[UIScreen mainScreen] bounds];
float fHeight = screenRect.size.height - 49.0;
if( UIDeviceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation) )
{
fHeight = screenRect.size.width - 49.0;
}
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
for(UIView *view in tabbarcontroller.view.subviews)
{
if([view isKindOfClass:[UITabBar class]])
{
[view setFrame:CGRectMake(view.frame.origin.x, fHeight, view.frame.size.width, view.frame.size.height)];
}
else
{
[view setFrame:CGRectMake(view.frame.origin.x, view.frame.origin.y, view.frame.size.width, fHeight)];
}
}
[UIView commitAnimations];
}
//Edit
I've tried using this but I'm not sure how to pass in the view properly - I've tried self.view and webView and others but I can't get it to work on both iOS 6 and 7! Any kind of idea at all would be really helpful! Let me know if you need more info
- (void)setTabBarHidden:(BOOL)hidden view:(UIView *)view animated:(BOOL)animated
{
if (self.tabBar.hidden == hidden)
return;
CGRect screenRect = [[UIScreen mainScreen] bounds];
float height = 0.0f;
if(UIDeviceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation))
{
height = screenRect.size.width;
}
else
{
height = screenRect.size.height;
}
if (!hidden)
{
height -= CGRectGetHeight(self.tabBar.frame);
}
void (^workerBlock)() = ^() {
self.tabBar.frame = CGRectMake(CGRectGetMinX(self.tabBar.frame), height, CGRectGetWidth(self.tabBar.frame), CGRectGetHeight(self.tabBar.frame));
view.frame = CGRectMake(CGRectGetMinX(view.frame), CGRectGetMinY(view.frame), CGRectGetWidth(view.frame), height);
};
void (^completionBlock)(BOOL finished) = ^(BOOL finished) {
self.tabBar.hidden = hidden;
};
if (animated)
{
[UIView animateWithDuration:0.25f animations:workerBlock completion:completionBlock];
}
else
{
workerBlock();
completionBlock(YES);
}
}
I've created a a public Gist on Github for how we're doing this.
This solution has gone through several iterations due to #Chris Byatt and our team trying it out. So, make sure you download the latest revision from there.
The method signature has been simplified to
- (void)setTabBarHidden:(BOOL)hidden animated:(BOOL)animated;
You can call it like this within your UIViewController subclass:
[self.tabBarController setTabBarHidden:YES animated:YES];
OK guys, after struggling with this for about two hours, my colleague taught me the right way to do it. There is actually a very simple fix that I can't find online:
just put :
self.hidesBottomBarWhenPushed = YES;
In the init method of your viewController and comment out the self.tabBar.hidden related code.
I eventually got this working, but it took a while. It stemmed from a mixture of my original code and some of JRG-Developers work.
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
BOOL toLandscape = UIDeviceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation);
CGRect screenRect = [[UIScreen mainScreen] bounds];
void (^workerBlock)() = ^() {
[[UIApplication sharedApplication] setStatusBarHidden:toLandscape withAnimation:UIStatusBarAnimationSlide];
float height = toLandscape ? screenRect.size.width : screenRect.size.height - CGRectGetHeight(self.tabBarController.tabBar.frame);
float width = toLandscape ? screenRect.size.height : screenRect.size.width;
webView.frame = CGRectMake(CGRectGetMinX(webView.frame),
CGRectGetMinY(webView.frame),
width,
height);
[self moveTabBarToPosition:height];
};
[UIView animateWithDuration:0.25f animations:workerBlock];
}
//Moving the tab bar and its subviews offscreen so that top is at position y
-(void)moveTabBarToPosition:(int)y {
self.tabBarController.tabBar.frame = CGRectMake(self.tabBarController.tabBar.frame.origin.x, y, self.tabBarController.tabBar.frame.size.width, self.tabBarController.tabBar.frame.size.height);
for(UIView *view in self.tabBarController.view.subviews) {
if ([view isKindOfClass:[UITabBar class]]) {
[view setFrame:CGRectMake(view.frame.origin.x, y, view.frame.size.width, view.frame.size.height)];
} else {
[view setFrame:CGRectMake(view.frame.origin.x, view.frame.origin.y, view.frame.size.width, y)];
view.backgroundColor = [UIColor blackColor];
}
}
}
In my case this is for my webview but theoretically you can give it any view. Works in iOS 6 and 7
-(void) hideBottomTabs{
// Get the size of the main screen
CGRect fullScreenRect = [[UIScreen mainScreen]bounds];
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0){
UITabBar *bar = ((UITabBarController *)self.parentViewController).tabBarController.tabBar;
fullScreenRect.size.height += ViewHeight(bar);
}
// Hide the tab bar
((UITabBarController *)self.parentViewController).tabBarController.tabBar.hidden = YES;
// Resize and fill the screen
[[((UITabBarController *)self.parentViewController).view.subviews objectAtIndex:0] setFrame:fullScreenRect];
}
I have solved my problem in a such way.
I have project is single view app and add to view controller scrollview
with parameters
[scroller setScrollEnabled:YES];
[scroller setContentSize:CGSizeMake(0, 960)];
if screen resolution is 320x480 then we have some invisible "screen 2" (320x480)
how do I make that - did load app at position "screen 2" and after that
I can scroll not down, but to up at start launch app.
How to release that?
you have to give the scrollview a proper content size, depending on the screen size.
Assuming that the scrollview is fullscreen in portrait:
//------------------------------------------
- (void)viewDidLoad{
[super viewDidLoad];
CGRect screenSize = [[UIScreen mainScreen] bounds];
[scroller setScrollEnabled:YES];
[scroller setContentSize:CGSizeMake(0, screenSize.size.height)];
}
//------------------------------------------
- (void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
CGRect screenSize = [[UIScreen mainScreen] bounds];
CGPoint scrollPoint = CGPointMake( 0.0, screenSize.size.height / 2);
[scroller setContentOffset:scrollPoint animated:YES];
}
- (void)viewDidLoad
{
self.YourSecondView.frame = CGRectMake("As You Need");
[self.ScView addSubview:self.YourSecondView];
CGRect rect = CGRectMake(self.YourSecondView.frame.origin.x,self.YourSecondView.frame.origin.y,self.YourSecondView.frame.size.width,self.YourSecondView.frame.size.height);
[self.ScView scrollRectToVisible:rect animated:YES];
}
I'm pushing a ViewController when the iPhone changes orientation to landscape and I'm having trouble with changing the orientation of the ViewController.
I used that code:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
Storage *strg = [Storage sharedStorage];
if ([strg.orient intValue] == 2)
{
[[UIApplication sharedApplication] setStatusBarOrientation:
UIInterfaceOrientationLandscapeRight];
UIScreen *screen = [UIScreen mainScreen];
CGFloat screenWidth = screen.bounds.size.width;
CGFloat screenHeight = screen.bounds.size.height;
UIView *navView = [[self navigationController] view];
navView.bounds = CGRectMake(0, 0, screenHeight, screenWidth);
navView.transform = CGAffineTransformIdentity;
navView.transform = CGAffineTransformMakeRotation(1.57079633);
navView.center = CGPointMake(screenWidth/2.0, screenHeight/2.0);
[UIView commitAnimations];
}
if ([strg.orient intValue] == 1)
{
[[UIApplication sharedApplication] setStatusBarOrientation:
UIInterfaceOrientationLandscapeLeft];
UIScreen *screen = [UIScreen mainScreen];
CGFloat screenWidth = screen.bounds.size.width;
CGFloat screenHeight = screen.bounds.size.height;
UIView *navView = [[self navigationController] view];
navView.bounds = CGRectMake(0, 0, screenHeight, screenWidth);
navView.transform = CGAffineTransformIdentity;
navView.transform = CGAffineTransformMakeRotation(4.71238898);
navView.center = CGPointMake(screenWidth/2.0, screenHeight/2.0);
[UIView commitAnimations];
}
}
The result is not consistent; sometimes it goes into the right orientation and sometimes it's upside-down.
When I go from LandcapeRight to LandscapeLeft strait away (and vise versa) it works fine, the problem is only when I go to portrait mode.
Any ideas what I'm doing wrong?
If you really are responding to device orientation change they you probably shouldn't be using setStatusBarOrientation. I think you'd be better off making your viewcontrollers rotate to the supported orientations using shouldAutorotateToInterfaceOrientation and deviceDidRotateSelector notifications.
[[NSNotificationCenter defaultCenter] addObserver: self selector: #selector(deviceDidRotateSelector:) name: UIDeviceOrientationDidChangeNotification object: nil];
-(void)deviceDidRotateSelector:(NSNotification*) notification {
// respond to rotation here
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
//Return YES for supported orientations
return YES;
}
I use following code I found in the web to rotate the screen to landscape mode. I don’t understand what they suppose to do. Specially the bounds it is setting. Can someone give some explanation what it is doing?
if ([[UIApplication sharedApplication] statusBarOrientation] == UIInterfaceOrientationPortrait)
{
CGRect statusBarFrame = [[UIApplication sharedApplication] statusBarFrame];
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight animated:NO];
UIScreen *screen = [UIScreen mainScreen];
CGRect newBounds = CGRectMake(0, 0, screen.bounds.size.height, screen.bounds.size.width - statusBarFrame.size.height);
self.navigationController.view.bounds = newBounds;
self.navigationController.view.center = CGPointMake(newBounds.size.height / 2.0, newBounds.size.width / 2.0);
self.navigationController.view.transform = CGAffineTransformConcat(self.navigationController.view.transform, CGAffineTransformMakeRotation(degreesToRadian(90)));
self.navigationController.view.center = window.center;
}
Your rootView's size used to be (320, 480) for example, after rotating, you should set it to (480, 320) in order to fit the screen in landscape mode, that's why you need to change the bounds of your view.
Set the transform is making the view actually rotate 90 degrees.
UIKit is doing the similar things when automatically rotate for you.
Hello Janaka,
You will try this code.
Take a look at the function `shouldAutorotateToInterfaceOrientation`: in the UIViewController class. This function returns YES if the orientations is supported by your UIView. If you return YES only to the landscape orientation, then the iPhone will automatically be put in that orientation.
The following code should do it. Put it in the UIViewController that controls the view that you want to put in landscape mode.
Use this Method.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationLandscape);
}
Try this link its definitely help you
this
#define degreesToRadians(x) (M_PI * x / 180.0)
- (void)viewWillAppear:(BOOL)animated
{
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight];
CGRect newBounds = CGRectMake(0, 0, 480, 320);
self.navigationController.view.bounds = newBounds;
self.navigationController.view.center = CGPointMake(newBounds.size.height / 2.0, newBounds.size.width / 2.0);
self.navigationController.view.transform = CGAffineTransformMakeRotation(degreesToRadians(90));
[super viewWillAppear:animated];
}
- (void)viewWillDisappear:(BOOL)animated
{
self.navigationController.view.transform = CGAffineTransformIdentity;
self.navigationController.view.transform = CGAffineTransformMakeRotation(degreesToRadians(0));
self.navigationController.view.bounds = CGRectMake(0.0, 0.0, 320.0, 480.0);
[super viewWillDisappear:animated];
}
So, I've managed to create a UIScrollView with zooming method programmatically, but I'm kind of stuck how to solve an issue I'm having with zooming:
When I zoom in or out the point at where it expands/retracts does not happen where I do the pinch gesture, it happens on a corner.
After zooming in or out, it will leave extra space outside the bounds, and I cannot scroll the image more than half the width & height of the image.
Other than this, I'm so close to getting it working 100%. I've tried playing around with achorpoints, but it looks like the scroll view and image view does not respond to this.
Here is the important stuff in the code listing:
UIScrollView *mapScrollView;
UIImageView *mapImageView;
CGFloat lastScale = 0;
NSMutableArray *map_List;
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
mainMenuAppDelegate *del = (mainMenuAppDelegate *)[[UIApplication sharedApplication] delegate];
map_List = [[NSMutableArray alloc] init];
[map_List addObject:#"Pacific_Map_8bit.png"];
[map_List addObject:#"Atlantic_Map_8bit.png"];
CGRect mapScrollViewFrame = CGRectMake(0, 0, 1024, 768);
mapScrollView = [[UIScrollView alloc] initWithFrame:mapScrollViewFrame];
mapScrollView.contentSize = CGSizeMake(2437, 1536);
UIImage *mapImage = [UIImage imageNamed:[map_List objectAtIndex:mapNum]];
mapImageView = [[UIImageView alloc] initWithImage: mapImage];
mapScrollView.bounces = NO;
[mapImage release];
[mapScrollView addSubview:mapImageView];
[self addSubview:mapScrollView];
mapImageView.userInteractionEnabled = YES;
UIPinchGestureRecognizer *pinchRecognizer = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:#selector(scale:)];
[mapImageView addGestureRecognizer:pinchRecognizer];
[pinchRecognizer release];
}
return self;
}
// the scale method thats triggered to zoom when pinching
-(void)scale:(id)sender {
if([(UIPinchGestureRecognizer*)sender state] == UIGestureRecognizerStateEnded) {
lastScale = 1.0;
return;
}
CGFloat scale = 1.0 - (lastScale - [(UIPinchGestureRecognizer*)sender scale]);
NSLog(#"map scale %f", scale);
CGFloat mapWidth = mapImageView.frame.size.width;
CGFloat mapHeight = mapImageView.frame.size.height;
NSLog(#"map width %f", mapWidth);
if(scale>=1 & mapWidth<=4000 || scale<1 & mapWidth>=1234){
CGAffineTransform currentTransform = [(UIPinchGestureRecognizer*)sender view].transform;
CGAffineTransform newTransform = CGAffineTransformScale(currentTransform, scale, scale);
[[(UIPinchGestureRecognizer*)sender view] setTransform:newTransform];
lastScale = [(UIPinchGestureRecognizer*)sender scale];
}
mapScrollView.contentSize = CGSizeMake(mapWidth, mapHeight);
}
Thanks!
UIScrollView has built-in zooming support. All you need to do is set the minimumZoomScale and maximumZoomScale properties, and return a view to be used for zooming using viewForZoomingInScrollView.