FlutterViewController.h 9.39 KB
Newer Older
jzhang's avatar
jzhang 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 25 26 27 28 29 30 31 32 33 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 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef FLUTTER_FLUTTERVIEWCONTROLLER_H_
#define FLUTTER_FLUTTERVIEWCONTROLLER_H_

#import <UIKit/UIKit.h>
#include <sys/cdefs.h>

#import "FlutterBinaryMessenger.h"
#import "FlutterDartProject.h"
#import "FlutterEngine.h"
#import "FlutterMacros.h"
#import "FlutterPlugin.h"
#import "FlutterTexture.h"

NS_ASSUME_NONNULL_BEGIN

@class FlutterEngine;

/**
 * The name used for semantic update notifications via `NSNotificationCenter`.
 *
 * The object passed as the sender is the `FlutterViewController` associated
 * with the update.
 */
FLUTTER_DARWIN_EXPORT
extern NSNotificationName const FlutterSemanticsUpdateNotification;

/**
 * A `UIViewController` implementation for Flutter views.
 *
 * Dart execution, channel communication, texture registration, and plugin registration are all
 * handled by `FlutterEngine`. Calls on this class to those members all proxy through to the
 * `FlutterEngine` attached FlutterViewController.
 *
 * A FlutterViewController can be initialized either with an already-running `FlutterEngine` via the
 * `initWithEngine:` initializer, or it can be initialized with a `FlutterDartProject` that will be
 * used to implicitly spin up a new `FlutterEngine`. Creating a `FlutterEngine` before showing a
 * FlutterViewController can be used to pre-initialize the Dart VM and to prepare the isolate in
 * order to reduce the latency to the first rendered frame. See
 * https://flutter.dev/docs/development/add-to-app/performance for more details on loading
 * latency.
 *
 * Holding a `FlutterEngine` independently of FlutterViewControllers can also be used to not to lose
 * Dart-related state and asynchronous tasks when navigating back and forth between a
 * FlutterViewController and other `UIViewController`s.
 */
FLUTTER_DARWIN_EXPORT
#ifdef __IPHONE_13_4
@interface FlutterViewController
    : UIViewController <FlutterTextureRegistry, FlutterPluginRegistry, UIGestureRecognizerDelegate>
#else
@interface FlutterViewController : UIViewController <FlutterTextureRegistry, FlutterPluginRegistry>
#endif

/**
 * Initializes this FlutterViewController with the specified `FlutterEngine`.
 *
 * The initialized viewcontroller will attach itself to the engine as part of this process.
 *
 * @param engine The `FlutterEngine` instance to attach to. Cannot be nil.
 * @param nibName The NIB name to initialize this UIViewController with.
 * @param nibBundle The NIB bundle.
 */
- (instancetype)initWithEngine:(FlutterEngine*)engine
                       nibName:(nullable NSString*)nibName
                        bundle:(nullable NSBundle*)nibBundle NS_DESIGNATED_INITIALIZER;

/**
 * Initializes a new FlutterViewController and `FlutterEngine` with the specified
 * `FlutterDartProject`.
 *
 * This will implicitly create a new `FlutterEngine` which is retrievable via the `engine` property
 * after initialization.
 *
 * @param project The `FlutterDartProject` to initialize the `FlutterEngine` with.
 * @param nibName The NIB name to initialize this UIViewController with.
 * @param nibBundle The NIB bundle.
 */
- (instancetype)initWithProject:(nullable FlutterDartProject*)project
                        nibName:(nullable NSString*)nibName
                         bundle:(nullable NSBundle*)nibBundle NS_DESIGNATED_INITIALIZER;

/**
 * Initializes a new FlutterViewController and `FlutterEngine` with the specified
 * `FlutterDartProject` and `initialRoute`.
 *
 * This will implicitly create a new `FlutterEngine` which is retrievable via the `engine` property
 * after initialization.
 *
 * @param project The `FlutterDartProject` to initialize the `FlutterEngine` with.
 * @param initialRoute The initial `Navigator` route to load.
 * @param nibName The NIB name to initialize this UIViewController with.
 * @param nibBundle The NIB bundle.
 */
- (instancetype)initWithProject:(nullable FlutterDartProject*)project
                   initialRoute:(nullable NSString*)initialRoute
                        nibName:(nullable NSString*)nibName
                         bundle:(nullable NSBundle*)nibBundle NS_DESIGNATED_INITIALIZER;

/**
 * Initializer that is called from loading a FlutterViewController from a XIB.
 *
 * See also:
 * https://developer.apple.com/documentation/foundation/nscoding/1416145-initwithcoder?language=objc
 */
- (instancetype)initWithCoder:(NSCoder*)aDecoder NS_DESIGNATED_INITIALIZER;

/**
 * Registers a callback that will be invoked when the Flutter view has been rendered.
 * The callback will be fired only once.
 *
 * Replaces an existing callback. Use a `nil` callback to unregister the existing one.
 */
