Flutter Engine
The Flutter Engine
Instance Methods | Properties | List of all members
FlutterViewController(Tests) Category Reference

Instance Methods

(void) - createTouchRateCorrectionVSyncClientIfNeeded
 
(void) - surfaceUpdated:
 
(void) - performOrientationUpdate:
 
(void) - handlePressEvent:nextAction:
 
(void) - discreteScrollEvent:
 
(void) - updateViewportMetricsIfNeeded
 
(void) - onUserSettingsChanged:
 
(void) - applicationWillTerminate:
 
(void) - goToApplicationLifecycle:
 
(void) - handleKeyboardNotification:
 
(CGFloat) - calculateKeyboardInset:keyboardMode:
 
(BOOL- shouldIgnoreKeyboardNotification:
 
(FlutterKeyboardMode) - calculateKeyboardAttachMode:
 
(CGFloat) - calculateMultitaskingAdjustment:keyboardFrame:
 
(void) - startKeyBoardAnimation:
 
(UIView *) - keyboardAnimationView
 
(SpringAnimation *) - keyboardSpringAnimation
 
(void) - setUpKeyboardSpringAnimationIfNeeded:
 
(void) - setUpKeyboardAnimationVsyncClient:
 
(void) - ensureViewportMetricsIsCorrect
 
(void) - invalidateKeyboardAnimationVSyncClient
 
(void) - addInternalPlugins
 
(flutter::PointerData- generatePointerDataForFake
 
(void) - sharedSetupWithProject:initialRoute:
 
(void) - applicationBecameActive:
 
(void) - applicationWillResignActive:
 
(void) - applicationWillTerminate:
 
(void) - applicationDidEnterBackground:
 
(void) - applicationWillEnterForeground:
 
(void) - sceneBecameActive:
 
(void) - sceneWillResignActive:
 
(void) - sceneWillDisconnect:
 
(void) - sceneDidEnterBackground:
 
(void) - sceneWillEnterForeground:
 
(void) - triggerTouchRateCorrectionIfNeeded:
 

Properties

double targetViewInsetBottom
 
BOOL isKeyboardInOrTransitioningFromBackground
 
BOOL keyboardAnimationIsShowing
 
VSyncClientkeyboardAnimationVSyncClient
 
VSyncClienttouchRateCorrectionVSyncClient
 

Detailed Description

Definition at line 122 of file FlutterViewControllerTest.mm.

Method Documentation

◆ addInternalPlugins

- (void) addInternalPlugins

Creates and registers plugins used by this view controller.

Extends class FlutterViewController.

Definition at line 527 of file FlutterViewController.mm.

814 {
815 self.keyboardManager = [[[FlutterKeyboardManager alloc] init] autorelease];
816 fml::WeakNSObject<FlutterViewController> weakSelf = [self getWeakNSObject];
817 FlutterSendKeyEvent sendEvent =
818 ^(const FlutterKeyEvent& event, FlutterKeyEventCallback callback, void* userData) {
819 if (weakSelf) {
820 [weakSelf.get()->_engine.get() sendKeyEvent:event callback:callback userData:userData];
821 }
822 };
823 [self.keyboardManager addPrimaryResponder:[[[FlutterEmbedderKeyResponder alloc]
824 initWithSendEvent:sendEvent] autorelease]];
826 initWithChannel:self.engine.keyEventChannel] autorelease];
827 [self.keyboardManager addPrimaryResponder:responder];
828 FlutterTextInputPlugin* textInputPlugin = self.engine.textInputPlugin;
829 if (textInputPlugin != nil) {
830 [self.keyboardManager addSecondaryResponder:textInputPlugin];
831 }
832 if ([_engine.get() viewController] == self) {
833 [textInputPlugin setUpIndirectScribbleInteraction:self];
834 }
835}
void(* FlutterKeyEventCallback)(bool, void *)
Definition: embedder.h:1155
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
FlKeyEvent * event
void setUpIndirectScribbleInteraction:(id< FlutterViewResponder > viewResponder)
void(^ FlutterSendKeyEvent)(const FlutterKeyEvent &, _Nullable FlutterKeyEventCallback, void *_Nullable)
FlutterViewController * viewController
FlutterTextInputPlugin * textInputPlugin
fml::scoped_nsobject< FlutterEngine > _engine

◆ applicationBecameActive:

- (void) applicationBecameActive: (NSNotification *)  notification

Extends class FlutterViewController.

Definition at line 527 of file FlutterViewController.mm.

995 :(NSNotification*)notification {
996 TRACE_EVENT0("flutter", "applicationBecameActive");
997 [self appOrSceneBecameActive];
998}
#define TRACE_EVENT0(category_group, name)
Definition: trace_event.h:131

◆ applicationDidEnterBackground:

- (void) applicationDidEnterBackground: (NSNotification *)  notification

Extends class FlutterViewController.

Definition at line 527 of file FlutterViewController.mm.

1009 :(NSNotification*)notification {
1010 TRACE_EVENT0("flutter", "applicationDidEnterBackground");
1011 [self appOrSceneDidEnterBackground];
1012}

◆ applicationWillEnterForeground:

- (void) applicationWillEnterForeground: (NSNotification *)  notification

Extends class FlutterViewController.

Definition at line 527 of file FlutterViewController.mm.

