FLB2FlutterViewContainer.m 8 KB
Newer Older
Jidong Chen's avatar
init  
Jidong Chen committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
/*
 * The MIT License (MIT)
 * 
 * Copyright (c) 2019 Alibaba Group
 * 
 * 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.
 */

Jidong Chen's avatar
Jidong Chen committed
25 26
#import "FLB2FlutterViewContainer.h"
#import "FLB2FlutterApplication.h"
Jidong Chen's avatar
Jidong Chen committed
27
#import "BoostMessageChannel.h"
28 29
#import "FLB2FlutterContainerManager.h"
#import "FlutterBoostPlugin2_private.h"
Jidong Chen's avatar
init  
Jidong Chen committed
30

31
#define FLUTTER_APP [FlutterBoostPlugin2 sharedInstance].application
Jidong Chen's avatar
Jidong Chen committed
32 33
#define FLUTTER_VIEW FLUTTER_APP.flutterViewController.view
#define FLUTTER_VC FLUTTER_APP.flutterViewController
Jidong Chen's avatar
init  
Jidong Chen committed
34

35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
@interface FlutterViewController (bridgeToviewDidDisappear)
- (void)flushOngoingTouches;
- (void)bridge_viewDidDisappear:(BOOL)animated;
- (void)bridge_viewWillAppear:(BOOL)animated;
@end

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wincomplete-implementation"
@implementation FlutterViewController (bridgeToviewDidDisappear)
- (void)bridge_viewDidDisappear:(BOOL)animated{
//    TRACE_EVENT0("flutter", "viewDidDisappear");
    [self flushOngoingTouches];

    [super viewDidDisappear:animated];
}

- (void)bridge_viewWillAppear:(BOOL)animated{
//    TRACE_EVENT0("flutter", "viewWillAppear");

//    if (_engineNeedsLaunch) {
//      [_engine.get() launchEngine:nil libraryURI:nil];
//      [_engine.get() setViewController:self];
//      _engineNeedsLaunch = NO;
//    }
    [FLUTTER_APP inactive];
    
    [super viewWillAppear:animated];
}
@end
#pragma pop

Jidong Chen's avatar
Jidong Chen committed
66
@interface FLB2FlutterViewContainer  ()
Jidong Chen's avatar
init  
Jidong Chen committed
67 68 69 70
@property (nonatomic,strong,readwrite) NSDictionary *params;
@property (nonatomic,assign) long long identifier;
@end

Jidong Chen's avatar
Jidong Chen committed
71
@implementation FLB2FlutterViewContainer
Jidong Chen's avatar
init  
Jidong Chen committed
72

Jidong Chen's avatar
Jidong Chen committed
73 74 75 76 77 78
- (instancetype)init
{
    [FLUTTER_APP.flutterProvider prepareEngineIfNeeded];
    if(self = [super initWithEngine:FLUTTER_APP.flutterProvider.engine
                            nibName:nil
                             bundle:nil]){
79 80
        //NOTES:在present页面时,默认是全屏,如此可以触发底层VC的页面事件。否则不会触发而导致异常
        self.modalPresentationStyle = UIModalPresentationFullScreen;
Jidong Chen's avatar
Jidong Chen committed
81 82 83 84 85
        [self _setup];
    }
    return self;
}

86 87 88 89 90 91 92
- (instancetype)initWithProject:(FlutterDartProject*)projectOrNil
                        nibName:(NSString*)nibNameOrNil
                         bundle:(NSBundle*)nibBundleOrNil {
    NSAssert(NO, @"unsupported init method!");
    return nil;
}

Jidong Chen's avatar
Jidong Chen committed
93 94 95 96 97 98 99 100
- (instancetype)initWithCoder:(NSCoder *)aDecoder{
    if (self = [super initWithCoder: aDecoder]) {
        NSAssert(NO, @"unsupported init method!");
        [self _setup];
    }
    return self;
}