- (void)setFlutterViewDidRenderCallback:(void (^)(void))callback;

/**
 * Returns the file name for the given asset.
 * The returned file name can be used to access the asset in the application's
 * main bundle.
 *
 * @param asset The name of the asset. The name can be hierarchical.
 * @return The file name to be used for lookup in the main bundle.
 */
- (NSString*)lookupKeyForAsset:(NSString*)asset;

/**
 * Returns the file name for the given asset which originates from the specified
 * package.
 * The returned file name can be used to access the asset in the application's
 * main bundle.
 *
 * @param asset The name of the asset. The name can be hierarchical.
 * @param package The name of the package from which the asset originates.
 * @return The file name to be used for lookup in the main bundle.
 */
- (NSString*)lookupKeyForAsset:(NSString*)asset fromPackage:(NSString*)package;

/**
 * Deprecated API to set initial route.
 *
 * Attempts to set the first route that the Flutter app shows if the Flutter
 * runtime hasn't yet started. The default is "/".
 *
 * This method must be called immediately after `initWithProject` and has no
 * effect when using `initWithEngine` if the `FlutterEngine` has already been
 * run.
 *
 * Setting this after the Flutter started running has no effect. See `pushRoute`
 * and `popRoute` to change the route after Flutter started running.
 *
 * This is deprecated because it needs to be called at the time of initialization
 * and thus should just be in the `initWithProject` initializer. If using
 * `initWithEngine`, the initial route should be set on the engine's
 * initializer.
 *
 * @param route The name of the first route to show.
 */
- (void)setInitialRoute:(NSString*)route
    FLUTTER_DEPRECATED("Use FlutterViewController initializer to specify initial route");

/**
 * Instructs the Flutter Navigator (if any) to go back.
 */
- (void)popRoute;

/**
 * Instructs the Flutter Navigator (if any) to push a route on to the navigation
 * stack.
 *
 * @param route The name of the route to push to the navigation stack.
 */
- (void)pushRoute:(NSString*)route;

/**
 * The `FlutterPluginRegistry` used by this FlutterViewController.
 */
- (id<FlutterPluginRegistry>)pluginRegistry;

/**
 * True if at least one frame has rendered and the ViewController has appeared.
 *
 * This property is reset to false when the ViewController disappears. It is
 * guaranteed to only alternate between true and false for observers.
 */
@property(nonatomic, readonly, getter=isDisplayingFlutterUI) BOOL displayingFlutterUI;

/**
 * Specifies the view to use as a splash screen. Flutter's rendering is asynchronous, so the first
 * frame rendered by the Flutter application might not immediately appear when theFlutter view is
 * initially placed in the view hierarchy. The splash screen view will be used as
 * a replacement until the first frame is rendered.
 *
 * The view used should be appropriate for multiple sizes; an autoresizing mask to
 * have a flexible width and height will be applied automatically.
 */
@property(strong, nonatomic) UIView* splashScreenView;

/**
 * Attempts to set the `splashScreenView` property from the `UILaunchStoryboardName` from the
 * main bundle's `Info.plist` file.  This method will not change the value of `splashScreenView`
 * if it cannot find a default one from a storyboard or nib.
 *
 * @return `YES` if successful, `NO` otherwise.
 */
- (BOOL)loadDefaultSplashScreenView;

/**
 * Controls whether the created view will be opaque or not.
 *
 * Default is `YES`.  Note that setting this to `NO` may negatively impact performance
 * when using hardware acceleration, and toggling this will trigger a re-layout of the
 * view.
 */
@property(nonatomic, getter=isViewOpaque) BOOL viewOpaque;

/**
 * The `FlutterEngine` instance for this view controller. This could be the engine this
 * `FlutterViewController` is initialized with or a new `FlutterEngine` implicitly created if
 * no engine was supplied during initialization.
 */
@property(weak, nonatomic, readonly) FlutterEngine* engine;

/**
 * The `FlutterBinaryMessenger` associated with this FlutterViewController (used for communicating
 * with channels).
 *
 * This is just a convenient way to get the |FlutterEngine|'s binary messenger.
 */
@property(nonatomic, readonly) NSObject<FlutterBinaryMessenger>* binaryMessenger;

/**
 * If the `FlutterViewController` creates a `FlutterEngine`, this property
 * determines if that `FlutterEngine` has `allowHeadlessExecution` set.
 *
 * The intention is that this is used with the XIB.  Otherwise, a
 * `FlutterEngine` can just be sent to the init methods.
 *
 * See also: `-[FlutterEngine initWithName:project:allowHeadlessExecution:]`
 */
@property(nonatomic, readonly) BOOL engineAllowHeadlessExecution;

@end

NS_ASSUME_NONNULL_END

#endif  // FLUTTER_FLUTTERVIEWCONTROLLER_H_