1014 :(NSNotification*)notification {
1015 TRACE_EVENT0("flutter", "applicationWillEnterForeground");
1016 [self appOrSceneWillEnterForeground];
1017}

◆ applicationWillResignActive:

- (void) applicationWillResignActive: (NSNotification *)  notification

Extends class FlutterViewController.

Definition at line 527 of file FlutterViewController.mm.

1000 :(NSNotification*)notification {
1001 TRACE_EVENT0("flutter", "applicationWillResignActive");
1002 [self appOrSceneWillResignActive];
1003}

◆ applicationWillTerminate: [1/2]

- (void) applicationWillTerminate: (NSNotification *)  notification

◆ applicationWillTerminate: [2/2]

- (void) applicationWillTerminate: (NSNotification *)  notification

Extends class FlutterViewController.

Definition at line 527 of file FlutterViewController.mm.

1005 :(NSNotification*)notification {
1006 [self appOrSceneWillTerminate];
1007}

◆ calculateKeyboardAttachMode:

- (FlutterKeyboardMode) calculateKeyboardAttachMode: (NSNotification *)  notification

Extends class FlutterViewController.

Definition at line 1112 of file FlutterViewController.mm.

1597 :(NSNotification*)notification {
1598 // There are multiple types of keyboard: docked, undocked, split, split docked,
1599 // floating, expanded shortcuts bar, minimized shortcuts bar. This function will categorize
1600 // the keyboard as one of the following modes: docked, floating, or hidden.
1601 // Docked mode includes docked, split docked, expanded shortcuts bar (when opening via click),
1602 // and minimized shortcuts bar (when opened via click).
1603 // Floating includes undocked, split, floating, expanded shortcuts bar (when dragged and dropped),
1604 // and minimized shortcuts bar (when dragged and dropped).
1605 NSDictionary* info = notification.userInfo;
1606 CGRect keyboardFrame = [info[UIKeyboardFrameEndUserInfoKey] CGRectValue];
1607
1608 if (notification.name == UIKeyboardWillHideNotification) {
1609 return FlutterKeyboardModeHidden;
1610 }
1611
1612 // If keyboard's dimensions and position are all zeroes, that means it's a Minimized/Expanded
1613 // Shortcuts Bar that has been dropped after dragging, which we categorize as floating.
1614 if (CGRectEqualToRect(keyboardFrame, CGRectZero)) {
1615 return FlutterKeyboardModeFloating;
1616 }
1617 // If keyboard's width or height are 0, it's hidden.
1618 if (CGRectIsEmpty(keyboardFrame)) {
1619 return FlutterKeyboardModeHidden;
1620 }
1621
1622 CGRect screenRect = [self flutterScreenIfViewLoaded].bounds;
1623 CGRect adjustedKeyboardFrame = keyboardFrame;
1624 adjustedKeyboardFrame.origin.y += [self calculateMultitaskingAdjustment:screenRect
1625 keyboardFrame:keyboardFrame];
1626
1627 // If the keyboard is partially or fully showing within the screen, it's either docked or
1628 // floating. Sometimes with custom keyboard extensions, the keyboard's position may be off by a
1629 // small decimal amount (which is why CGRectIntersectRect can't be used). Round to compare.
1630 CGRect intersection = CGRectIntersection(adjustedKeyboardFrame, screenRect);
1631 CGFloat intersectionHeight = CGRectGetHeight(intersection);
1632 CGFloat intersectionWidth = CGRectGetWidth(intersection);
1633 if (round(intersectionHeight) > 0 && intersectionWidth > 0) {
1634 // If the keyboard is above the bottom of the screen, it's floating.
1635 CGFloat screenHeight = CGRectGetHeight(screenRect);
1636 CGFloat adjustedKeyboardBottom = CGRectGetMaxY(adjustedKeyboardFrame);
1637 if (round(adjustedKeyboardBottom) < screenHeight) {
1638 return FlutterKeyboardModeFloating;
1639 }
1640 return FlutterKeyboardModeDocked;
1641 }
1642 return FlutterKeyboardModeHidden;
1643}
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition: DM.cpp:213
static void round(SkPoint *p)

◆ calculateKeyboardInset:keyboardMode:

