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:

enter image description hereenter image description here

Any ideas?

+3


source to share


2 answers


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

0


source


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];
}

      

0


source







All Articles