美文网首页
Flutter 记一次屏幕旋转实践

Flutter 记一次屏幕旋转实践

作者: mtko | 来源:发表于2020-04-06 20:25 被阅读0次

    两个方案:

    一、Flutter旋转

    使用orientation

    一开始一直旋转不动,后来检查原生代码,发现window的旋转被原生所限制了

    func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
        return .portrait
    }
    

    现在有两个方案:

    1.不重写supportedInterfaceOrientationsFor window:,采用单个控制器旋转的方案,关闭自动旋转,在控制器中重写supportedInterfaceOrientations修改返回值,在Flutter中使用orientation旋转,但存在旋转失败的情况;开启自动旋转,有时可旋转成功有时不可,并且需求本身不需要自动旋转
    2.重写supportedInterfaceOrientationsFor window:,使用orientation旋转,监听Flutter页面进出,修改supportedInterfaceOrientationsFor window:

    结论:2方案最可行,但在android端出现orientation插件一直注册失败的情况,原因未知

    二、原生旋转(推荐

    自定义State基类,在基类中使用flutter_page_tracker监听页面Flutter进出,并通知原生页面进出消息并传出页面路由,让原生控制旋转window

    Flutter:

      /// 页面进入
      @override
      void didPageView() {
        super.didPageView();
        //通知原生可操作旋转
      }
      
      /// 页面退出
      @override
      void didPageExit() {
        super.didPageExit();
        //通知原生可操作旋转
      }
    
      /// 点击自定义的转屏按钮
      void manualRotate() {
        //通知原生可操作旋转
      }
    

    iOS:

    let APPLICATION =  UIApplication.shared.delegate as! AppDelegate
    
    @UIApplicationMain
    class AppDelegate: UIResponder, UIApplicationDelegate {
        var orientation = UIInterfaceOrientationMask.portrait
    }
    
    // 收到Flutter页面进出消息
    func receivedRouteEnterOrExitMessage(message: String) {
         let message = message.jsonObject
         let route = message["route"] as! String
         let enter = message["enter"] as! bool
         if route == "needRotateViewRoute" {
            APPLICATION.orientation = enter ? .landscapeRight : .portrait
            UIDevice.current.setValue(APPLICATION.orientation.rawValue, forKey: "orientation")
        }  
    }
    
     // 收到Flutter手动点击转屏消息
    func receivedManualRotateMessage() {
        if APPLICATION.orientation == .portrait {
            APPLICATION.orientation = . landscapeRight
        } else {
            APPLICATION.orientation = .portrait
        }
        UIDevice.current.setValue(APPLICATION.orientation.rawValue, forKey: "orientation")
    }
    
    // 旋转window
    func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
        return APPLICATION.orientation
    }
    

    Tip:
    对于混合项目,其实原生监听Flutter页面进出很有必要,因为页面进出这个时点是业务处理逻辑的集中期且很有可能需要监听页面的进出

    相关文章

      网友评论

          本文标题:Flutter 记一次屏幕旋转实践

          本文链接:https://www.haomeiwen.com/subject/fkciphtx.html