- (CGFloat) calculateKeyboardInset: (CGRect)  keyboardFrame
keyboardMode: (int keyboardMode 

Extends class FlutterViewController.

◆ calculateMultitaskingAdjustment:keyboardFrame:

- (CGFloat) calculateMultitaskingAdjustment: (CGRect)  screenRect
keyboardFrame: (CGRect)  keyboardFrame 

Extends class FlutterViewController.

Definition at line 1112 of file FlutterViewController.mm.

1645 :(CGRect)screenRect keyboardFrame:(CGRect)keyboardFrame {
1646 // In Slide Over mode, the keyboard's frame does not include the space
1647 // below the app, even though the keyboard may be at the bottom of the screen.
1648 // To handle, shift the Y origin by the amount of space below the app.
1649 if (self.viewIfLoaded.traitCollection.userInterfaceIdiom == UIUserInterfaceIdiomPad &&
1650 self.viewIfLoaded.traitCollection.horizontalSizeClass == UIUserInterfaceSizeClassCompact &&
1651 self.viewIfLoaded.traitCollection.verticalSizeClass == UIUserInterfaceSizeClassRegular) {
1652 CGFloat screenHeight = CGRectGetHeight(screenRect);
1653 CGFloat keyboardBottom = CGRectGetMaxY(keyboardFrame);
1654
1655 // Stage Manager mode will also meet the above parameters, but it does not handle
1656 // the keyboard positioning the same way, so skip if keyboard is at bottom of page.
1657 if (screenHeight == keyboardBottom) {
1658 return 0;
1659 }
1660 CGRect viewRectRelativeToScreen =
1661 [self.viewIfLoaded convertRect:self.viewIfLoaded.frame
1662 toCoordinateSpace:[self flutterScreenIfViewLoaded].coordinateSpace];
1663 CGFloat viewBottom = CGRectGetMaxY(viewRectRelativeToScreen);
1664 CGFloat offset = screenHeight - viewBottom;
1665 if (offset > 0) {
1666 return offset;
1667 }
1668 }
1669 return 0;
1670}
SeparatedVector2 offset

◆ createTouchRateCorrectionVSyncClientIfNeeded

- (void) createTouchRateCorrectionVSyncClientIfNeeded

Extends class FlutterViewController.

Definition at line 1112 of file FlutterViewController.mm.

1319 {
1320 if (_touchRateCorrectionVSyncClient != nil) {
1321 return;
1322 }
1323
1324 double displayRefreshRate = DisplayLinkManager.displayRefreshRate;
1325 const double epsilon = 0.1;
1326 if (displayRefreshRate < 60.0 + epsilon) { // displayRefreshRate <= 60.0
1327
1328 // If current device's max frame rate is not larger than 60HZ, the delivery rate of touch events
1329 // is the same with render vsync rate. So it is unnecessary to create
1330 // _touchRateCorrectionVSyncClient to correct touch callback's rate.
1331 return;
1332 }
1333
1334 flutter::Shell& shell = [_engine.get() shell];
1335 auto callback = [](std::unique_ptr<flutter::FrameTimingsRecorder> recorder) {
1336 // Do nothing in this block. Just trigger system to callback touch events with correct rate.
1337 };
1338 _touchRateCorrectionVSyncClient =
1339 [[VSyncClient alloc] initWithTaskRunner:shell.GetTaskRunners().GetPlatformTaskRunner()
1340 callback:callback];
1341 _touchRateCorrectionVSyncClient.allowPauseAfterVsync = NO;
1342}
double displayRefreshRate
The display refresh rate used for reporting purposes. The engine does not care about this for frame s...

◆ discreteScrollEvent:

- (void) discreteScrollEvent: (UIPanGestureRecognizer *)  recognizer

Extends class FlutterViewController.

◆ ensureViewportMetricsIsCorrect

- (void) ensureViewportMetricsIsCorrect

Extends class FlutterViewController.

Definition at line 1112 of file FlutterViewController.mm.

1848 {
1849 if (_viewportMetrics.physical_view_inset_bottom != self.targetViewInsetBottom) {
1850 // Make sure the `physical_view_inset_bottom` is the target value.
1851 _viewportMetrics.physical_view_inset_bottom = self.targetViewInsetBottom;
1852 [self updateViewportMetricsIfNeeded];
1853 }
1854}
flutter::ViewportMetrics _viewportMetrics

◆ generatePointerDataForFake

- (PointerData FlutterViewController(Tests)):

Extends class FlutterViewController.

Definition at line 463 of file FlutterViewController.mm.

516 {
517 flutter::PointerData pointer_data;
518 pointer_data.Clear();
520 // `UITouch.timestamp` is defined as seconds since system startup. Synthesized events can get this
521 // time with `NSProcessInfo.systemUptime`. See
522 // https://developer.apple.com/documentation/uikit/uitouch/1618144-timestamp?language=objc
523 pointer_data.time_stamp = [[NSProcessInfo processInfo] systemUptime] * kMicrosecondsPerSecond;
524 return pointer_data;
525}
static constexpr int kMicrosecondsPerSecond

◆ goToApplicationLifecycle:

- (void) goToApplicationLifecycle: (nonnull NSString *)  state

Extends class FlutterViewController.

Definition at line 527 of file FlutterViewController.mm.

1080 :(nonnull NSString*)state {
1081 // Accessing self.view will create the view. Instead use viewIfLoaded
1082 // to check whether the view is attached to window.
1083 if (self.viewIfLoaded.window) {
1084 [[_engine.get() lifecycleChannel] sendMessage:state];
1085 }
1086}
AtkStateType state

◆ handleKeyboardNotification:

- (void) handleKeyboardNotification: (NSNotification *)  notification

Extends class FlutterViewController.

Definition at line 1112 of file FlutterViewController.mm.

1493 :(NSNotification*)notification {
1494 // See https://flutter.dev/go/ios-keyboard-calculating-inset for more details
1495 // on why notifications are used and how things are calculated.
1496 if ([self shouldIgnoreKeyboardNotification:notification]) {
1497 return;
1498 }
1499
1500 NSDictionary* info = notification.userInfo;
1501 CGRect beginKeyboardFrame = [info[UIKeyboardFrameBeginUserInfoKey] CGRectValue];
1502 CGRect keyboardFrame = [info[UIKeyboardFrameEndUserInfoKey] CGRectValue];
1503 FlutterKeyboardMode keyboardMode = [self calculateKeyboardAttachMode:notification];
1504 CGFloat calculatedInset = [self calculateKeyboardInset:keyboardFrame keyboardMode:keyboardMode];
1505
1506 // Avoid double triggering startKeyBoardAnimation.
1507 if (self.targetViewInsetBottom == calculatedInset) {
1508 return;
1509 }
1510
1511 self.targetViewInsetBottom = calculatedInset;
1512 NSTimeInterval duration = [info[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
1513
1514 // Flag for simultaneous compounding animation calls.
1515 // This captures animation calls made while the keyboard animation is currently animating. If the
1516 // new animation is in the same direction as the current animation, this flag lets the current
1517 // animation continue with an updated targetViewInsetBottom instead of starting a new keyboard
1518 // animation. This allows for smoother keyboard animation interpolation.
1519 BOOL keyboardWillShow = beginKeyboardFrame.origin.y > keyboardFrame.origin.y;
1520 BOOL keyboardAnimationIsCompounding =
1521 self.keyboardAnimationIsShowing == keyboardWillShow && _keyboardAnimationVSyncClient != nil;
1522
1523 // Mark keyboard as showing or hiding.
1524 self.keyboardAnimationIsShowing = keyboardWillShow;
1525
1526 if (!keyboardAnimationIsCompounding) {
1527 [self startKeyBoardAnimation:duration];
1528 } else if ([self keyboardSpringAnimation]) {
1529 [self keyboardSpringAnimation].toValue = self.targetViewInsetBottom;
1530 }
1531}
double duration
Definition: examples.cpp:30
int BOOL
Definition: windows_types.h:37

◆ handlePressEvent:nextAction:

- (void) handlePressEvent: (FlutterUIPressProxy *)  press
nextAction: (ios(13.4))  API_AVAILABLE 

Extends class FlutterViewController.

Definition at line 1112 of file FlutterViewController.mm.

1856 :(FlutterUIPressProxy*)press
1857 nextAction:(void (^)())next API_AVAILABLE(ios(13.4)) {
1858 if (@available(iOS 13.4, *)) {
1859 } else {
1860 next();
1861 return;
1862 }
1863 [self.keyboardManager handlePress:press nextAction:next];
1864}
static float next(float f)
SK_API sk_sp< SkSurface > ios(9.0)
API_AVAILABLE(ios(14.0), macos(11.0)) static NSString *MTLCommandEncoderErrorStateToString(MTLCommandEncoderErrorState state)

◆ invalidateKeyboardAnimationVSyncClient

- (void) invalidateKeyboardAnimationVSyncClient

Extends class FlutterViewController.

Definition at line 1112 of file FlutterViewController.mm.

1836 {
1837 [_keyboardAnimationVSyncClient invalidate];
1838 [_keyboardAnimationVSyncClient release];
1839 _keyboardAnimationVSyncClient = nil;
1840}

◆ keyboardAnimationView

- (UIView *) keyboardAnimationView

Extends class FlutterViewController.

Definition at line 527 of file FlutterViewController.mm.

665 {
667}
T get() const __attribute((ns_returns_not_retained))
fml::scoped_nsobject< UIView > _keyboardAnimationView

◆ keyboardSpringAnimation

- (SpringAnimation *) keyboardSpringAnimation

Extends class FlutterViewController.

Definition at line 527 of file FlutterViewController.mm.

669 {
670 return _keyboardSpringAnimation.get();
671}
fml::scoped_nsobject< SpringAnimation > _keyboardSpringAnimation

◆ onUserSettingsChanged:

- (void) onUserSettingsChanged: (NSNotification *)  notification

Extends class FlutterViewController.

Definition at line 1112 of file FlutterViewController.mm.

2131 :(NSNotification*)notification {
2132 [[_engine.get() settingsChannel] sendMessage:@{
2133 @"textScaleFactor" : @([self textScaleFactor]),
2134 @"alwaysUse24HourFormat" : @([self isAlwaysUse24HourFormat]),
2135 @"platformBrightness" : [self brightnessMode],
2136 @"platformContrast" : [self contrastMode],
2137 @"nativeSpellCheckServiceDefined" : @true,
2138 @"supportsShowingSystemContextMenu" : @([self supportsShowingSystemContextMenu])
2139 }];
2140}

◆ performOrientationUpdate:

- (void) performOrientationUpdate: (UIInterfaceOrientationMask)  new_preferences

Extends class FlutterViewController.

Definition at line 1112 of file FlutterViewController.mm.

1973 :(UIInterfaceOrientationMask)new_preferences {
1974 if (new_preferences != _orientationPreferences) {
1975 _orientationPreferences = new_preferences;
1976
1977 if (@available(iOS 16.0, *)) {
1978 NSSet<UIScene*>* scenes =
1979#if APPLICATION_EXTENSION_API_ONLY
1980 self.flutterWindowSceneIfViewLoaded
1981 ? [NSSet setWithObject:self.flutterWindowSceneIfViewLoaded]
1982 : [NSSet set];
1983#else
1984 [UIApplication.sharedApplication.connectedScenes
1985 filteredSetUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(
1986 id scene, NSDictionary* bindings) {
1987 return [scene isKindOfClass:[UIWindowScene class]];
1988 }]];
1989#endif
1990 [self requestGeometryUpdateForWindowScenes:scenes];
1991 } else {
1992 UIInterfaceOrientationMask currentInterfaceOrientation = 0;
1993 if (@available(iOS 13.0, *)) {
1994 UIWindowScene* windowScene = [self flutterWindowSceneIfViewLoaded];
1995 if (!windowScene) {
1996 FML_LOG(WARNING)
1997 << "Accessing the interface orientation when the window scene is unavailable.";
1998 return;
1999 }
2000 currentInterfaceOrientation = 1 << windowScene.interfaceOrientation;
2001 } else {
2002#if APPLICATION_EXTENSION_API_ONLY
2003 FML_LOG(ERROR) << "Application based status bar orentiation update is not supported in "
2004 "app extension. Orientation: "
2005 << currentInterfaceOrientation;
2006#else
2007 currentInterfaceOrientation = 1 << [[UIApplication sharedApplication] statusBarOrientation];
2008#endif
2009 }
2010 if (!(_orientationPreferences & currentInterfaceOrientation)) {
2011 [UIViewController attemptRotationToDeviceOrientation];
2012 // Force orientation switch if the current orientation is not allowed
2013 if (_orientationPreferences & UIInterfaceOrientationMaskPortrait) {
2014 // This is no official API but more like a workaround / hack (using
2015 // key-value coding on a read-only property). This might break in
2016 // the future, but currently it´s the only way to force an orientation change
2017 [[UIDevice currentDevice] setValue:@(UIInterfaceOrientationPortrait)
2018 forKey:@"orientation"];
2019 } else if (_orientationPreferences & UIInterfaceOrientationMaskPortraitUpsideDown) {
2020 [[UIDevice currentDevice] setValue:@(UIInterfaceOrientationPortraitUpsideDown)
2021 forKey:@"orientation"];
2022 } else if (_orientationPreferences & UIInterfaceOrientationMaskLandscapeLeft) {
2023 [[UIDevice currentDevice] setValue:@(UIInterfaceOrientationLandscapeLeft)
2024 forKey:@"orientation"];
2025 } else if (_orientationPreferences & UIInterfaceOrientationMaskLandscapeRight) {
2026 [[UIDevice currentDevice] setValue:@(UIInterfaceOrientationLandscapeRight)
2027 forKey:@"orientation"];
2028 }
2029 }
2030 }
2031 }
2032}
#define FML_LOG(severity)
Definition: logging.h:82
UIInterfaceOrientationMask _orientationPreferences
#define ERROR(message)
Definition: elf_loader.cc:260

◆ sceneBecameActive:

- (void) sceneBecameActive: (ios(13.0))  API_AVAILABLE

Extends class FlutterViewController.

Definition at line 527 of file FlutterViewController.mm.

1021 :(NSNotification*)notification API_AVAILABLE(ios(13.0)) {
1022 TRACE_EVENT0("flutter", "sceneBecameActive");
1023 [self appOrSceneBecameActive];
1024}

◆ sceneDidEnterBackground:

- (void) sceneDidEnterBackground: (ios(13.0))  API_AVAILABLE

Extends class FlutterViewController.

Definition at line 527 of file FlutterViewController.mm.

1035 :(NSNotification*)notification API_AVAILABLE(ios(13.0)) {
1036 TRACE_EVENT0("flutter", "sceneDidEnterBackground");
1037 [self appOrSceneDidEnterBackground];
1038}

◆ sceneWillDisconnect:

- (void) sceneWillDisconnect: (ios(13.0))  API_AVAILABLE

Extends class FlutterViewController.

Definition at line 527 of file FlutterViewController.mm.

1031 :(NSNotification*)notification API_AVAILABLE(ios(13.0)) {
1032 [self appOrSceneWillTerminate];
1033}

◆ sceneWillEnterForeground:

- (void) sceneWillEnterForeground: (ios(13.0))  API_AVAILABLE

Extends class FlutterViewController.

Definition at line 527 of file FlutterViewController.mm.

1040 :(NSNotification*)notification API_AVAILABLE(ios(13.0)) {
1041 TRACE_EVENT0("flutter", "sceneWillEnterForeground");
1042 [self appOrSceneWillEnterForeground];
1043}

◆ sceneWillResignActive:

- (void) sceneWillResignActive: (ios(13.0))  API_AVAILABLE

Extends class FlutterViewController.

Definition at line 527 of file FlutterViewController.mm.

1026 :(NSNotification*)notification API_AVAILABLE(ios(13.0)) {
1027 TRACE_EVENT0("flutter", "sceneWillResignActive");
1028 [self appOrSceneWillResignActive];
1029}

◆ setUpKeyboardAnimationVsyncClient:

- (void) setUpKeyboardAnimationVsyncClient: (FlutterKeyboardAnimationCallback keyboardAnimationCallback

Extends class FlutterViewController.

Definition at line 1112 of file FlutterViewController.mm.

1811 :
1812 (FlutterKeyboardAnimationCallback)keyboardAnimationCallback {
1813 if (!keyboardAnimationCallback) {
1814 return;
1815 }
1816 NSAssert(_keyboardAnimationVSyncClient == nil,
1817 @"_keyboardAnimationVSyncClient must be nil when setting up.");
1818
1819 // Make sure the new viewport metrics get sent after the begin frame event has processed.
1821 [keyboardAnimationCallback copy]);
1822 auto uiCallback = [animationCallback](std::unique_ptr<flutter::FrameTimingsRecorder> recorder) {
1823 fml::TimeDelta frameInterval = recorder->GetVsyncTargetTime() - recorder->GetVsyncStartTime();
1824 fml::TimePoint keyboardAnimationTargetTime = recorder->GetVsyncTargetTime() + frameInterval;
1825 dispatch_async(dispatch_get_main_queue(), ^(void) {
1826 animationCallback.get()(keyboardAnimationTargetTime);
1827 });
1828 };
1829
1830 _keyboardAnimationVSyncClient = [[VSyncClient alloc] initWithTaskRunner:[_engine uiTaskRunner]
1831 callback:uiCallback];
1832 _keyboardAnimationVSyncClient.allowPauseAfterVsync = NO;
1833 [_keyboardAnimationVSyncClient await];
1834}
void(^ FlutterKeyboardAnimationCallback)(fml::TimePoint)
Definition: copy.py:1

◆ setUpKeyboardSpringAnimationIfNeeded:

- (void) setUpKeyboardSpringAnimationIfNeeded: (CAAnimation *)  keyboardAnimation

Extends class FlutterViewController.

Definition at line 1112 of file FlutterViewController.mm.

1793 :(CAAnimation*)keyboardAnimation {
1794 // If keyboard animation is null or not a spring animation, fallback to DisplayLink tracking.
1795 if (keyboardAnimation == nil || ![keyboardAnimation isKindOfClass:[CASpringAnimation class]]) {
1797 return;
1798 }
1799
1800 // Setup keyboard spring animation details for spring curve animation calculation.
1801 CASpringAnimation* keyboardCASpringAnimation = (CASpringAnimation*)keyboardAnimation;
1803 initWithStiffness:keyboardCASpringAnimation.stiffness
1804 damping:keyboardCASpringAnimation.damping
1805 mass:keyboardCASpringAnimation.mass
1806 initialVelocity:keyboardCASpringAnimation.initialVelocity
1807 fromValue:self.originalViewInsetBottom
1808 toValue:self.targetViewInsetBottom]);
1809}

