FLBFlutterViewContainer.m 7.68 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

余玠's avatar
余玠 committed
37
@interface FLBFlutterViewContainer  ()
Jidong Chen's avatar
init  
Jidong Chen committed
38 39
@property (nonatomic,strong,readwrite) NSDictionary *params;
@property (nonatomic,assign) long long identifier;
Leo's avatar
Leo committed
40 41
@property (nonatomic, copy) NSString *flbNibName;
@property (nonatomic, strong) NSBundle *flbNibBundle;
Jidong Chen's avatar
init  
Jidong Chen committed
42 43
@end

余玠's avatar
余玠 committed
44 45
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wincomplete-implementation"
46
@implementation FLBFlutterViewContainer
Jidong Chen's avatar
init  
Jidong Chen committed
47

Jidong Chen's avatar
Jidong Chen committed
48 49 50 51
- (instancetype)init
{
    [FLUTTER_APP.flutterProvider prepareEngineIfNeeded];
    if(self = [super initWithEngine:FLUTTER_APP.flutterProvider.engine
Leo's avatar
Leo committed
52 53
                            nibName:_flbNibName
                            bundle:_flbNibBundle]){
Jidong Chen's avatar
Jidong Chen committed
54 55 56 57 58
        [self _setup];
    }
    return self;
}

Leo's avatar
Leo committed
59 60
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wobjc-designated-initializers"
Jidong Chen's avatar
Jidong Chen committed
61 62 63 64 65 66 67
- (instancetype)initWithCoder:(NSCoder *)aDecoder{
    if (self = [super initWithCoder: aDecoder]) {
        NSAssert(NO, @"unsupported init method!");
        [self _setup];
    }
    return self;
}
Leo's avatar
Leo committed
68 69 70 71 72 73 74
#pragma pop

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

Jidong Chen's avatar
init  
Jidong Chen committed
76 77 78 79 80
- (void)setName:(NSString *)name params:(NSDictionary *)params
{
    if(!_name && name){
        _name = name;
        _params = params;
Jidong Chen's avatar
Jidong Chen committed
81
        [BoostMessageChannel didInitPageContainer:^(NSNumber *r) {}
Jidong Chen's avatar
init  
Jidong Chen committed
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
                                               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
99
        [FLUTTER_APP resume];
Jidong Chen's avatar
init  
Jidong Chen committed
100 101 102 103 104 105 106
    }
}

+ (void)instanceCounterDecrease
{
    kInstanceCounter--;
    if([self.class instanceCounter] == 0){
Jidong Chen's avatar
Jidong Chen committed
107
        [FLUTTER_APP pause];
Jidong Chen's avatar
init  
Jidong Chen committed
108 109 110 111 112 113 114 115
    }
}

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

116 117 118 119 120
- (void)_setup
{
    static long long sCounter = 0;
    _identifier = sCounter++;
    [self.class instanceCounterIncrease];
Jidong Chen's avatar
init  
Jidong Chen committed
121 122 123 124 125 126 127 128 129 130
}

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

- (void)notifyWillDealloc
{
Jidong Chen's avatar
Jidong Chen committed
131
    [BoostMessageChannel willDeallocPageContainer:^(NSNumber *r) {}
Jidong Chen's avatar
init  
Jidong Chen committed
132 133 134
                                               pageName:_name params:_params
                                               uniqueId:[self uniqueIDString]];

Jidong Chen's avatar
Jidong Chen committed
135
    [FLUTTER_APP removeViewController:self];
Jidong Chen's avatar
init  
Jidong Chen committed
136 137 138 139
    
    [self.class instanceCounterDecrease];
}

Jidong Chen's avatar
Jidong Chen committed
140 141 142 143
- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = UIColor.whiteColor;
}
Jidong Chen's avatar
init  
Jidong Chen committed
144 145 146 147 148 149 150

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

Jidong Chen's avatar
Jidong Chen committed
151
- (void)attatchFlutterEngine
Jidong Chen's avatar
init  
Jidong Chen committed
152
{
Jidong Chen's avatar
Jidong Chen committed
153
    [FLUTTER_APP.flutterProvider atacheToViewController:self];
Jidong Chen's avatar
init  
Jidong Chen committed
154 155
}

Jidong Chen's avatar
Jidong Chen committed
156
- (void)detatchFlutterEngine
Jidong Chen's avatar
init  
Jidong Chen committed
157
{
Jidong Chen's avatar
Jidong Chen committed
158
    [FLUTTER_APP.flutterProvider detach];
Jidong Chen's avatar
init  
Jidong Chen committed
159 160 161 162 163 164 165
}

#pragma mark - Life circle methods

