renzifeng/ZFPlayer

iOS 16横屏后瞬间又变回竖屏

limengka opened this issue · 28 comments

点击横屏按钮 横屏后瞬间又变回竖屏是啥原因

Yloya commented

我也遇到了这种状况 而且再退出播放页面之后点击事件都无法响应了

一样的问题 横屏后瞬间又变回竖屏 再退出播放页面之后点击事件都无法响应了

哥哥姐姐们啊,转屏问题麻烦看看readme里转屏适配啊

哥哥姐姐们啊,转屏问题麻烦看看readme里转屏适配啊

func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
    let orientationMask: ZFInterfaceOrientationMask  = ZFLandscapeRotationManager.supportedInterfaceOrientations(for: window) as ZFInterfaceOrientationMask
    if orientationMask != .unknow {
        //报错 'unknow' is unavailable: use [] to construct an empty option set
    }else{
        return .portrait
    }

swift这个判断进行不下去,我太菜了[捂脸]

Yloya commented

哥哥姐姐们啊,转屏问题麻烦看看readme里转屏适配啊

大神,试过了,还是会有偶发的【点击横屏按钮 横屏后瞬间又变回竖屏】这种情况呢

你们是不是在播放器这使用了YYTextView

Yloya commented

你们是不是在播放器这使用了YYTextView

没有用到YYTextView

目前已知的有初始化过YYTextView会导致转屏失败,这样适配试试,如果不是这个原因,那就得具体问题具体分享了,排查一下项目里有没有其他window

    self.player.orientationDidChanged = ^(ZFPlayerController * _Nonnull player, BOOL isFullScreen) {
        // 使用YYTextView转屏失败
        for (UIWindow *window in [UIApplication sharedApplication].windows) {
            if ([window isKindOfClass:NSClassFromString(@"YYTextEffectWindow")]) {
                window.hidden = isFullScreen;
            }
        }
    };
Yloya commented

目前已知的有初始化过YYTextView会导致转屏失败,这样适配试试,如果不是这个原因,那就得具体问题具体分享了,排查一下项目里有没有其他window

    self.player.orientationDidChanged = ^(ZFPlayerController * _Nonnull player, BOOL isFullScreen) {
        // 使用YYTextView转屏失败
        for (UIWindow *window in [UIApplication sharedApplication].windows) {
            if ([window isKindOfClass:NSClassFromString(@"YYTextEffectWindow")]) {
                window.hidden = isFullScreen;
            }
        }
    };

大神,我检查了window,排除了类似YYTextEffectWindow的影响,现在再退出播放页面之后点击事件都正常响应了,但是还是会出现【点击横屏按钮 横屏后瞬间又变回竖屏】这种情况

遇到了同样的问题,我是这样解决的,作者抖音demo的VC里orientationWillChange把appdelgate.allowOrentitaionRotation = isFullScreen;这行代码去掉就可以了。
self.player.orientationWillChange = ^(ZFPlayerController * _Nonnull player, BOOL isFullScreen) {
@zf_strongify(self)
if (isFullScreen) {
self.player.disablePanMovingDirection = ZFPlayerDisablePanMovingDirectionNone;
} else {
self.player.disablePanMovingDirection = ZFPlayerDisablePanMovingDirectionAll;
}
self.player.controlView.hidden = YES;
};

我也碰到了这个问题,解决方式如下:
一、先按作者写的旋转配置改一下。
注意,较早的版本(如果我没记错的话)在AppDelegate里面控制旋转方法里面是实现了

    // 可以这么写
    if (self.allowOrentitaionRotation) {
        return UIInterfaceOrientationMaskAllButUpsideDown;
    }

较早的版本以前会在VC中调用以下以处理导航栏消失的问题:

 self.player.orientationWillChange = ^(ZFPlayerController * _Nonnull player, BOOL isFullScreen) {
        XXXXXXX
 };

作者说在4.1.0修复了导航栏消失的问题,所以可以按需去掉self.player.orientationWillChange = ...的整个调用,或者直接去掉回调里面的 appdelgate.allowOrentitaionRotation = isFullScreen,或者修改或者去掉AppDelegate里的

    // 可以这么写
    if (self.allowOrentitaionRotation) {
        ZFInterfaceOrientationMask orientationMask = [ZFLandscapeRotationManager supportedInterfaceOrientationsForWindow:window];
         if (orientationMask != ZFInterfaceOrientationMaskUnknow) {
             return (UIInterfaceOrientationMask)orientationMask;
         }
    }