◆ sharedSetupWithProject:initialRoute:

- (void) sharedSetupWithProject: (nullable FlutterDartProject *)  project
initialRoute: (nullable NSString *)  initialRoute 

Extends class FlutterViewController.

Definition at line 152 of file FlutterViewController.mm.

234 :(nullable FlutterDartProject*)project
235 initialRoute:(nullable NSString*)initialRoute {
236 // Need the project to get settings for the view. Initializing it here means
237 // the Engine class won't initialize it later.
238 if (!project) {
239 project = [[[FlutterDartProject alloc] init] autorelease];
240 }
241 FlutterView.forceSoftwareRendering = project.settings.enable_software_rendering;
242 _weakFactory = std::make_unique<fml::WeakNSObjectFactory<FlutterViewController>>(self);
244 initWithName:@"io.flutter"
245 project:project
246 allowHeadlessExecution:self.engineAllowHeadlessExecution
247 restorationEnabled:[self restorationIdentifier] != nil]};
248
249 if (!engine) {
250 return;
251 }
252
253 _viewOpaque = YES;
254 _engine = engine;
255 _flutterView.reset([[FlutterView alloc] initWithDelegate:_engine
256 opaque:self.isViewOpaque
257 enableWideGamut:project.isWideGamutEnabled]);
258 [_engine.get() createShell:nil libraryURI:nil initialRoute:initialRoute];
259 _engineNeedsLaunch = YES;
260 _ongoingTouches.reset([[NSMutableSet alloc] init]);
261 [self loadDefaultSplashScreenView];
262 [self performCommonViewControllerInitialization];
263}
FlutterEngine engine
Definition: main.cc:68
BOOL forceSoftwareRendering
Definition: FlutterView.h:49
std::unique_ptr< fml::WeakNSObjectFactory< FlutterEngine > > _weakFactory
fml::scoped_nsobject< FlutterView > _flutterView
fml::scoped_nsobject< NSMutableSet< NSNumber * > > _ongoingTouches
BOOL _viewOpaque
BOOL _engineNeedsLaunch
static bool init()