- (void)viewDidLayoutSubviews
{
    [super viewDidLayoutSubviews];
Jidong Chen's avatar
Jidong Chen committed
166
    [FLUTTER_APP resume];
Jidong Chen's avatar
init  
Jidong Chen committed
167 168 169 170 171 172
}

- (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
173
 
Jidong Chen's avatar
Jidong Chen committed
174
    [BoostMessageChannel willShowPageContainer:^(NSNumber *result) {}
Jidong Chen's avatar
init  
Jidong Chen committed
175 176 177 178
                                            pageName:_name
                                              params:_params
                                            uniqueId:self.uniqueIDString];
    //Save some first time page info.
179 180 181 182
    if(![FlutterBoostPlugin sharedInstance].fPagename){
        [FlutterBoostPlugin sharedInstance].fPagename = _name;
        [FlutterBoostPlugin sharedInstance].fPageId = self.uniqueIDString;
        [FlutterBoostPlugin sharedInstance].fParams = _params;
Jidong Chen's avatar
init  
Jidong Chen committed
183
    }
184
 
185
    [super viewWillAppear:animated];
186
    [self.view setNeedsLayout];
187
    //instead of calling [super viewWillAppear:animated];, call super's super
188 189 190 191 192 193
//    struct objc_super target = {
//        .super_class = class_getSuperclass([FlutterViewController class]),
//        .receiver = self,
//    };
//    NSMethodSignature * (*callSuper)(struct objc_super *, SEL, BOOL animated) = (__typeof__(callSuper))objc_msgSendSuper;
//    callSuper(&target, @selector(viewWillAppear:), animated);
Jidong Chen's avatar
init  
Jidong Chen committed
194 195 196 197
}

- (void)viewDidAppear:(BOOL)animated
{
Jidong Chen's avatar
Jidong Chen committed
198
    [FLUTTER_APP addUniqueViewController:self];
Jidong Chen's avatar
init  
Jidong Chen committed
199
    
Jidong Chen's avatar
Jidong Chen committed
200 201
    //Ensure flutter view is attached.
    [self attatchFlutterEngine];
Jidong Chen's avatar
Jidong Chen committed
202
 
Jidong Chen's avatar
Jidong Chen committed
203
    [BoostMessageChannel didShowPageContainer:^(NSNumber *result) {}
Jidong Chen's avatar
init  
Jidong Chen committed
204 205 206 207
                                           pageName:_name
                                             params:_params
                                           uniqueId:self.uniqueIDString];
    
208 209 210
    //NOTES:务必在show之后再update,否则有闪烁
    [self surfaceUpdated:YES];
    
Jidong Chen's avatar
init  
Jidong Chen committed
211 212 213 214 215
    [super viewDidAppear:animated];
}

- (void)viewWillDisappear:(BOOL)animated
{
Jidong Chen's avatar
Jidong Chen committed
216
    [BoostMessageChannel willDisappearPageContainer:^(NSNumber *result) {}
Jidong Chen's avatar
init  
Jidong Chen committed
217 218 219
                                                 pageName:_name
                                                   params:_params
                                                 uniqueId:self.uniqueIDString];
220
    [[[UIApplication sharedApplication] keyWindow] endEditing:YES];
Jidong Chen's avatar
init  
Jidong Chen committed
221 222 223 224 225 226
    [super viewWillDisappear:animated];
}


- (void)viewDidDisappear:(BOOL)animated
{
Jidong Chen's avatar
Jidong Chen committed
227
    [BoostMessageChannel didDisappearPageContainer:^(NSNumber *result) {}
Jidong Chen's avatar
init  
Jidong Chen committed
228 229 230
                                                pageName:_name
                                                  params:_params
                                                uniqueId:self.uniqueIDString];
231
    [super viewDidDisappear:animated];
232
//  instead of calling [super viewDidDisappear:animated];, call super's super
233 234 235 236 237 238
//    struct objc_super target = {
//        .super_class = class_getSuperclass([FlutterViewController class]),
//        .receiver = self,
//    };
//    NSMethodSignature * (*callSuper)(struct objc_super *, SEL, BOOL animated) = (__typeof__(callSuper))objc_msgSendSuper;
//    callSuper(&target, @selector(viewDidDisappear:), animated);
Jidong Chen's avatar
init  
Jidong Chen committed
239 240
}

Jidong Chen's avatar
Jidong Chen committed
241 242 243 244 245 246 247 248 249
- (void)installSplashScreenViewIfNecessary {
    //Do nothing.
}

- (BOOL)loadDefaultSplashScreenView
{
    return NO;
}

Jidong Chen's avatar
init  
Jidong Chen committed
250 251

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