自己看着改呗

getTransformRotationAngle

func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
    
    var orientationMask: ZFInterfaceOrientationMask = .portrait
    if #available(iOS 16.0, *) {
        orientationMask = ZFLandscapeRotationManager_iOS16.supportedInterfaceOrientations(for: window)

    }else if #available(iOS 15.0, *) {
        orientationMask = ZFLandscapeRotationManager_iOS15.supportedInterfaceOrientations(for: window)

    }else{
        orientationMask = ZFLandscapeRotationManager.supportedInterfaceOrientations(for: window)
    }
    
   if #available(iOS 16.0, *) {
        if allowOrentitaionRotation {
            return UIInterfaceOrientationMask.landscape
        } else {
            return UIInterfaceOrientationMask.portrait
        }
    }else {
        if orientationMask != [] {
            if orientationMask == .portrait {
                return UIInterfaceOrientationMask.portrait
            }else if orientationMask == .landscapeLeft {
                return UIInterfaceOrientationMask.landscapeLeft
            }else if orientationMask == .landscapeRight {
                return UIInterfaceOrientationMask.landscapeRight
            }else if orientationMask == .landscape {
                return UIInterfaceOrientationMask.landscape
            }else if orientationMask == .portraitUpsideDown {
                return UIInterfaceOrientationMask.portraitUpsideDown
            }else if orientationMask == .all {
                return UIInterfaceOrientationMask.all
            }else if orientationMask == .allButUpsideDown {
                return UIInterfaceOrientationMask.allButUpsideDown
            }else{
                return UIInterfaceOrientationMask.all
            }

        }else{
            return UIInterfaceOrientationMask.portrait
        }
    }         
}

更新到4.1.4后,这么写,初步解决了我自己的iOS15.7,及iOS16旋转问题,目前发现在iPhone7P的iOS15.4上,多次旋转,竖屏进度条会是横屏的,没变过来

func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
    
    var orientationMask: ZFInterfaceOrientationMask = .portrait
    if #available(iOS 16.0, *) {
        orientationMask = ZFLandscapeRotationManager_iOS16.supportedInterfaceOrientations(for: window)

    }else if #available(iOS 15.0, *) {
        orientationMask = ZFLandscapeRotationManager_iOS15.supportedInterfaceOrientations(for: window)

    }else{
        orientationMask = ZFLandscapeRotationManager.supportedInterfaceOrientations(for: window)
    }
    
   if #available(iOS 16.0, *) {
        if allowOrentitaionRotation {
            return UIInterfaceOrientationMask.landscape
        } else {
            return UIInterfaceOrientationMask.portrait
        }
    }else {
        if orientationMask != [] {
            if orientationMask == .portrait {
                return UIInterfaceOrientationMask.portrait
            }else if orientationMask == .landscapeLeft {
                return UIInterfaceOrientationMask.landscapeLeft
            }else if orientationMask == .landscapeRight {
                return UIInterfaceOrientationMask.landscapeRight
            }else if orientationMask == .landscape {
                return UIInterfaceOrientationMask.landscape
            }else if orientationMask == .portraitUpsideDown {
                return UIInterfaceOrientationMask.portraitUpsideDown
            }else if orientationMask == .all {
                return UIInterfaceOrientationMask.all
            }else if orientationMask == .allButUpsideDown {
                return UIInterfaceOrientationMask.allButUpsideDown
            }else{
                return UIInterfaceOrientationMask.all
            }

        }else{
            return UIInterfaceOrientationMask.portrait
        }
    }         
}

更新到4.1.4后,这么写,初步解决了我自己的iOS15.7,及iOS16旋转问题,目前发现在iPhone7P的iOS15.4上,多次旋转,竖屏进度条会是横屏的,没变过来

@shls77cxl
请教此处的allowOrentitaionRotation 是您在 appdeleget 声明的 ZFPlayer吗?

6c2e7d7b45cc968964bdb4f7f784e0eb.png