◆ shouldIgnoreKeyboardNotification:

- (BOOL) shouldIgnoreKeyboardNotification: (NSNotification *)  notification

Extends class FlutterViewController.

Definition at line 1112 of file FlutterViewController.mm.

1533 :(NSNotification*)notification {
1534 // Don't ignore UIKeyboardWillHideNotification notifications.
1535 // Even if the notification is triggered in the background or by a different app/view controller,
1536 // we want to always handle this notification to avoid inaccurate inset when in a mulitasking mode
1537 // or when switching between apps.
1538 if (notification.name == UIKeyboardWillHideNotification) {
1539 return NO;
1540 }
1541
1542 // Ignore notification when keyboard's dimensions and position are all zeroes for
1543 // UIKeyboardWillChangeFrameNotification. This happens when keyboard is dragged. Do not ignore if
1544 // the notification is UIKeyboardWillShowNotification, as CGRectZero for that notfication only
1545 // occurs when Minimized/Expanded Shortcuts Bar is dropped after dragging, which we later use to
1546 // categorize it as floating.
1547 NSDictionary* info = notification.userInfo;
1548 CGRect keyboardFrame = [info[UIKeyboardFrameEndUserInfoKey] CGRectValue];
1549 if (notification.name == UIKeyboardWillChangeFrameNotification &&
1550 CGRectEqualToRect(keyboardFrame, CGRectZero)) {
1551 return YES;
1552 }
1553
1554 // When keyboard's height or width is set to 0, don't ignore. This does not happen
1555 // often but can happen sometimes when switching between multitasking modes.
1556 if (CGRectIsEmpty(keyboardFrame)) {
1557 return NO;
1558 }
1559
1560 // Ignore keyboard notifications related to other apps or view controllers.
1561 if ([self isKeyboardNotificationForDifferentView:notification]) {
1562 return YES;
1563 }
1564
1565 if (@available(iOS 13.0, *)) {
1566 // noop
1567 } else {
1568 // If OS version is less than 13, ignore notification if the app is in the background
1569 // or is transitioning from the background. In older versions, when switching between
1570 // apps with the keyboard open in the secondary app, notifications are sent when
1571 // the app is in the background/transitioning from background as if they belong
1572 // to the app and as if the keyboard is showing even though it is not.
1573 if (self.isKeyboardInOrTransitioningFromBackground) {
1574 return YES;
1575 }
1576 }
1577
1578 return NO;
1579}

