两个方案:
一、Flutter旋转
一开始一直旋转不动,后来检查原生代码,发现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页面进出很有必要,因为页面进出这个时点是业务处理逻辑的集中期且很有可能需要监听页面的进出
网友评论