FLBFlutterViewContainer.m 8.45 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.
 */

25 26
#import "FLBFlutterViewContainer.h"
#import "FLBFlutterApplication.h"
Jidong Chen's avatar
Jidong Chen committed
27
#import "BoostMessageChannel.h"
28 29
#import "FLBFlutterContainerManager.h"
#import "FlutterBoostPlugin_private.h"
30 31
#import <objc/message.h>
#import <objc/runtime.h>
Jidong Chen's avatar
init  
Jidong Chen committed
32

33
#define FLUTTER_APP [FlutterBoostPlugin sharedInstance].application
Jidong Chen's avatar
Jidong Chen committed
34 35
#define FLUTTER_VIEW FLUTTER_APP.flutterViewController.view
#define FLUTTER_VC FLUTTER_APP.flutterViewController
Jidong Chen's avatar
init  
Jidong Chen committed
36

37 38
@interface FlutterViewController (bridgeToviewDidDisappear)
- (void)flushOngoingTouches;
39 40
- (void)bridge_viewDidDisappear:(BOOL)animated;
- (void)bridge_viewWillAppear:(BOOL)animated;
41 42 43 44 45 46 47 48 49 50 51
@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];
}
52 53 54 55 56 57 58 59 60 61 62 63
- (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];
}
64
@end
65
#pragma pop
66

余玠's avatar
余玠 committed
67
@interface FLBFlutterViewContainer  ()
Jidong Chen's avatar
init  
Jidong Chen committed
68 69
@property (nonatomic,strong,readwrite) NSDictionary *params;
@property (nonatomic,assign) long long identifier;
Leo's avatar
Leo committed
70 71
@property (nonatomic, copy) NSString *flbNibName;
@property (nonatomic, strong) NSBundle *flbNibBundle;
Jidong Chen's avatar
init  
Jidong Chen committed
72 73
@end

余玠's avatar
余玠 committed
74 75
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wincomplete-implementation"
76
@implementation FLBFlutterViewContainer
Jidong Chen's avatar
init  
Jidong Chen committed
77

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

Jidong Chen's avatar
Jidong Chen committed
87 88 89 90 91
        [self _setup];
    }
    return self;
}

92 93 94 95 96 97 98
- (instancetype)initWithProject:(FlutterDartProject*)projectOrNil
                        nibName:(NSString*)nibNameOrNil
                         bundle:(NSBundle*)nibBundleOrNil {
    NSAssert(NO, @"unsupported init method!");
    return nil;
}

Leo's avatar
Leo committed
99 100
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wobjc-designated-initializers"
Jidong Chen's avatar
Jidong Chen committed
101 102 103 104 105 106 107
- (instancetype)initWithCoder:(NSCoder *)aDecoder{
    if (self = [super initWithCoder: aDecoder]) {
        NSAssert(NO, @"unsupported init method!");
        [self _setup];
    }
    return self;
}
Leo's avatar
Leo committed
108 109 110 111 112 113 114
#pragma pop

- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    _flbNibName = nibNameOrNil;
    _flbNibBundle = nibBundleOrNil;
    return [self init];
}
Jidong Chen's avatar
Jidong Chen committed
115

Jidong Chen's avatar
init  
Jidong Chen committed
116 117 118 119 120
- (void)setName:(NSString *)name params:(NSDictionary *)params
{
    if(!_name && name){
        _name = name;
        _params = params;
Jidong Chen's avatar
Jidong Chen committed
121
        [BoostMessageChannel didInitPageContainer:^(NSNumber *r) {}
Jidong Chen's avatar
init  
Jidong Chen committed
122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
                                               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
139
        [FLUTTER_APP resume];
Jidong Chen's avatar
init  
Jidong Chen committed
140 141 142 143 144 145 146
    }
}

+ (void)instanceCounterDecrease
{
    kInstanceCounter--;
    if([self.class instanceCounter] == 0){
Jidong Chen's avatar
Jidong Chen committed
147
        [FLUTTER_APP pause];
Jidong Chen's avatar
init  
Jidong Chen committed
148 149 150 151 152 153 154 155
    }
}

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

156 157 158 159 160
- (void)_setup
{
    static long long sCounter = 0;
    _identifier = sCounter++;
    [self.class instanceCounterIncrease];
Jidong Chen's avatar
init  
Jidong Chen committed
161 162 163 164 165 166 167 168 169 170
}

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

- (void)notifyWillDealloc
{
Jidong Chen's avatar
Jidong Chen committed
171
    [BoostMessageChannel willDeallocPageContainer:^(NSNumber *r) {}
Jidong Chen's avatar
init  
Jidong Chen committed
172 173 174
                                               pageName:_name params:_params
                                               uniqueId:[self uniqueIDString]];

Jidong Chen's avatar
Jidong Chen committed
175
    [FLUTTER_APP removeViewController:self];
Jidong Chen's avatar
init  
Jidong Chen committed
176 177 178 179
    
    [self.class instanceCounterDecrease];
}

Jidong Chen's avatar
Jidong Chen committed
180 181 182 183
- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = UIColor.whiteColor;
}
Jidong Chen's avatar
init  
Jidong Chen committed
184 185 186 187 188 189 190

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