◆ startKeyBoardAnimation:

- (void) startKeyBoardAnimation: (NSTimeInterval)  duration

Extends class FlutterViewController.

Definition at line 1112 of file FlutterViewController.mm.

1691 :(NSTimeInterval)duration {
1692 // If current physical_view_inset_bottom == targetViewInsetBottom, do nothing.
1693 if (_viewportMetrics.physical_view_inset_bottom == self.targetViewInsetBottom) {
1694 return;
1695 }
1696
1697 // When this method is called for the first time,
1698 // initialize the keyboardAnimationView to get animation interpolation during animation.
1699 if ([self keyboardAnimationView] == nil) {
1700 UIView* keyboardAnimationView = [[UIView alloc] init];
1701 [keyboardAnimationView setHidden:YES];
1702 _keyboardAnimationView.reset(keyboardAnimationView);
1703 }
1704
1705 if ([self keyboardAnimationView].superview == nil) {
1706 [self.view addSubview:[self keyboardAnimationView]];
1707 }
1708
1709 // Remove running animation when start another animation.
1710 [[self keyboardAnimationView].layer removeAllAnimations];
1711
1712 // Set animation begin value and DisplayLink tracking values.
1713 [self keyboardAnimationView].frame =
1714 CGRectMake(0, _viewportMetrics.physical_view_inset_bottom, 0, 0);
1715 self.keyboardAnimationStartTime = fml::TimePoint().Now();
1716 self.originalViewInsetBottom = _viewportMetrics.physical_view_inset_bottom;
1717
1718 // Invalidate old vsync client if old animation is not completed.
1719 [self invalidateKeyboardAnimationVSyncClient];
1720
1721 fml::WeakNSObject<FlutterViewController> weakSelf = [self getWeakNSObject];
1722 FlutterKeyboardAnimationCallback keyboardAnimationCallback = ^(
1723 fml::TimePoint keyboardAnimationTargetTime) {
1724 if (!weakSelf) {
1725 return;
1726 }
1727 fml::scoped_nsobject<FlutterViewController> flutterViewController(
1728 [(FlutterViewController*)weakSelf.get() retain]);
1729 if (!flutterViewController) {
1730 return;
1731 }
1732
1733 // If the view controller's view is not loaded, bail out.
1734 if (!flutterViewController.get().isViewLoaded) {
1735 return;
1736 }
1737 // If the view for tracking keyboard animation is nil, means it is not
1738 // created, bail out.
1739 if ([flutterViewController keyboardAnimationView] == nil) {
1740 return;
1741 }
1742 // If keyboardAnimationVSyncClient is nil, means the animation ends.
1743 // And should bail out.
1744 if (flutterViewController.get().keyboardAnimationVSyncClient == nil) {
1745 return;
1746 }
1747
1748 if ([flutterViewController keyboardAnimationView].superview == nil) {
1749 // Ensure the keyboardAnimationView is in view hierarchy when animation running.
1750 [flutterViewController.get().view addSubview:[flutterViewController keyboardAnimationView]];
1751 }
1752
1753 if ([flutterViewController keyboardSpringAnimation] == nil) {
1754 if (flutterViewController.get().keyboardAnimationView.layer.presentationLayer) {
1755 flutterViewController.get()->_viewportMetrics.physical_view_inset_bottom =
1756 flutterViewController.get()
1757 .keyboardAnimationView.layer.presentationLayer.frame.origin.y;
1758 [flutterViewController updateViewportMetricsIfNeeded];
1759 }
1760 } else {
1761 fml::TimeDelta timeElapsed =
1762 keyboardAnimationTargetTime - flutterViewController.get().keyboardAnimationStartTime;
1763 flutterViewController.get()->_viewportMetrics.physical_view_inset_bottom =
1764 [[flutterViewController keyboardSpringAnimation] curveFunction:timeElapsed.ToSecondsF()];
1765 [flutterViewController updateViewportMetricsIfNeeded];
1766 }
1767 };
1768 [self setUpKeyboardAnimationVsyncClient:keyboardAnimationCallback];
1769 VSyncClient* currentVsyncClient = _keyboardAnimationVSyncClient;
1770
1771 [UIView animateWithDuration:duration
1772 animations:^{
1773 // Set end value.
1774 [self keyboardAnimationView].frame = CGRectMake(0, self.targetViewInsetBottom, 0, 0);
1775
1776 // Setup keyboard animation interpolation.
1777 CAAnimation* keyboardAnimation =
1778 [[self keyboardAnimationView].layer animationForKey:@"position"];
1779 [self setUpKeyboardSpringAnimationIfNeeded:keyboardAnimation];
1780 }
1781 completion:^(BOOL finished) {
1782 if (_keyboardAnimationVSyncClient == currentVsyncClient) {
1783 // Indicates the vsync client captured by this block is the original one, which also
1784 // indicates the animation has not been interrupted from its beginning. Moreover,
1785 // indicates the animation is over and there is no more to execute.
1786 [self invalidateKeyboardAnimationVSyncClient];
1787 [self removeKeyboardAnimationView];
1788 [self ensureViewportMetricsIsCorrect];
1789 }
1790 }];
1791}
void reset(NST *object=Traits::InvalidValue(), scoped_policy::OwnershipPolicy policy=scoped_policy::OwnershipPolicy::kAssume)
std::chrono::time_point< std::chrono::high_resolution_clock > TimePoint
Definition: timing.h:15
const myers::Point & get(const myers::Segment &)