Jidong Chen's avatar
init  
Jidong Chen committed
101 102 103 104 105
- (void)setName:(NSString *)name params:(NSDictionary *)params
{
    if(!_name && name){
        _name = name;
        _params = params;
Jidong Chen's avatar
Jidong Chen committed
106
        [BoostMessageChannel didInitPageContainer:^(NSNumber *r) {}
Jidong Chen's avatar
init  
Jidong Chen committed
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
                                               pageName:name
                                                 params:params
                                               uniqueId:[self uniqueIDString]];
    }
}


static NSUInteger kInstanceCounter = 0;

+ (NSUInteger)instanceCounter
{
    return kInstanceCounter;
}

+ (void)instanceCounterIncrease
{
    kInstanceCounter++;
    if(kInstanceCounter == 1){
Jidong Chen's avatar
Jidong Chen committed
125
        [FLUTTER_APP resume];
Jidong Chen's avatar
init  
Jidong Chen committed
126 127 128 129 130 131 132
    }
}

+ (void)instanceCounterDecrease
{
    kInstanceCounter--;
    if([self.class instanceCounter] == 0){
Jidong Chen's avatar
Jidong Chen committed
133
        [FLUTTER_APP pause];
Jidong Chen's avatar
init  
Jidong Chen committed
134 135 136 137 138 139 140 141
    }
}

- (NSString *)uniqueIDString
{
    return @(_identifier).stringValue;
}

142 143 144 145 146
- (void)_setup
{
    static long long sCounter = 0;
    _identifier = sCounter++;
    [self.class instanceCounterIncrease];
Jidong Chen's avatar
init  
Jidong Chen committed
147 148 149 150 151 152 153 154 155 156
}

- (void)dealloc
{
    [self notifyWillDealloc];
    [NSNotificationCenter.defaultCenter removeObserver:self];
}

- (void)notifyWillDealloc
{
Jidong Chen's avatar
Jidong Chen committed
157
    [BoostMessageChannel willDeallocPageContainer:^(NSNumber *r) {}
Jidong Chen's avatar
init  
Jidong Chen committed
158 159 160
                                               pageName:_name params:_params
                                               uniqueId:[self uniqueIDString]];

Jidong Chen's avatar
Jidong Chen committed
161
    [FLUTTER_APP removeViewController:self];
Jidong Chen's avatar
init  
Jidong Chen committed
162 163 164 165
    
    [self.class instanceCounterDecrease];
}

Jidong Chen's avatar
Jidong Chen committed
166 167 168 169
- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = UIColor.whiteColor;
}
Jidong Chen's avatar
init  
Jidong Chen committed
170 171 172 173 174 175 176

#pragma mark - ScreenShots
- (BOOL)isFlutterViewAttatched
{
    return FLUTTER_VIEW.superview == self.view;
}

Jidong Chen's avatar
Jidong Chen committed
177
- (void)attatchFlutterEngine
Jidong Chen's avatar
init  
Jidong Chen committed
178
{
Jidong Chen's avatar
Jidong Chen committed
179 180
    [FLUTTER_APP.flutterProvider prepareEngineIfNeeded];
    [FLUTTER_APP.flutterProvider atacheToViewController:self];
Jidong Chen's avatar
init  
Jidong Chen committed
181 182
}

Jidong Chen's avatar
Jidong Chen committed
183
- (void)detatchFlutterEngine
Jidong Chen's avatar
init  
Jidong Chen committed
184
{
Jidong Chen's avatar
Jidong Chen committed
185
    [FLUTTER_APP.flutterProvider detach];
Jidong Chen's avatar
init  
Jidong Chen committed
186 187 188 189 190 191 192
}

#pragma mark - Life circle methods

- (void)viewDidLayoutSubviews
{
    [super viewDidLayoutSubviews];
Jidong Chen's avatar
Jidong Chen committed
193
    [FLUTTER_APP resume];
Jidong Chen's avatar
init  
Jidong Chen committed
194 195 196 197 198 199
}

