Flutter知识库

Flutter混合栈实践

2019-10-20  本文已影响0人  whqfor
混合栈产生原因

Flutter热度很高,无论大小公司都跃跃预试,接入的形式可能是:

*已有项目为主部分模块接入Flutter,
*新开Flutter项目部分Native,
*完全Flutter项目

除了最后一种情况不用考虑混合栈的问题,上面两种情况都需要考虑Native和Flutter的交互,其中Native和Flutter间的页面就是要讲述的混合栈问题。

一个场景:
Flutter Page1 -> Native Page1 -> Flutter Page2 -> Native Page1 -> Flutter Page1
解决方案

由于承载Flutter的项根控制器FlutterViewController不带导航栏的,所以推出Hybrid页面时只能模态推出,这样造成了动画效果的割裂,我们采用的方式是自定义转场动画,核心代码如下:
推出

- (void)presentViewController:(id <UIViewControllerContextTransitioning>)transitionContext
{
    UIView *fromView = [transitionContext viewForKey:UITransitionContextFromViewKey];
    UIView *toView = [transitionContext viewForKey:UITransitionContextToViewKey];
    UIView *containerView = [transitionContext containerView];
    [containerView addSubview:toView];
    
    CGRect frame = toView.frame;
    frame.origin.x = [[UIScreen mainScreen] bounds].size.width;
    toView.frame = frame;
    
    // 保存当前页面的截图
    self.snapshotView = [fromView snapshotViewAfterScreenUpdates:NO];
    
    [UIView animateWithDuration:[self transitionDuration:transitionContext] delay:0
                        options:UIViewAnimationOptionTransitionFlipFromLeft animations:^{
        CGRect frame = toView.frame;
        frame.origin.x = 0;
        toView.frame = frame;
    } completion:^(BOOL finished) {
        [transitionContext completeTransition:YES];
    }];
}

返回

- (void)dismissViewController:(id <UIViewControllerContextTransitioning>)transitionContext toRight:(BOOL)toRight
{
    UIView *fromView = [transitionContext viewForKey:UITransitionContextFromViewKey];
    UIView *containerView = [transitionContext containerView];
    
    // 展示上个页面的截图
    [containerView addSubview:self.snapshotView];
    [containerView addSubview:fromView];
    
    [UIView animateWithDuration:[self transitionDuration:transitionContext] delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
        CGRect frame = fromView.frame;
        frame.origin.x = (toRight ? 1 : -1) * [[UIScreen mainScreen] bounds].size.width;
        fromView.frame = frame;
    } completion:^(BOOL finished) {
        [self.snapshotView removeFromSuperview];
        self.snapshotView = nil;
        [transitionContext completeTransition:YES];
    }];
}

如果需要保存之前的Hybrid页面的话,可以进行状态保存,具体流程如下图:

混合栈.png
问题与不足
let controller : FlutterViewController = app.delegate!.window!!.rootViewController as! FlutterViewController;

具体选择哪种方式,还要结合自己的业务进行,如果Native为主可以选择flutter_boost,如果flutter为主,我们的方式也是个参考。

上一篇 下一篇

猜你喜欢

热点阅读