◆ surfaceUpdated:

- (void) surfaceUpdated: (BOOL appeared

Extends class FlutterViewController.

Definition at line 527 of file FlutterViewController.mm.

738 :(BOOL)appeared {
739 if (!_engine) {
740 return;
741 }
742
743 // NotifyCreated/NotifyDestroyed are synchronous and require hops between the UI and raster
744 // thread.
745 if (appeared) {
746 [self installFirstFrameCallback];
747 [_engine.get() platformViewsController]->SetFlutterView(_flutterView.get());
748 [_engine.get() platformViewsController]->SetFlutterViewController(self);
749 [_engine.get() iosPlatformView]->NotifyCreated();
750 } else {
751 self.displayingFlutterUI = NO;
752 [_engine.get() iosPlatformView]->NotifyDestroyed();
753 [_engine.get() platformViewsController]->SetFlutterView(nullptr);
754 [_engine.get() platformViewsController]->SetFlutterViewController(nullptr);
755 }
756}

◆ triggerTouchRateCorrectionIfNeeded:

- (void) triggerTouchRateCorrectionIfNeeded: (NSSet *)  touches

Extends class FlutterViewController.

Definition at line 1112 of file FlutterViewController.mm.

1344 :(NSSet*)touches {
1345 if (_touchRateCorrectionVSyncClient == nil) {
1346 // If the _touchRateCorrectionVSyncClient is not created, means current devices doesn't
1347 // need to correct the touch rate. So just return.
1348 return;
1349 }
1350
1351 // As long as there is a touch's phase is UITouchPhaseBegan or UITouchPhaseMoved,
1352 // activate the correction. Otherwise pause the correction.
1353 BOOL isUserInteracting = NO;
1354 for (UITouch* touch in touches) {
1355 if (touch.phase == UITouchPhaseBegan || touch.phase == UITouchPhaseMoved) {
1356 isUserInteracting = YES;
1357 break;
1358 }
1359 }
1360
1361 if (isUserInteracting && [_engine.get() viewController] == self) {
1362 [_touchRateCorrectionVSyncClient await];
1363 } else {
1364 [_touchRateCorrectionVSyncClient pause];
1365 }
1366}

◆ updateViewportMetricsIfNeeded

- (void) updateViewportMetricsIfNeeded

Extends class FlutterViewController.

Definition at line 1112 of file FlutterViewController.mm.

1376 {
1377 if (_shouldIgnoreViewportMetricsUpdatesDuringRotation) {
1378 return;
1379 }
1380 if ([_engine.get() viewController] == self) {
1381 [_engine.get() updateViewportMetrics:_viewportMetrics];
1382 }
1383}

Property Documentation

◆ isKeyboardInOrTransitioningFromBackground

- (BOOL) isKeyboardInOrTransitioningFromBackground
readwritenonatomicassign

Extends class FlutterViewController.

Definition at line 125 of file FlutterViewControllerTest.mm.

◆ keyboardAnimationIsShowing

- (BOOL) keyboardAnimationIsShowing
readwritenonatomicassign

Extends class FlutterViewController.

Definition at line 126 of file FlutterViewControllerTest.mm.

◆ keyboardAnimationVSyncClient

- (VSyncClient*) keyboardAnimationVSyncClient
readwritenonatomicstrong

Extends class FlutterViewController.

Definition at line 127 of file FlutterViewControllerTest.mm.

◆ targetViewInsetBottom

- (double) targetViewInsetBottom
readwritenonatomicassign

Extends class FlutterViewController.

Definition at line 124 of file FlutterViewControllerTest.mm.

◆ touchRateCorrectionVSyncClient

- (VSyncClient*) touchRateCorrectionVSyncClient
readwritenonatomicstrong

Extends class FlutterViewController.

Definition at line 128 of file FlutterViewControllerTest.mm.


The documentation for this category was generated from the following file: