Does anyone know fix(not to rotate) a certain UIView with allowing rotation of UIViewController?
I want to implement a interface like camera app UI. A view showing camera's view does not rotate but HUD(like buttons) does rotate.
You can apply transformation to the view you don't want to rotate.
Use following method to do it.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if(interfaceOrientation == UIInterfaceOrientationLandscapeRight)
{
view.transform = CGAffineTransformMakeRotation(-M_PI/2);
}
else if(interfaceOrientation == UIInterfaceOrientationLandscapeLeft)
{
view.transform = CGAffineTransformMakeRotation(M_PI/2);
}
return YES;
}
Related
I want to rotate my UISlider in iPhone landscape layouts and am using this code to to it.
self.customSlider.transform = CGAffineTransformMakeRotation(M_PI/2);
However, I want to use it in -(void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator so that it rotates appropriately based on size classes.
I have the following code where I put other rotation code
-(void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id)coordinator {
[super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
if ([UIDevice currentDevice].orientation == UIDeviceOrientationLandscapeLeft) {
self.stillCamera.outputImageOrientation = UIInterfaceOrientationLandscapeRight;
}
if ([UIDevice currentDevice].orientation == UIDeviceOrientationLandscapeRight) {
self.stillCamera.outputImageOrientation = UIInterfaceOrientationLandscapeLeft;
}
if ([UIDevice currentDevice].orientation == UIDeviceOrientationPortrait) {
self.stillCamera.outputImageOrientation = UIDeviceOrientationPortrait;
}
}
I want to make sure that the UISlider is in the proper orientation in each orientation with the left edge of the slider on top in landscape and the right on the bottom. I need to check the rotation to make sure that slider is in the right position regardless of how the user rotates from portrait to landscape left or right. How can I do this?
EDIT:
I am using GPUImage and the preview view uses an orientation left/right for that view, so I need to find an implementation that allows me to keep that while also allowing for general size class customization.
I figured it out
First - place the UISlider in a container view and pin that container view as needed.
Pin the UISlider to the container view in portrait - either centered horizontally/vertically with equal height/width to container.
In landscape, pin container view as needed with UISlider centered H/V with equal width to container.
In
-(void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
[super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
if ([UIDevice currentDevice].orientation == UIDeviceOrientationLandscapeLeft) {
self.stillCamera.outputImageOrientation = UIInterfaceOrientationLandscapeRight;
self.customSlider.transform = CGAffineTransformMakeRotation(M_PI/2);
}
if ([UIDevice currentDevice].orientation == UIDeviceOrientationLandscapeRight) {
self.stillCamera.outputImageOrientation = UIInterfaceOrientationLandscapeLeft;
self.customSlider.transform = CGAffineTransformMakeRotation(M_PI/2);
}
if ([UIDevice currentDevice].orientation == UIDeviceOrientationPortrait) {
self.stillCamera.outputImageOrientation = UIDeviceOrientationPortrait;
self.customSlider.transform = CGAffineTransformIdentity;
}
}
My code is very simple. I want to change the positioning of an SKSpriteNode to always remain in the bottom right corner of the device screen. I call my UIDeviceOrientationDidChangeNotification method "rotated" on device rotation and it should simply move the node, but for some reason it always flips the desired location so the landscape position is where the portrait should be and vice-versa.
My code is as follows:
UI
- (void)rotated:(NSNotification *)notification {
DeviceOrientation deviceOrientation = [UIDevice currentDevice].orientation;
if (UIDeviceOrientationIsLandscape(deviceOrientation) && !_isShowingLandscapeView)
[self.node setPosition:bottom_right];
_isShowingLandscapeView = YES;
}
else if (UIDeviceOrientationIsPortrait(deviceOrientation) && _isShowingLandscapeView)
{
[self.node setPosition:bottom_right];
_isShowingLandscapeView = NO;
}
}
Ok so what I'm doing is simple. Just use UIButtons over your SKScene. Go back to the UIViewController where you call your skscene from and add buttons. You'll have to use NSNotification center to pass information to the buttons, labels, etc.
http://www.raywenderlich.com/forums/viewtopic.php?f=2&t=8843
I add a AVCaptureVideoPreviewLayer pretty much based on Apple's documentation about AVCaptureVideoPreviewLayer as the following:
AVCaptureSession *captureSession = <#Get a capture session#>;<br>
AVCaptureVideoPreviewLayer *previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:captureSession];<br>
UIView *aView = <#The view in which to present the layer#>;<br>
previewLayer.frame = aView.bounds; // Assume you want the preview layer to fill the view.<br>
[aView.layer addSublayer:previewLayer];
I added the didRotateFromInterfaceOrientation function in order to handle the rotation with the following code:
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
[super didRotateFromInterfaceOrientation:fromInterfaceOrientation];
[self.videoPreviewLayer setFrame:self.view.layer.bounds];
[self.videoPreviewLayer.connection setVideoOrientation:[self getAVCaptureVideoOrientation]];
}
- (AVCaptureVideoOrientation)getAVCaptureVideoOrientation {
UIDeviceOrientation deviceOrientation = [[UIDevice currentDevice] orientation];
if ( deviceOrientation == UIDeviceOrientationLandscapeLeft )
return AVCaptureVideoOrientationLandscapeRight;
else if
// and other 3 orientations
// ...
}
The result looks okay but but animation not so good. The camera layer doesn't start resizing until the rotation finished and I can see the background view during the rotation.
http://yzhong.co/wp-content/uploads/2015/03/My_Movie_1_-_Small.gif
Then I start looking around and found these two SO questions: Problems automatically resizing AVCaptureVideoPreviewLayer on rotation and AVCaptureVideoPreviewLayer smooth orientation rotation. I tried the solutions proposed in those question and added the following function:
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
if (_videoPreviewLayer) {
if (toInterfaceOrientation==UIInterfaceOrientationPortrait) {
[self.videoPreviewLayer setAffineTransform:CGAffineTransformMakeRotation(0)];
} else if (toInterfaceOrientation==UIInterfaceOrientationLandscapeLeft) {
[self.videoPreviewLayer setAffineTransform:CGAffineTransformMakeRotation(M_PI/2)];
} else if (toInterfaceOrientation==UIInterfaceOrientationLandscapeRight) {
[self.videoPreviewLayer setAffineTransform:CGAffineTransformMakeRotation(-M_PI/2)];
} else {
[self.videoPreviewLayer setAffineTransform:CGAffineTransformMakeRotation(M_PI)];
}
self.videoPreviewLayer.frame = self.view.bounds;
}
}
And I get this following, which is a lot better. However, the animation is still a little weird. It seems like it is rotating backward and then forward to the right position? Now I have no clue what to do next.
http://yzhong.co/wp-content/uploads/2015/03/My_Movie_2_-_Small.gif
What I am looking for is really very simple. I want to have a nice, smooth and natural transition/rotation such as the Apple's default camera app does. Could anyone tell me what I am doing wrong here?
http://yzhong.co/wp-content/uploads/2015/03/My_Movie_3_-_Small.gif
Please help!
I have two views in my app; "Calculator" and the "Tape". I can click on the button inside calculator to get to the tape and vice versa. I set the rotation as per code below and it works fine most of the time.
However there are issues if I rotate either calculator view or tape view to landscape and then if I try to access other view, interface is all messed up like it doesn't recognize that device was already rotated. Any suggestions?
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation) toInterfaceOrientation duration:(NSTimeInterval)duration
{
[self doLayoutForOrientation:toInterfaceOrientation];
}
- (void)doLayoutForOrientation:(UIInterfaceOrientation)orientation {
if (UIInterfaceOrientationIsPortrait(orientation))
{
//set the frames here
}
else
{
//set the frames here
}
}
write these codes in the view will appear of each view.
UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
if(orientation == UIInterfaceOrientationLandscapeLeft || orientation == UIInterfaceOrientationLandscapeRight)
{
//adjust the view for landscape
}
else if(orientation == UIInterfaceOrientationPortrait || orientation == UIInterfaceOrientationPortraitUpsideDown)
{
//adjust the view for portrait.
}
In many situation need to rotate the controller and is not working.
Right now I have the inverse of the problem: it is rotating, and I want to disable.
In that ViewController I have this:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait || interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown);
}
but it is auto-rotating, because not this UIViewController is asked, but his parent in UI tree. Maybe that is the problem. The root controller must return Yes for all cases, because there are a few other UIViewControllers on the stack, which has / must have Portait / Landscape support.
I can't / don't want to touch other parts, because ... there are several reasons, for eg: the app is huge, with lot of know bugs and I don't want to make 1 and test it for 1 week, other is the deadline.
Please don't suggest it shouldn't be like this and must rewritten. I know.
How to deal with this controller to force Portait ?
Please read the bolded text too: can't force the whole app to support only Portait for 1 view controller, there are many on stack!
Try marking the app's supported Interface orientations in the properties file to only being portrait. But then of course in that function you just return YES on view controllers that you want to allow rotation. But then when you push it back in the stack the other views should be portrait.
detect the Landscape rotation and rotate to Portait:
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
UIInterfaceOrientation appOrientation = [UIApplication sharedApplication].statusBarOrientation;
float width = self.view.bounds.size.width;
float height = self.view.bounds.size.height;
//NSLog(#"width %3.0f, height: %3.0f", width, height);
if((fromInterfaceOrientation == UIInterfaceOrientationPortrait || fromInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown)){
// if is rotated from Portait:
if((appOrientation == UIInterfaceOrientationLandscapeLeft || appOrientation == UIInterfaceOrientationLandscapeRight)){
// to Landscape:
CGAffineTransform transform = self.view.transform;
transform = CGAffineTransformRotate(transform, -(M_PI / 2.0));
self.view.transform = transform;
[self.view setBounds:CGRectMake(0, 0, height, width)];
}
}
else {
// it is rotated from Landscape:
if((appOrientation == UIInterfaceOrientationPortrait || appOrientation == UIInterfaceOrientationPortraitUpsideDown)){
// to Portrait:
CGAffineTransform transform = self.view.transform;
transform = CGAffineTransformRotate(transform, +(M_PI / 2.0));
self.view.transform = transform;
[self.view setBounds:CGRectMake(0, 0, height, width)];
}
}
}
it isn't the best programming paradigm, but it does the trick.
Somebody write similar like tis to accept his answer, or write a better method, if you can!