- (void)viewWillAppear:(BOOL)animated
{
    //For new page we should attach flutter view in view will appear
    //for better performance.
200 201 202

    [self attatchFlutterEngine];

Jidong Chen's avatar
Jidong Chen committed
203
    [BoostMessageChannel willShowPageContainer:^(NSNumber *result) {}
Jidong Chen's avatar
init  
Jidong Chen committed
204 205 206 207
                                            pageName:_name
                                              params:_params
                                            uniqueId:self.uniqueIDString];
    //Save some first time page info.
208 209 210 211
    if(![FlutterBoostPlugin2 sharedInstance].fPagename){
        [FlutterBoostPlugin2 sharedInstance].fPagename = _name;
        [FlutterBoostPlugin2 sharedInstance].fPageId = self.uniqueIDString;
        [FlutterBoostPlugin2 sharedInstance].fParams = _params;
Jidong Chen's avatar
init  
Jidong Chen committed
212 213
    }
    
214 215
    [super bridge_viewWillAppear:animated];
    [self.view setNeedsLayout];//TODO:通过param来设定
Jidong Chen's avatar
init  
Jidong Chen committed
216 217 218 219
}

- (void)viewDidAppear:(BOOL)animated
{
Jidong Chen's avatar
Jidong Chen committed
220
    [FLUTTER_APP addUniqueViewController:self];
Jidong Chen's avatar
init  
Jidong Chen committed
221
    
Jidong Chen's avatar
Jidong Chen committed
222 223
    //Ensure flutter view is attached.
    [self attatchFlutterEngine];
Jidong Chen's avatar
Jidong Chen committed
224
 
Jidong Chen's avatar
Jidong Chen committed
225
    [BoostMessageChannel didShowPageContainer:^(NSNumber *result) {}
Jidong Chen's avatar
init  
Jidong Chen committed
226 227 228
                                           pageName:_name
                                             params:_params
                                           uniqueId:self.uniqueIDString];
229
    //NOTES:务必在show之后再update,否则有闪烁; 或导致侧滑返回时上一个页面会和top页面内容一样
230
    [self surfaceUpdated:YES];
231

Jidong Chen's avatar
init  
Jidong Chen committed
232 233 234 235 236
    [super viewDidAppear:animated];
}

- (void)viewWillDisappear:(BOOL)animated
{
Jidong Chen's avatar
Jidong Chen committed
237
    [BoostMessageChannel willDisappearPageContainer:^(NSNumber *result) {}
Jidong Chen's avatar
init  
Jidong Chen committed
238 239 240
                                                 pageName:_name
                                                   params:_params
                                                 uniqueId:self.uniqueIDString];
241
    [[[UIApplication sharedApplication] keyWindow] endEditing:YES];
Jidong Chen's avatar
init  
Jidong Chen committed
242 243 244 245 246 247
    [super viewWillDisappear:animated];
}


- (void)viewDidDisappear:(BOOL)animated
{
Jidong Chen's avatar
Jidong Chen committed
248
    [BoostMessageChannel didDisappearPageContainer:^(NSNumber *result) {}
Jidong Chen's avatar
init  
Jidong Chen committed
249 250 251
                                                pageName:_name
                                                  params:_params
                                                uniqueId:self.uniqueIDString];
252 253 254 255 256
    //如果当前不可见vc和engine所持有的vc一致。在FlutterVC在混合栈中是最后一张页面,如tab中的页面
    if (self == FLUTTER_VC)
    {
        [self surfaceUpdated:NO];
    }
257
    [super bridge_viewDidDisappear:animated];
Jidong Chen's avatar
init  
Jidong Chen committed
258 259
}

Jidong Chen's avatar
Jidong Chen committed
260 261 262 263 264 265 266 267 268
- (void)installSplashScreenViewIfNecessary {
    //Do nothing.
}

- (BOOL)loadDefaultSplashScreenView
{
    return NO;
}

Jidong Chen's avatar
init  
Jidong Chen committed
269 270

@end