func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
    
    var orientationMask: ZFInterfaceOrientationMask = .portrait
    if #available(iOS 16.0, *) {
        orientationMask = ZFLandscapeRotationManager_iOS16.supportedInterfaceOrientations(for: window)

    }else if #available(iOS 15.0, *) {
        orientationMask = ZFLandscapeRotationManager_iOS15.supportedInterfaceOrientations(for: window)

    }else{
        orientationMask = ZFLandscapeRotationManager.supportedInterfaceOrientations(for: window)
    }
    
   if #available(iOS 16.0, *) {
        if allowOrentitaionRotation {
            return UIInterfaceOrientationMask.landscape
        } else {
            return UIInterfaceOrientationMask.portrait
        }
    }else {
        if orientationMask != [] {
            if orientationMask == .portrait {
                return UIInterfaceOrientationMask.portrait
            }else if orientationMask == .landscapeLeft {
                return UIInterfaceOrientationMask.landscapeLeft
            }else if orientationMask == .landscapeRight {
                return UIInterfaceOrientationMask.landscapeRight
            }else if orientationMask == .landscape {
                return UIInterfaceOrientationMask.landscape
            }else if orientationMask == .portraitUpsideDown {
                return UIInterfaceOrientationMask.portraitUpsideDown
            }else if orientationMask == .all {
                return UIInterfaceOrientationMask.all
            }else if orientationMask == .allButUpsideDown {
                return UIInterfaceOrientationMask.allButUpsideDown
            }else{
                return UIInterfaceOrientationMask.all
            }

        }else{
            return UIInterfaceOrientationMask.portrait
        }
    }         
}

更新到4.1.4后,这么写,初步解决了我自己的iOS15.7,及iOS16旋转问题,目前发现在iPhone7P的iOS15.4上,多次旋转,竖屏进度条会是横屏的,没变过来

@shls77cxl
请教此处的allowOrentitaionRotation 是您在 appdeleget 声明的 ZFPlayer吗?

6c2e7d7b45cc968964bdb4f7f784e0eb.png

appdelegate声明的一个bool值,点击播放器旋转按钮会改变这个值

shyh5 commented
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
    
    var orientationMask: ZFInterfaceOrientationMask = .portrait
    if #available(iOS 16.0, *) {
        orientationMask = ZFLandscapeRotationManager_iOS16.supportedInterfaceOrientations(for: window)

    }else if #available(iOS 15.0, *) {
        orientationMask = ZFLandscapeRotationManager_iOS15.supportedInterfaceOrientations(for: window)

    }else{
        orientationMask = ZFLandscapeRotationManager.supportedInterfaceOrientations(for: window)
    }
    
   if #available(iOS 16.0, *) {
        if allowOrentitaionRotation {
            return UIInterfaceOrientationMask.landscape
        } else {
            return UIInterfaceOrientationMask.portrait
        }
    }else {
        if orientationMask != [] {
            if orientationMask == .portrait {
                return UIInterfaceOrientationMask.portrait
            }else if orientationMask == .landscapeLeft {
                return UIInterfaceOrientationMask.landscapeLeft
            }else if orientationMask == .landscapeRight {
                return UIInterfaceOrientationMask.landscapeRight
            }else if orientationMask == .landscape {
                return UIInterfaceOrientationMask.landscape
            }else if orientationMask == .portraitUpsideDown {
                return UIInterfaceOrientationMask.portraitUpsideDown
            }else if orientationMask == .all {
                return UIInterfaceOrientationMask.all
            }else if orientationMask == .allButUpsideDown {
                return UIInterfaceOrientationMask.allButUpsideDown
            }else{
                return UIInterfaceOrientationMask.all
            }

        }else{
            return UIInterfaceOrientationMask.portrait
        }
    }         
}

更新到4.1.4后,这么写,初步解决了我自己的iOS15.7,及iOS16旋转问题,目前发现在iPhone7P的iOS15.4上,多次旋转,竖屏进度条会是横屏的,没变过来
您好,我用了您的方法,会出现横屏会做两次,请问有遇到这种情况吗

测试过OC环境没有该问题,Swift的项目就会出现

测试过OC环境没有该问题,Swift的项目就会出现

self.player.orientationWillChange = { (player, isFullScreen) in

    if #available(iOS 16.0, *) {
        var requestOrientation: UIInterfaceOrientationMask = .portrait
        if isFullScreen {
            requestOrientation = .landscape
        }
        if let scene = UIApplication.shared.connectedScenes.first as? UIWindowScene {
            let geometryPreferencesios = UIWindowScene.GeometryPreferences.iOS.init(interfaceOrientations: requestOrientation)
            scene.requestGeometryUpdate(geometryPreferencesios) { error in
                print("强制旋转 错误 \(error)")
            }
        }
    }
}

这样能暂时解决问题,旋转都适合会有抖动的小问题。部分机型还是会变回竖屏。

