单军华
2018-07-12 3e8437ae559487362fae3525beb79c534c213a51
screendisplay/Pods/ZFPlayer/ZFPlayer/Classes/Core/ZFOrientationObserver.m
New file
@@ -0,0 +1,281 @@
//  ZFOrentationObserver.m
//  ZFPlayer
//
// Copyright (c) 2016年 任子丰 ( http://github.com/renzifeng )
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#import "ZFOrientationObserver.h"
@interface UIWindow (CurrentViewController)
/*!
 @method currentViewController
 @return Returns the topViewController in stack of topMostController.
 */
+ (UIViewController*)zf_currentViewController;
@end
@implementation UIWindow (CurrentViewController)
+ (UIViewController*)zf_currentViewController; {
    UIWindow *window = [[UIApplication sharedApplication].delegate window];
    UIViewController *topViewController = [window rootViewController];
    while (true) {
        if (topViewController.presentedViewController) {
            topViewController = topViewController.presentedViewController;
        } else if ([topViewController isKindOfClass:[UINavigationController class]] && [(UINavigationController*)topViewController topViewController]) {
            topViewController = [(UINavigationController *)topViewController topViewController];
        } else if ([topViewController isKindOfClass:[UITabBarController class]]) {
            UITabBarController *tab = (UITabBarController *)topViewController;
            topViewController = tab.selectedViewController;
        } else {
            break;
        }
    }
    return topViewController;
}
@end
static UIWindow *kWindow;
@interface ZFOrientationObserver ()
@property (nonatomic, weak) UIView *view;
@property (nonatomic, assign, getter=isFullScreen) BOOL fullScreen;
@property (nonatomic, assign) NSInteger playerViewIndex;
@property (nonatomic, strong) UIView *cell;
@property (nonatomic, assign) NSInteger playerViewTag;
@property (nonatomic, assign) ZFRotateType roateType;
@end
@implementation ZFOrientationObserver
- (instancetype)init {
    self = [super init];
    if (self) {
        _duration = 0.25;
        _fullScreenMode = ZFFullScreenModeLandscape;
        kWindow = [(id)[UIApplication sharedApplication].delegate valueForKey:@"window"];
        _shouldAutorotate = YES;
    }
    return self;
}
- (instancetype)initWithRotateView:(UIView *)rotateView containerView:(UIView *)containerView {
    if ([self init]) {
        _roateType = ZFRotateTypeNormal;
        _view = rotateView;
        _containerView = containerView;
    }
    return self;
}
- (void)cellModelRotateView:(UIView *)rotateView rotateViewAtCell:(UIView *)cell playerViewTag:(NSInteger)playerViewTag {
    self.roateType = ZFRotateTypeCell;
    self.view = rotateView;
    self.cell = cell;
    self.playerViewTag = playerViewTag;
}
- (void)cellSmallModelRotateView:(UIView *)rotateView containerView:(UIView *)containerView {
    self.roateType = ZFRotateTypeCellSmall;
    self.view = rotateView;
    self.containerView = containerView;
}
- (void)dealloc {
    [self removeDeviceOrientationObserver];
}
- (void)addDeviceOrientationObserver {
    if (![UIDevice currentDevice].generatesDeviceOrientationNotifications) {
        [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
    }
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleDeviceOrientationChange) name:UIDeviceOrientationDidChangeNotification object:nil];
}
- (void)removeDeviceOrientationObserver {
    if (![UIDevice currentDevice].generatesDeviceOrientationNotifications) {
        [[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications];
    }
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIDeviceOrientationDidChangeNotification object:nil];
}
- (void)handleDeviceOrientationChange {
    if (self.fullScreenMode == ZFFullScreenModePortrait) return;
    if (!self.shouldAutorotate) return;
    if (UIDeviceOrientationIsValidInterfaceOrientation([UIDevice currentDevice].orientation)) {
        _currentOrientation = (UIInterfaceOrientation)[UIDevice currentDevice].orientation;
    } else {
        _currentOrientation = UIInterfaceOrientationUnknown;
        return;
    }
    UIInterfaceOrientation currentOrientation = [UIApplication sharedApplication].statusBarOrientation;
    // Determine that if the current direction is the same as the direction you want to rotate, do nothing
    if (_currentOrientation == currentOrientation) return;
    switch (_currentOrientation) {
        case UIInterfaceOrientationPortrait: {
            [self enterLandscapeFullScreen:UIInterfaceOrientationPortrait animated:YES];
        }
            break;
        case UIInterfaceOrientationLandscapeLeft: {
            [self enterLandscapeFullScreen:UIInterfaceOrientationLandscapeLeft animated:YES];
        }
            break;
        case UIInterfaceOrientationLandscapeRight: {
            [self enterLandscapeFullScreen:UIInterfaceOrientationLandscapeRight animated:YES];
        }
            break;
        default: break;
    }
}
- (void)enterLandscapeFullScreen:(UIInterfaceOrientation)orientation animated:(BOOL)animated {
    if (self.fullScreenMode == ZFFullScreenModeLandscape) {
        UIView *superview = nil;
        CGRect frame;
        if (UIInterfaceOrientationIsLandscape(orientation)) {
            superview = kWindow;
            if (!self.isFullScreen) { /// It's not set from the other side of the screen to this side
                self.view.frame = [self.view convertRect:self.view.frame toView:superview];
            }
            for (NSInteger i = 0; i < _containerView.subviews.count; i++) {
                if (self.containerView.subviews[i] == self.view) {
                    self.playerViewIndex = i;
                    break;
                }
            }
            self.fullScreen = YES;
            [superview addSubview:_view];
        } else {
            if (self.roateType == ZFRotateTypeCell) {
                superview = [self.cell viewWithTag:self.playerViewTag];
            } else {
                superview = self.containerView;
            }
            self.fullScreen = NO;
        }
        frame = [superview convertRect:superview.bounds toView:kWindow];
        _currentOrientation = orientation;
        [UIApplication sharedApplication].statusBarOrientation = orientation;
        if (self.orientationWillChange) {
            self.orientationWillChange(self, self.isFullScreen);
        }
        [UIView animateWithDuration:self.duration animations:^{
            self.view.transform = [self getTransformRotationAngle:orientation];
            [UIView animateWithDuration:self.duration animations:^{
                self.view.frame = frame;
                [self.view layoutIfNeeded];
            }];
        } completion:^(BOOL finished) {
            if (!UIInterfaceOrientationIsLandscape(orientation) && self.roateType == ZFRotateTypeNormal) {
                [superview insertSubview:self.view atIndex:self.playerViewIndex];
            } else if (!UIInterfaceOrientationIsLandscape(orientation)) {
                [superview addSubview:self.view];
            }
            self.view.frame = superview.bounds;
            if (self.orientationDidChanged) self.orientationDidChanged(self, self.isFullScreen);
        }];
    }
}
/// Gets the rotation Angle of the transformation.
- (CGAffineTransform)getTransformRotationAngle:(UIInterfaceOrientation)orientation {
    if (UIDeviceOrientationIsLandscape([UIDevice currentDevice].orientation) && orientation == UIInterfaceOrientationPortrait) {
        return CGAffineTransformIdentity;
    }
    if (orientation == UIInterfaceOrientationPortrait) {
        return CGAffineTransformIdentity;
    } else if (orientation == UIInterfaceOrientationLandscapeLeft){
        return CGAffineTransformMakeRotation(-M_PI_2);
    } else if(orientation == UIInterfaceOrientationLandscapeRight){
        return CGAffineTransformMakeRotation(M_PI_2);
    }
    return CGAffineTransformIdentity;
}
- (void)enterPortraitFullScreen:(BOOL)fullScreen animated:(BOOL)animated {
    if (self.fullScreenMode == ZFFullScreenModeLandscape) return;
    UIView *superview = nil;
    if (fullScreen) {
        superview = kWindow;
        self.view.frame = [self.view convertRect:self.view.frame toView:superview];
        [superview addSubview:self.view];
        self.fullScreen = YES;
        if (self.orientationWillChange) {
            self.orientationWillChange(self, self.isFullScreen);
        }
    } else {
        if (self.roateType == ZFRotateTypeCell) {
            superview = [self.cell viewWithTag:self.playerViewTag];
        } else {
            superview = self.containerView;
        }
        self.fullScreen = NO;
        if (self.orientationWillChange) {
            self.orientationWillChange(self, self.isFullScreen);
        }
    }
    CGRect frame = [superview convertRect:superview.bounds toView:kWindow];
    [UIView animateWithDuration:self.duration animations:^{
        self.view.frame = frame;
        [self.view layoutIfNeeded];
    } completion:^(BOOL finished) {
        [superview addSubview:self.view];
        self.view.frame = superview.bounds;
        if (self.orientationDidChanged) {
            self.orientationDidChanged(self, self.isFullScreen);
        }
    }];
}
- (void)setLockedScreen:(BOOL)lockedScreen {
    _lockedScreen = lockedScreen;
    if (lockedScreen) {
        [self removeDeviceOrientationObserver];
    } else {
         [self addDeviceOrientationObserver];
    }
}
- (void)setFullScreen:(BOOL)fullScreen {
    _fullScreen = fullScreen;
    [[UIWindow zf_currentViewController] setNeedsStatusBarAppearanceUpdate];
}
- (void)setStatusBarHidden:(BOOL)statusBarHidden {
    _statusBarHidden = statusBarHidden;
    [[UIWindow zf_currentViewController] setNeedsStatusBarAppearanceUpdate];
}
@end