Preserve UIView when connecting to UIWindow in iOS8
Prior to iOS7, if I wanted to create some kind of fixed "background" that would not rotate, nor the same or scale, I would simply bind the UIView to the main UIWindow. It was kind of a hack ... but it served its purpose perfectly.
In iOS8, they changed the way UIWindow behaves, among other things (for example, it now [UIScreen mainScreen].bounds
returns a different size based on orientation).
Anyway...
My question is, how do I get iOS8 to behave like iOS7 and below? I've already tried to create two ViewControllers, one with a method shouldAutorotate
set to NO
, but with no luck.
The desired effect is the one shown here:
Any ideas?
source to share
If you are building your app with the iOS8 SDK, you can use nativeBounds , which will always return borders for portrait orientation, but in pixels, not points.
To get the correct boundaries in points, you must divide them by nativeScale
.
if ([[UIScreen mainScreen] respondsToSelector:@selector(nativeBounds)]) {
CGFloat scaleFactor = 1.0f / [self nativeScale];
CGRect realBounds = CGRectApplyAffineTransform([self nativeBounds],
CGAffineTransformMakeScale(scaleFactor, scaleFactor));
}
So I think you can subscribe to the didChangeStatusBarOrientation notification and in your method calculate a new frame for the green square and justify the rotation:
rect.transform = CGAffineTransformMakeRotation((CGFloat)M_PI * (90.f) / 180.0f);
for landscape orientation
source to share
try using this fixed rotation subclass:
@interface RotationView : UIView {
struct {
CGPoint portOrigin;
CGPoint leftOrigin;
CGPoint rightOrigin;
CGPoint upsideOrigin;
} origins;
struct {
NSInteger portDegree;
NSInteger leftDegree;
NSInteger rightDegree;
NSInteger upsideDegree;
} degrees;
}
@end
@implementation RotationView
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(deviceOrientationDidChange:)
name:UIDeviceOrientationDidChangeNotification object:nil];
}
return self;
}
- (void)didMoveToSuperview {
[super didMoveToSuperview];
UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
if (orientation == UIInterfaceOrientationPortrait) {
origins.portOrigin = self.frame.origin;
origins.rightOrigin = CGPointMake(CGRectGetMinY(self.frame), CGRectGetWidth(self.superview.frame) - CGRectGetMinX(self.frame) - CGRectGetWidth(self.frame));
origins.leftOrigin = CGPointMake(CGRectGetHeight(self.superview.frame) - CGRectGetMinY(self.frame) - CGRectGetHeight(self.frame), CGRectGetMinX(self.frame));
origins.upsideOrigin = CGPointMake(CGRectGetWidth(self.superview.frame) - CGRectGetMinX(self.frame) - CGRectGetWidth(self.frame),
CGRectGetHeight(self.superview.frame) - CGRectGetMinY(self.frame) - CGRectGetHeight(self.frame));
degrees.portDegree = 0.0F;
degrees.rightDegree = 270;
degrees.leftDegree = 90.0F;
degrees.upsideDegree = 180.0F;
} else if (orientation == UIInterfaceOrientationPortraitUpsideDown) {
origins.portOrigin = CGPointMake(CGRectGetWidth(self.superview.frame) - CGRectGetMinX(self.frame) - CGRectGetWidth(self.frame),
CGRectGetHeight(self.superview.frame) - CGRectGetMinY(self.frame) - CGRectGetHeight(self.frame));
origins.leftOrigin = CGPointMake(CGRectGetMinY(self.frame), CGRectGetWidth(self.superview.frame) - CGRectGetMinX(self.frame) - CGRectGetWidth(self.frame));
origins.rightOrigin = CGPointMake(CGRectGetHeight(self.superview.frame) - CGRectGetMinY(self.frame) - CGRectGetHeight(self.frame), CGRectGetMinX(self.frame));
origins.upsideOrigin = self.frame.origin;
degrees.portDegree = 180.0F;
degrees.rightDegree = 90.0F;
degrees.leftDegree = 270;
degrees.upsideDegree = 0.0F;
} else if (orientation == UIInterfaceOrientationLandscapeLeft) {
origins.upsideOrigin = CGPointMake(CGRectGetHeight(self.superview.frame) - CGRectGetMinY(self.frame) - CGRectGetHeight(self.frame), CGRectGetMinX(self.frame));
origins.leftOrigin = self.frame.origin;
origins.rightOrigin = CGPointMake(CGRectGetWidth(self.superview.frame) - CGRectGetMinX(self.frame) - CGRectGetWidth(self.frame),
CGRectGetHeight(self.superview.frame) - CGRectGetMinY(self.frame) - CGRectGetHeight(self.frame));
origins.portOrigin = CGPointMake(CGRectGetMinY(self.frame), CGRectGetWidth(self.superview.frame) - CGRectGetMinX(self.frame) - CGRectGetWidth(self.frame));
degrees.upsideDegree = 90.0F;
degrees.leftDegree = 0.0F;
degrees.rightDegree = 180.0F;
degrees.portDegree = 270.0;
} else if (orientation == UIInterfaceOrientationLandscapeRight) {
origins.portOrigin = CGPointMake(CGRectGetHeight(self.superview.frame) - CGRectGetMinY(self.frame) - CGRectGetHeight(self.frame), CGRectGetMinX(self.frame));
origins.leftOrigin = CGPointMake(CGRectGetWidth(self.superview.frame) - CGRectGetMinX(self.frame) - CGRectGetWidth(self.frame),
CGRectGetHeight(self.superview.frame) - CGRectGetMinY(self.frame) - CGRectGetHeight(self.frame));
origins.rightOrigin = self.frame.origin;
origins.upsideOrigin = CGPointMake(CGRectGetMinY(self.frame), CGRectGetWidth(self.superview.frame) - CGRectGetMinX(self.frame) - CGRectGetWidth(self.frame));
degrees.portDegree = 90.0F;
degrees.leftDegree = 180.0F;
degrees.rightDegree = 0.0F;
degrees.upsideDegree = 270.0F;
}
}
#pragma mark Manual oritentation change
#define RADIANS(degrees) ((degrees * (float)M_PI) / 180.0f)
- (void)deviceOrientationDidChange:(NSNotification *)notification {
if (!self.superview) {
return;
}
if ([self.superview isKindOfClass:[UIWindow class]]) {
[self setTransformForCurrentOrientation];
}
}
- (void)setTransformForCurrentOrientation {
UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
if (UIInterfaceOrientationIsLandscape(orientation)) {
if (orientation == UIInterfaceOrientationLandscapeLeft) {
[self setTransform:CGAffineTransformMakeRotation(RADIANS(degrees.leftDegree))];
[self setOrigin:origins.leftOrigin];
} else {
[self setTransform:CGAffineTransformMakeRotation(RADIANS(degrees.rightDegree))];
[self setOrigin:origins.rightOrigin];
}
} else {
if (orientation == UIInterfaceOrientationPortraitUpsideDown) {
[self setTransform:CGAffineTransformMakeRotation(RADIANS(degrees.upsideDegree))];
[self setOrigin:origins.upsideOrigin];
} else {
[self setTransform:CGAffineTransformMakeRotation(RADIANS(degrees.portDegree))];
[self setOrigin:origins.portOrigin];
}
}
}
@end
setOrigin is a category method:
- (void)setX:(CGFloat)x {
CGRect frame = self.frame;
frame.origin.x = x;
self.frame = frame;
}
- (void)setY:(CGFloat)y {
CGRect frame = self.frame;
frame.origin.y = y;
self.frame = frame;
}
- (void)setOrigin:(CGPoint)origin {
[self setX:origin.x];
[self setY:origin.y];
}
source to share