JTPopOverWindow.m 7.09 KB
//
//  JTPopupWindow.m
//  JobTalk
//
//  Created by Xummer on 14-5-20.
//  Copyright (c) 2014年 BST. All rights reserved.
//

#import "JTPopOverWindow.h"

@interface StatusBarViewController : UIViewController
@property (assign, nonatomic) UIStatusBarStyle statusBarStyle;
@end

@implementation StatusBarViewController

- (id)initWithStatusBarStyle:(UIStatusBarStyle)statusBarStyle {
    self = [super init];
    if (!self) {
        return nil;
    }
    
    self.statusBarStyle = statusBarStyle;
    
    return self;
}

- (UIStatusBarStyle)preferredStatusBarStyle {
    return _statusBarStyle;
}

#pragma mark - Route

// Below iOS6 use this method
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    return UIInterfaceOrientationIsPortrait(interfaceOrientation);
}

// Above iOS6 use these two methods
- (BOOL)shouldAutorotate {
    return YES;
}

- (NSUInteger)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskPortrait;
}

@end

@interface JTPopOverWindow ()
@property (weak, nonatomic) UIWindow *previousKeyWindow;

@end

@implementation JTPopOverWindow

#pragma mark - Life Cycle
- (id)init {
    self = [super initWithFrame:[[UIScreen mainScreen] bounds]];
    if (!self) {
        return nil;
    }
    
    self.windowLevel = UIWindowLevelStatusBar;
    self.hidden = YES;
    self.userInteractionEnabled = NO;
    self.backgroundColor = [UIColor clearColor];
    self.vignetteBackground = NO;
    _statusBarStyle = UIStatusBarStyleDefault;
    self.rootViewController = [[StatusBarViewController alloc] initWithStatusBarStyle:_statusBarStyle];
    
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(setRotation:)
                                                 name:UIApplicationDidChangeStatusBarOrientationNotification
                                               object:nil];
    [self setRotation:nil];
    
    return self;
}

- (void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self
                                                    name:UIApplicationDidChangeStatusBarOrientationNotification
                                                  object:nil];
}

- (void)drawRect:(CGRect)rect
{
    if (_backgroundImage || !_vignetteBackground) return;
    CGContextRef context = UIGraphicsGetCurrentContext();
    
	size_t locationsCount = 2;
	CGFloat locations[2] = {0.0f, 1.0f};
	CGFloat colors[8] = {0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.75f};
	CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
	CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace, colors, locations, locationsCount);
	CGColorSpaceRelease(colorSpace);
	
	CGPoint center = CGPointMake(self.bounds.size.width/2, self.bounds.size.height/2);
	float radius = MIN(self.bounds.size.width , self.bounds.size.height) ;
	CGContextDrawRadialGradient (context, gradient, center, 0, center, radius, kCGGradientDrawsAfterEndLocation);
	CGGradientRelease(gradient);
}

#pragma mark - Setter
- (void)setStatusBarStyle:(UIStatusBarStyle)statusBarStyle {
    
    if (_statusBarStyle == statusBarStyle) {
        return;
    }
    
    _statusBarStyle = statusBarStyle;
    self.rootViewController = [[StatusBarViewController alloc] initWithStatusBarStyle:_statusBarStyle];
}



#pragma mark - Public Method

+ (instancetype)sharedInstance {
    static JTPopOverWindow *_sharedInstance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _sharedInstance = [[self alloc] init];
    });
    
    return _sharedInstance;
}

- (void)addToMainWindow:(UIView *)view {
    [self setRotation:nil];
    
    if ([self.subviews containsObject:view]) {
        return;
    }
    
    if (self.hidden)  {
        self.previousKeyWindow = [[UIApplication sharedApplication] keyWindow];
        self.alpha = 0.0f;
        self.hidden = NO;
        [self makeKeyWindow];
    }
    
    // if something's been added to this window, then this window should have interaction
    self.userInteractionEnabled = YES;
    
    if (self.subviews.count > 1) {
        ((UIView*)[self.subviews lastObject]).userInteractionEnabled = NO;
    }
    
    if (_backgroundImage) {
        UIImageView *backgroundView = [[UIImageView alloc] initWithImage:_backgroundImage];
        backgroundView.frame = self.bounds;
        backgroundView.contentMode = UIViewContentModeScaleToFill;
        [self addSubview:backgroundView];
        _backgroundImage = nil;
    }
    
    [self addSubview:view];
}

- (void)removeView:(UIView *)view {
    [view removeFromSuperview];
    
    UIView *topView = [self.subviews lastObject];
    if ([topView isKindOfClass:[UIImageView class]]) {
        // It's a background. Remove it too
        [topView removeFromSuperview];
    }
    
    // It's a view which belong to |StatusBarViewController|
    [self.rootViewController.view removeFromSuperview];
    
    if (self.subviews.count == 0) {
        self.hidden = YES;
        [_previousKeyWindow makeKeyWindow];
        _previousKeyWindow = nil;
    }
    else {
        ((UIView*)[self.subviews lastObject]).userInteractionEnabled = YES;
    }
}

- (void)reduceAlphaIfEmpty {
    if (self.subviews.count == 1 || (self.subviews.count == 2 && [[self.subviews objectAtIndex:0] isKindOfClass:[UIImageView class]]))
    {
        self.alpha = 0.0f;
        self.userInteractionEnabled = NO;
    }
}

#pragma mark - Private Method
- (void)setRotation:(NSNotification*)notification {
    UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
    
    CGRect orientationFrame = [UIScreen mainScreen].bounds;
    
    if(
       (UIInterfaceOrientationIsLandscape(orientation) && orientationFrame.size.height > orientationFrame.size.width) ||
       (UIInterfaceOrientationIsPortrait(orientation) && orientationFrame.size.width > orientationFrame.size.height)
       ) {
        float temp = orientationFrame.size.width;
        orientationFrame.size.width = orientationFrame.size.height;
        orientationFrame.size.height = temp;
    }
    
    self.transform = CGAffineTransformIdentity;
    self.frame = orientationFrame;
    
    CGFloat posY = orientationFrame.size.height/2;
    CGFloat posX = orientationFrame.size.width/2;
    
    CGPoint newCenter;
    CGFloat rotateAngle;
    
    switch (orientation) {
        case UIInterfaceOrientationPortraitUpsideDown:
            rotateAngle = M_PI;
            newCenter = CGPointMake(posX, orientationFrame.size.height-posY);
            break;
        case UIInterfaceOrientationLandscapeLeft:
            rotateAngle = -M_PI/2.0f;
            newCenter = CGPointMake(posY, posX);
            break;
        case UIInterfaceOrientationLandscapeRight:
            rotateAngle = M_PI/2.0f;
            newCenter = CGPointMake(orientationFrame.size.height-posY, posX);
            break;
        default: // UIInterfaceOrientationPortrait
            rotateAngle = 0.0;
            newCenter = CGPointMake(posX, posY);
            break;
    }
    
    self.transform = CGAffineTransformMakeRotation(rotateAngle);
    self.center = newCenter;
    
    [self setNeedsLayout];
    [self layoutSubviews];
}

@end