func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
        if window is ZFLandscapeWindow {
            return [.landscape]
        }
        return .portrait
    }

目前这个没有发现问题

测试过OC环境没有该问题,Swift的项目就会出现

self.player.orientationWillChange = { (player, isFullScreen) in

    if #available(iOS 16.0, *) {
        var requestOrientation: UIInterfaceOrientationMask = .portrait
        if isFullScreen {
            requestOrientation = .landscape
        }
        if let scene = UIApplication.shared.connectedScenes.first as? UIWindowScene {
            let geometryPreferencesios = UIWindowScene.GeometryPreferences.iOS.init(interfaceOrientations: requestOrientation)
            scene.requestGeometryUpdate(geometryPreferencesios) { error in
                print("强制旋转 错误 \(error)")
            }
        }
    }
}

这样能暂时解决问题,旋转都适合会有抖动的小问题。部分机型还是会变回竖屏。

是的, OC的Demo没有任何问题, 13和16的系统都可, 但Swift项目就不行了, 都有问题

``
WeChat14e0dc3390a8db93a34078c04f988ba3
WeChatefb4d59dbf6e51b90b05aa36b21236d1
使用这种方法问题解决,参考作者的屏幕适配。

遇到同样的问题,在iOS16系统上出现横屏瞬间又返回竖屏,没有用到YYTextView。项目为swift为主,部分OC混编。
更新4.1.4后问题依旧存在,而且退出全屏后无法响应点击事件。

解决方案:
1、处理退出全屏后无法响应点击事件
方法1:

 playerView.orientationDidChanged = { aPlayer, isFullScreen in
            /// 退出全屏
            if !isFullScreen {
                for window in UIApplication.shared.windows {
                    if window is ZFLandscapeWindow {
                        // 手动隐藏
                        window.isHidden = true
                    }
                }
            }
        }

方法2:
改动ZFPlayer源码

ZFLandscapeRotationManager_iOS16.m

- (void)interfaceOrientation:(UIInterfaceOrientation)orientation completion:(void(^ __nullable)(void))completion {
// 原代码不变
...
// 调整判定
if (toOrientation == UIInterfaceOrientationPortrait) {
    self.contentView.bounds = CGRectMake(0, 0, maxSize, minSize);
    self.contentView.center = CGPointMake(minSize * 0.5, maxSize * 0.5);
    self.contentView.transform = [self getRotationTransform:fromOrientation];
    [sourceWindow addSubview:self.contentView];
    [sourceWindow makeKeyAndVisible];
    [self.contentView layoutIfNeeded];
    self.window.hidden = YES;
} else if (fromOrientation == UIInterfaceOrientationPortrait || self.contentView.superview != self.landscapeViewController.view) {
    self.contentView.frame = sourceFrame;
    [sourceWindow addSubview:self.contentView];
    [self.contentView layoutIfNeeded];
    if (!self.window.isKeyWindow) {
        self.window.hidden = NO;
        [self.window makeKeyAndVisible];
    }
}
// 原代码不变
...
}

2、屏幕旋转问题,测试iOS14、iOS15、iOS16系列真机暂无异常

        playerView.orientationWillChange = {aPlayer, isFullScreen in
            if let appdelegate = UIApplication.shared.delegate as? AppDelegate {
                appdelegate.allowOrentitaionRotation = isFullScreen
            }
        }
   func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
        if window is ZFLandscapeWindow {
            var orientationMask: ZFInterfaceOrientationMask = .portrait
            if #available(iOS 16.0, *) {
                orientationMask = ZFLandscapeRotationManager_iOS16.supportedInterfaceOrientations(for: window)
            } else if #available(iOS 15.0, *) {
                orientationMask = ZFLandscapeRotationManager_iOS15.supportedInterfaceOrientations(for: window)
            } else {
                orientationMask = ZFLandscapeRotationManager.supportedInterfaceOrientations(for: window)
            }
            if orientationMask != ZFInterfaceOrientationMask(rawValue: 0) {
                return UIInterfaceOrientationMask(rawValue: orientationMask.rawValue)
            }
        }
        if allowOrentitaionRotation {
            return .allButUpsideDown
        }
        return .portrait
    }
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
        if window is ZFLandscapeWindow {
            return [.landscape]
        }
        return .portrait
    }

目前这个没有发现问题

iOS16上运行是OK的,但低版本就不行,点击全屏之后就直接卡住了😂