Jidong Chen's avatar
Jidong Chen committed
191
- (void)attatchFlutterEngine
Jidong Chen's avatar
init  
Jidong Chen committed
192
{
Jidong Chen's avatar
Jidong Chen committed
193
    [FLUTTER_APP.flutterProvider atacheToViewController:self];
Jidong Chen's avatar
init  
Jidong Chen committed
194 195
}

Jidong Chen's avatar
Jidong Chen committed
196
- (void)detatchFlutterEngine
Jidong Chen's avatar
init  
Jidong Chen committed
197
{
Jidong Chen's avatar
Jidong Chen committed
198
    [FLUTTER_APP.flutterProvider detach];
Jidong Chen's avatar
init  
Jidong Chen committed
199 200 201 202 203 204 205
}

#pragma mark - Life circle methods

- (void)viewDidLayoutSubviews
{
    [super viewDidLayoutSubviews];
Jidong Chen's avatar
Jidong Chen committed
206
    [FLUTTER_APP resume];
Jidong Chen's avatar
init  
Jidong Chen committed
207 208 209 210 211 212
}

- (void)viewWillAppear:(BOOL)animated
{
    //For new page we should attach flutter view in view will appear
    //for better performance.
Jidong Chen's avatar
Jidong Chen committed
213
 
214 215
    [self attatchFlutterEngine];
    
Jidong Chen's avatar
Jidong Chen committed
216
    [BoostMessageChannel willShowPageContainer:^(NSNumber *result) {}
Jidong Chen's avatar
init  
Jidong Chen committed
217 218 219 220
                                            pageName:_name
                                              params:_params
                                            uniqueId:self.uniqueIDString];
    //Save some first time page info.
zjq's avatar
zjq committed
221 222 223 224
    [FlutterBoostPlugin sharedInstance].fPagename = _name;
    [FlutterBoostPlugin sharedInstance].fPageId = self.uniqueIDString;
    [FlutterBoostPlugin sharedInstance].fParams = _params;
    
225
 
226 227
    
    [super bridge_viewWillAppear:animated];
228
    [self.view setNeedsLayout];//TODO:通过param来设定
Jidong Chen's avatar
init  
Jidong Chen committed
229 230 231 232
}

- (void)viewDidAppear:(BOOL)animated
{
Jidong Chen's avatar
Jidong Chen committed
233
    [FLUTTER_APP addUniqueViewController:self];
Jidong Chen's avatar
init  
Jidong Chen committed
234
    
Jidong Chen's avatar
Jidong Chen committed
235 236
    //Ensure flutter view is attached.
    [self attatchFlutterEngine];
Jidong Chen's avatar
Jidong Chen committed
237
 
Jidong Chen's avatar
Jidong Chen committed
238
    [BoostMessageChannel didShowPageContainer:^(NSNumber *result) {}
Jidong Chen's avatar
init  
Jidong Chen committed
239 240 241
                                           pageName:_name
                                             params:_params
                                           uniqueId:self.uniqueIDString];
242 243
    //NOTES:务必在show之后再update,否则有闪烁; 或导致侧滑返回时上一个页面会和top页面内容一样
    [self surfaceUpdated:YES];
Jidong Chen's avatar
init  
Jidong Chen committed
244 245 246 247 248 249
    
    [super viewDidAppear:animated];
}

- (void)viewWillDisappear:(BOOL)animated
{
Jidong Chen's avatar
Jidong Chen committed
250
    [BoostMessageChannel willDisappearPageContainer:^(NSNumber *result) {}
Jidong Chen's avatar
init  
Jidong Chen committed
251 252 253
                                                 pageName:_name
                                                   params:_params
                                                 uniqueId:self.uniqueIDString];
254
    [[[UIApplication sharedApplication] keyWindow] endEditing:YES];
Jidong Chen's avatar
init  
Jidong Chen committed
255 256 257 258 259 260
    [super viewWillDisappear:animated];
}


- (void)viewDidDisappear:(BOOL)animated
{
Jidong Chen's avatar
Jidong Chen committed
261
    [BoostMessageChannel didDisappearPageContainer:^(NSNumber *result) {}
Jidong Chen's avatar
init  
Jidong Chen committed
262 263 264
                                                pageName:_name
                                                  params:_params
                                                uniqueId:self.uniqueIDString];
265 266 267 268 269 270
    //如果当前不可见vc和engine所持有的vc一致。在FlutterVC在混合栈中是最后一张页面,如tab中的页面
    if (self == FLUTTER_VC)
    {
        [self surfaceUpdated:NO];
    }
    [super bridge_viewDidDisappear:animated];
Jidong Chen's avatar
init  
Jidong Chen committed
271 272
}

Jidong Chen's avatar
Jidong Chen committed
273 274 275 276 277 278 279 280 281
- (void)installSplashScreenViewIfNecessary {
    //Do nothing.
}

- (BOOL)loadDefaultSplashScreenView
{
    return NO;
}

Jidong Chen's avatar
init  
Jidong Chen committed
282 283

@end
余玠's avatar
余玠 committed
284
#pragma clang diagnostic pop