From 2a526b317dfeda2422e77b9e49b9d2be3d5ce3df Mon Sep 17 00:00:00 2001 From: chunhtai <47866232+chunhtai@users.noreply.github.com> Date: Mon, 21 Jun 2021 10:21:04 -0700 Subject: [PATCH] Revert "Issues/80711 reland (#26813)" (flutter/engine#26859) This reverts commit d03313b7b3f97d2083e3977d9e62974687760a33. --- .../flutter/lib/ui/semantics/semantics_node.h | 11 +- .../ios/framework/Source/SemanticsObject.h | 24 +- .../ios/framework/Source/SemanticsObject.mm | 225 ++---------------- .../framework/Source/SemanticsObjectTest.mm | 148 +----------- .../framework/Source/accessibility_bridge.mm | 14 +- 5 files changed, 28 insertions(+), 394 deletions(-) diff --git a/engine/src/flutter/lib/ui/semantics/semantics_node.h b/engine/src/flutter/lib/ui/semantics/semantics_node.h index b75d94eb5a0..1d798d66e35 100644 --- a/engine/src/flutter/lib/ui/semantics/semantics_node.h +++ b/engine/src/flutter/lib/ui/semantics/semantics_node.h @@ -44,17 +44,12 @@ enum class SemanticsAction : int32_t { kSetText = 1 << 21, }; -const int kVerticalScrollSemanticsActions = +const int kScrollableSemanticsActions = + static_cast(SemanticsAction::kScrollLeft) | + static_cast(SemanticsAction::kScrollRight) | static_cast(SemanticsAction::kScrollUp) | static_cast(SemanticsAction::kScrollDown); -const int kHorizontalScrollSemanticsActions = - static_cast(SemanticsAction::kScrollLeft) | - static_cast(SemanticsAction::kScrollRight); - -const int kScrollableSemanticsActions = - kVerticalScrollSemanticsActions | kHorizontalScrollSemanticsActions; - /// C/C++ representation of `SemanticsFlags` defined in /// `lib/ui/semantics.dart`. ///\warning This must match the `SemanticsFlags` enum in diff --git a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/SemanticsObject.h b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/SemanticsObject.h index dc9e0073e46..15a77c3efea 100644 --- a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/SemanticsObject.h +++ b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/SemanticsObject.h @@ -13,8 +13,6 @@ #import "flutter/shell/platform/darwin/ios/framework/Source/accessibility_bridge_ios.h" constexpr int32_t kRootNodeId = 0; -// This can be arbitrary number as long as it is bigger than 0. -constexpr float kScrollExtentMaxForInf = 1000; @class FlutterCustomAccessibilityAction; @class FlutterPlatformViewSemanticsContainer; @@ -33,7 +31,7 @@ constexpr float kScrollExtentMaxForInf = 1000; * The parent of this node in the node tree. Will be nil for the root node and * during transient state changes. */ -@property(nonatomic, assign) SemanticsObject* parent; +@property(nonatomic, readonly) SemanticsObject* parent; /** * The accessibility bridge that this semantics object is attached to. This @@ -96,14 +94,6 @@ constexpr float kScrollExtentMaxForInf = 1000; - (BOOL)onCustomAccessibilityAction:(FlutterCustomAccessibilityAction*)action; -/** - * Called after accessibility bridge finishes a semantics update. - * - * Subclasses can override this method if they contain states that can only be - * updated once every node in the accessibility tree has finished updating. - */ -- (void)accessibilityBridgeDidFinishUpdate; - #pragma mark - Designated initializers - (instancetype)init __attribute__((unavailable("Use initWithBridge instead"))); @@ -169,18 +159,6 @@ constexpr float kScrollExtentMaxForInf = 1000; @end -/// The semantics object for scrollable. This class creates an UIScrollView to interact with the -/// iOS. -@interface FlutterScrollableSemanticsObject : UIScrollView - -- (instancetype)init NS_UNAVAILABLE; -- (instancetype)initWithFrame:(CGRect)frame NS_UNAVAILABLE; -- (instancetype)initWithCoder:(NSCoder*)coder NS_UNAVAILABLE; -- (instancetype)initWithSemanticsObject:(SemanticsObject*)semanticsObject NS_DESIGNATED_INITIALIZER; -- (void)accessibilityBridgeDidFinishUpdate; - -@end - /** * Represents a semantics object that has children and hence has to be presented to the OS as a * UIAccessibilityContainer. diff --git a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/SemanticsObject.mm b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/SemanticsObject.mm index 8c9aab6227e..a0748e37c89 100644 --- a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/SemanticsObject.mm +++ b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/SemanticsObject.mm @@ -34,58 +34,6 @@ flutter::SemanticsAction GetSemanticsActionForScrollDirection( return flutter::SemanticsAction::kScrollUp; } -SkM44 GetGlobalTransform(SemanticsObject* reference) { - SkM44 globalTransform = [reference node].transform; - for (SemanticsObject* parent = [reference parent]; parent; parent = parent.parent) { - globalTransform = parent.node.transform * globalTransform; - } - return globalTransform; -} - -SkPoint ApplyTransform(SkPoint& point, const SkM44& transform) { - SkV4 vector = transform.map(point.x(), point.y(), 0, 1); - return SkPoint::Make(vector.x / vector.w, vector.y / vector.w); -} - -CGPoint ConvertPointToGlobal(SemanticsObject* reference, CGPoint local_point) { - SkM44 globalTransform = GetGlobalTransform(reference); - SkPoint point = SkPoint::Make(local_point.x, local_point.y); - point = ApplyTransform(point, globalTransform); - // `rect` is in the physical pixel coordinate system. iOS expects the accessibility frame in - // the logical pixel coordinate system. Therefore, we divide by the `scale` (pixel ratio) to - // convert. - CGFloat scale = [[[reference bridge]->view() window] screen].scale; - auto result = CGPointMake(point.x() / scale, point.y() / scale); - return [[reference bridge]->view() convertPoint:result toView:nil]; -} - -CGRect ConvertRectToGlobal(SemanticsObject* reference, CGRect local_rect) { - SkM44 globalTransform = GetGlobalTransform(reference); - - SkPoint quad[4] = { - SkPoint::Make(local_rect.origin.x, local_rect.origin.y), // top left - SkPoint::Make(local_rect.origin.x + local_rect.size.width, local_rect.origin.y), // top right - SkPoint::Make(local_rect.origin.x + local_rect.size.width, - local_rect.origin.y + local_rect.size.height), // bottom right - SkPoint::Make(local_rect.origin.x, - local_rect.origin.y + local_rect.size.height) // bottom left - }; - for (auto& point : quad) { - point = ApplyTransform(point, globalTransform); - } - SkRect rect; - NSCAssert(rect.setBoundsCheck(quad, 4), @"Transformed points can't form a rect"); - rect.setBounds(quad, 4); - - // `rect` is in the physical pixel coordinate system. iOS expects the accessibility frame in - // the logical pixel coordinate system. Therefore, we divide by the `scale` (pixel ratio) to - // convert. - CGFloat scale = [[[reference bridge]->view() window] screen].scale; - auto result = - CGRectMake(rect.x() / scale, rect.y() / scale, rect.width() / scale, rect.height() / scale); - return UIAccessibilityConvertFrameToScreenCoordinates(result, [reference bridge]->view()); -} - } // namespace @implementation FlutterSwitchSemanticsObject { @@ -140,152 +88,6 @@ CGRect ConvertRectToGlobal(SemanticsObject* reference, CGRect local_rect) { @end // FlutterSwitchSemanticsObject -@interface FlutterScrollableSemanticsObject () -@property(nonatomic, strong) SemanticsObject* semanticsObject; -@end - -@implementation FlutterScrollableSemanticsObject { - fml::scoped_nsobject _container; -} - -- (instancetype)initWithSemanticsObject:(SemanticsObject*)semanticsObject { - self = [super initWithFrame:CGRectZero]; - if (self) { - _semanticsObject = [semanticsObject retain]; - [semanticsObject.bridge->view() addSubview:self]; - } - return self; -} - -- (void)dealloc { - _container.get().semanticsObject = nil; - [_semanticsObject release]; - [self removeFromSuperview]; - [super dealloc]; -} - -- (UIView*)hitTest:(CGPoint)point withEvent:(UIEvent*)event { - return nil; -} - -- (NSMethodSignature*)methodSignatureForSelector:(SEL)sel { - NSMethodSignature* result = [super methodSignatureForSelector:sel]; - if (!result) { - result = [_semanticsObject methodSignatureForSelector:sel]; - } - return result; -} - -- (void)forwardInvocation:(NSInvocation*)anInvocation { - [anInvocation setTarget:_semanticsObject]; - [anInvocation invoke]; -} - -- (void)accessibilityBridgeDidFinishUpdate { - // In order to make iOS think this UIScrollView is scrollable, the following - // requirements must be true. - // 1. contentSize must be bigger than the frame size. - // 2. The scrollable isAccessibilityElement must return YES - // - // Once the requirements are met, the iOS uses contentOffset to determine - // what scroll actions are available. e.g. If the view scrolls vertically and - // contentOffset is 0.0, only the scroll down action is available. - [self setFrame:[_semanticsObject accessibilityFrame]]; - [self setContentSize:[self contentSizeInternal]]; - [self setContentOffset:[self contentOffsetInternal] animated:NO]; - if (self.contentSize.width > self.frame.size.width || - self.contentSize.height > self.frame.size.height) { - self.isAccessibilityElement = YES; - } else { - self.isAccessibilityElement = NO; - } -} - -- (void)setChildren:(NSArray*)children { - [_semanticsObject setChildren:children]; - // The children's parent is pointing to _semanticsObject, need to manually - // set it this object. - for (SemanticsObject* child in _semanticsObject.children) { - child.parent = (SemanticsObject*)self; - } -} - -- (id)accessibilityContainer { - if (_container == nil) { - _container.reset([[SemanticsObjectContainer alloc] - initWithSemanticsObject:(SemanticsObject*)self - bridge:[_semanticsObject bridge]]); - } - return _container.get(); -} - -// private methods - -- (CGSize)contentSizeInternal { - CGRect result; - const SkRect& rect = _semanticsObject.node.rect; - float scrollExtentMax = isfinite(_semanticsObject.node.scrollExtentMax) - ? _semanticsObject.node.scrollExtentMax - : kScrollExtentMaxForInf + _semanticsObject.node.scrollPosition; - if (_semanticsObject.node.actions & flutter::kVerticalScrollSemanticsActions) { - result = CGRectMake(rect.x(), rect.y(), rect.width(), rect.height() + scrollExtentMax); - } else if (_semanticsObject.node.actions & flutter::kHorizontalScrollSemanticsActions) { - result = CGRectMake(rect.x(), rect.y(), rect.width() + scrollExtentMax, rect.height()); - } else { - result = CGRectMake(rect.x(), rect.y(), rect.width(), rect.height()); - } - return ConvertRectToGlobal(_semanticsObject, result).size; -} - -- (CGPoint)contentOffsetInternal { - CGPoint result; - CGPoint origin = self.frame.origin; - const SkRect& rect = _semanticsObject.node.rect; - if (_semanticsObject.node.actions & flutter::kVerticalScrollSemanticsActions) { - result = ConvertPointToGlobal( - _semanticsObject, CGPointMake(rect.x(), rect.y() + _semanticsObject.node.scrollPosition)); - } else if (_semanticsObject.node.actions & flutter::kHorizontalScrollSemanticsActions) { - result = ConvertPointToGlobal( - _semanticsObject, CGPointMake(rect.x() + _semanticsObject.node.scrollPosition, rect.y())); - } else { - result = origin; - } - return CGPointMake(result.x - origin.x, result.y - origin.y); -} - -// The following methods are explicitly forwarded to the wrapped SemanticsObject because the -// forwarding logic above doesn't apply to them since they are also implemented in the -// UIScrollView class, the base class. - -- (BOOL)accessibilityActivate { - return [_semanticsObject accessibilityActivate]; -} - -- (void)accessibilityIncrement { - [_semanticsObject accessibilityIncrement]; -} - -- (void)accessibilityDecrement { - [_semanticsObject accessibilityDecrement]; -} - -- (BOOL)accessibilityScroll:(UIAccessibilityScrollDirection)direction { - return [_semanticsObject accessibilityScroll:direction]; -} - -- (BOOL)accessibilityPerformEscape { - return [_semanticsObject accessibilityPerformEscape]; -} - -- (void)accessibilityElementDidBecomeFocused { - [_semanticsObject accessibilityElementDidBecomeFocused]; -} - -- (void)accessibilityElementDidLoseFocus { - [_semanticsObject accessibilityElementDidLoseFocus]; -} -@end // FlutterScrollableSemanticsObject - @implementation FlutterCustomAccessibilityAction { } @end @@ -372,9 +174,6 @@ CGRect ConvertRectToGlobal(SemanticsObject* reference, CGRect local_rect) { _node = *node; } -- (void)accessibilityBridgeDidFinishUpdate { /* Do nothing by default */ -} - /** * Whether calling `setSemanticsNode:` with `node` would cause a layout change. */ @@ -599,9 +398,27 @@ CGRect ConvertRectToGlobal(SemanticsObject* reference, CGRect local_rect) { } - (CGRect)globalRect { - const SkRect& rect = [self node].rect; - CGRect localRect = CGRectMake(rect.x(), rect.y(), rect.width(), rect.height()); - return ConvertRectToGlobal(self, localRect); + SkM44 globalTransform = [self node].transform; + for (SemanticsObject* parent = [self parent]; parent; parent = parent.parent) { + globalTransform = parent.node.transform * globalTransform; + } + + SkPoint quad[4]; + [self node].rect.toQuad(quad); + for (auto& point : quad) { + SkV4 vector = globalTransform.map(point.x(), point.y(), 0, 1); + point.set(vector.x / vector.w, vector.y / vector.w); + } + SkRect rect; + rect.setBounds(quad, 4); + + // `rect` is in the physical pixel coordinate system. iOS expects the accessibility frame in + // the logical pixel coordinate system. Therefore, we divide by the `scale` (pixel ratio) to + // convert. + CGFloat scale = [[[self bridge]->view() window] screen].scale; + auto result = + CGRectMake(rect.x() / scale, rect.y() / scale, rect.width() / scale, rect.height() / scale); + return UIAccessibilityConvertFrameToScreenCoordinates(result, [self bridge]->view()); } #pragma mark - UIAccessibilityElement protocol diff --git a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/SemanticsObjectTest.mm b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/SemanticsObjectTest.mm index d6447abc915..1dcf8371d69 100644 --- a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/SemanticsObjectTest.mm +++ b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/SemanticsObjectTest.mm @@ -10,8 +10,6 @@ FLUTTER_ASSERT_ARC -const CGRect kScreenSize = CGRectMake(0, 0, 600, 800); - namespace flutter { namespace { @@ -26,11 +24,7 @@ class SemanticsActionObservation { class MockAccessibilityBridge : public AccessibilityBridgeIos { public: - MockAccessibilityBridge() : observations({}) { - view_ = [[UIView alloc] initWithFrame:kScreenSize]; - window_ = [[UIWindow alloc] initWithFrame:kScreenSize]; - [window_ addSubview:view_]; - } + MockAccessibilityBridge() : observations({}) { view_ = [[UIView alloc] init]; } UIView* view() const override { return view_; } UIView* textInputView() override { return nil; } void DispatchSemanticsAction(int32_t id, SemanticsAction action) override { @@ -52,7 +46,6 @@ class MockAccessibilityBridge : public AccessibilityBridgeIos { private: UIView* view_; - UIWindow* window_; }; } // namespace } // namespace flutter @@ -167,145 +160,6 @@ class MockAccessibilityBridge : public AccessibilityBridgeIos { XCTAssertEqual([object accessibilityTraits], UIAccessibilityTraitButton); } -- (void)testVerticalFlutterScrollableSemanticsObject { - fml::WeakPtrFactory factory( - new flutter::MockAccessibilityBridge()); - fml::WeakPtr bridge = factory.GetWeakPtr(); - - float transformScale = 0.5f; - float screenScale = [[bridge->view() window] screen].scale; - float effectivelyScale = transformScale / screenScale; - float x = 10; - float y = 10; - float w = 100; - float h = 200; - float scrollExtentMax = 500.0; - float scrollPosition = 150.0; - - flutter::SemanticsNode node; - node.flags = static_cast(flutter::SemanticsFlags::kHasImplicitScrolling); - node.actions = flutter::kVerticalScrollSemanticsActions; - node.rect = SkRect::MakeXYWH(x, y, w, h); - node.scrollExtentMax = scrollExtentMax; - node.scrollPosition = scrollPosition; - node.transform = { - transformScale, 0, 0, 0, 0, transformScale, 0, 0, 0, 0, transformScale, 0, 0, 0, 0, 1.0}; - FlutterSemanticsObject* delegate = [[FlutterSemanticsObject alloc] initWithBridge:bridge uid:0]; - FlutterScrollableSemanticsObject* scrollable = - [[FlutterScrollableSemanticsObject alloc] initWithSemanticsObject:delegate]; - SemanticsObject* scrollable_object = static_cast(scrollable); - [scrollable_object setSemanticsNode:&node]; - [scrollable_object accessibilityBridgeDidFinishUpdate]; - XCTAssertTrue( - CGRectEqualToRect(scrollable.frame, CGRectMake(x * effectivelyScale, y * effectivelyScale, - w * effectivelyScale, h * effectivelyScale))); - XCTAssertTrue(CGSizeEqualToSize( - scrollable.contentSize, - CGSizeMake(w * effectivelyScale, (h + scrollExtentMax) * effectivelyScale))); - XCTAssertTrue(CGPointEqualToPoint(scrollable.contentOffset, - CGPointMake(0, scrollPosition * effectivelyScale))); -} - -- (void)testHorizontalFlutterScrollableSemanticsObject { - fml::WeakPtrFactory factory( - new flutter::MockAccessibilityBridge()); - fml::WeakPtr bridge = factory.GetWeakPtr(); - - float transformScale = 0.5f; - float screenScale = [[bridge->view() window] screen].scale; - float effectivelyScale = transformScale / screenScale; - float x = 10; - float y = 10; - float w = 100; - float h = 200; - float scrollExtentMax = 500.0; - float scrollPosition = 150.0; - - flutter::SemanticsNode node; - node.flags = static_cast(flutter::SemanticsFlags::kHasImplicitScrolling); - node.actions = flutter::kHorizontalScrollSemanticsActions; - node.rect = SkRect::MakeXYWH(x, y, w, h); - node.scrollExtentMax = scrollExtentMax; - node.scrollPosition = scrollPosition; - node.transform = { - transformScale, 0, 0, 0, 0, transformScale, 0, 0, 0, 0, transformScale, 0, 0, 0, 0, 1.0}; - FlutterSemanticsObject* delegate = [[FlutterSemanticsObject alloc] initWithBridge:bridge uid:0]; - FlutterScrollableSemanticsObject* scrollable = - [[FlutterScrollableSemanticsObject alloc] initWithSemanticsObject:delegate]; - SemanticsObject* scrollable_object = static_cast(scrollable); - [scrollable_object setSemanticsNode:&node]; - [scrollable_object accessibilityBridgeDidFinishUpdate]; - XCTAssertTrue( - CGRectEqualToRect(scrollable.frame, CGRectMake(x * effectivelyScale, y * effectivelyScale, - w * effectivelyScale, h * effectivelyScale))); - XCTAssertTrue(CGSizeEqualToSize( - scrollable.contentSize, - CGSizeMake((w + scrollExtentMax) * effectivelyScale, h * effectivelyScale))); - XCTAssertTrue(CGPointEqualToPoint(scrollable.contentOffset, - CGPointMake(scrollPosition * effectivelyScale, 0))); -} - -- (void)testCanHandleInfiniteScrollExtent { - fml::WeakPtrFactory factory( - new flutter::MockAccessibilityBridge()); - fml::WeakPtr bridge = factory.GetWeakPtr(); - - float transformScale = 0.5f; - float screenScale = [[bridge->view() window] screen].scale; - float effectivelyScale = transformScale / screenScale; - float x = 10; - float y = 10; - float w = 100; - float h = 200; - float scrollExtentMax = INFINITY; - float scrollPosition = 150.0; - - flutter::SemanticsNode node; - node.flags = static_cast(flutter::SemanticsFlags::kHasImplicitScrolling); - node.actions = flutter::kVerticalScrollSemanticsActions; - node.rect = SkRect::MakeXYWH(x, y, w, h); - node.scrollExtentMax = scrollExtentMax; - node.scrollPosition = scrollPosition; - node.transform = { - transformScale, 0, 0, 0, 0, transformScale, 0, 0, 0, 0, transformScale, 0, 0, 0, 0, 1.0}; - FlutterSemanticsObject* delegate = [[FlutterSemanticsObject alloc] initWithBridge:bridge uid:0]; - FlutterScrollableSemanticsObject* scrollable = - [[FlutterScrollableSemanticsObject alloc] initWithSemanticsObject:delegate]; - SemanticsObject* scrollable_object = static_cast(scrollable); - [scrollable_object setSemanticsNode:&node]; - [scrollable_object accessibilityBridgeDidFinishUpdate]; - XCTAssertTrue( - CGRectEqualToRect(scrollable.frame, CGRectMake(x * effectivelyScale, y * effectivelyScale, - w * effectivelyScale, h * effectivelyScale))); - XCTAssertTrue(CGSizeEqualToSize( - scrollable.contentSize, - CGSizeMake(w * effectivelyScale, - (h + kScrollExtentMaxForInf + scrollPosition) * effectivelyScale))); - XCTAssertTrue(CGPointEqualToPoint(scrollable.contentOffset, - CGPointMake(0, scrollPosition * effectivelyScale))); -} - -- (void)testFlutterScrollableSemanticsObjectIsNotHittestable { - fml::WeakPtrFactory factory( - new flutter::MockAccessibilityBridge()); - fml::WeakPtr bridge = factory.GetWeakPtr(); - - flutter::SemanticsNode node; - node.flags = static_cast(flutter::SemanticsFlags::kHasImplicitScrolling); - node.actions = flutter::kHorizontalScrollSemanticsActions; - node.rect = SkRect::MakeXYWH(0, 0, 100, 200); - node.scrollExtentMax = 100.0; - node.scrollPosition = 0.0; - - FlutterSemanticsObject* delegate = [[FlutterSemanticsObject alloc] initWithBridge:bridge uid:0]; - FlutterScrollableSemanticsObject* scrollable = - [[FlutterScrollableSemanticsObject alloc] initWithSemanticsObject:delegate]; - SemanticsObject* scrollable_object = static_cast(scrollable); - [scrollable_object setSemanticsNode:&node]; - [scrollable_object accessibilityBridgeDidFinishUpdate]; - XCTAssertEqual([scrollable hitTest:CGPointMake(10, 10) withEvent:nil], nil); -} - - (void)testSemanticsObjectBuildsAttributedString { fml::WeakPtrFactory factory( new flutter::MockAccessibilityBridge()); diff --git a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/accessibility_bridge.mm b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/accessibility_bridge.mm index 073d1d22393..6b0c0f5cb15 100644 --- a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/accessibility_bridge.mm +++ b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/accessibility_bridge.mm @@ -200,16 +200,11 @@ void AccessibilityBridge::UpdateSemantics(flutter::SemanticsNodeUpdates nodes, view_controller_.view.accessibilityElements = nil; } - NSMutableArray* doomed_uids = [NSMutableArray arrayWithArray:[objects_ allKeys]]; - if (root) { + NSMutableArray* doomed_uids = [NSMutableArray arrayWithArray:[objects_.get() allKeys]]; + if (root) VisitObjectsRecursivelyAndRemove(root, doomed_uids); - } [objects_ removeObjectsForKeys:doomed_uids]; - for (SemanticsObject* object in [objects_ allValues]) { - [object accessibilityBridgeDidFinishUpdate]; - } - if (!ios_delegate_->IsFlutterViewControllerPresentingModalViewController(view_controller_)) { layoutChanged = layoutChanged || [doomed_uids count] > 0; @@ -263,11 +258,6 @@ static SemanticsObject* CreateObject(const flutter::SemanticsNode& node, } else if (node.HasFlag(flutter::SemanticsFlags::kHasToggledState) || node.HasFlag(flutter::SemanticsFlags::kHasCheckedState)) { return [[[FlutterSwitchSemanticsObject alloc] initWithBridge:weak_ptr uid:node.id] autorelease]; - } else if (node.HasFlag(flutter::SemanticsFlags::kHasImplicitScrolling)) { - SemanticsObject* delegateObject = - [[[FlutterSemanticsObject alloc] initWithBridge:weak_ptr uid:node.id] autorelease]; - return (SemanticsObject*)[[[FlutterScrollableSemanticsObject alloc] - initWithSemanticsObject:delegateObject] autorelease]; } else { return [[[FlutterSemanticsObject alloc] initWithBridge:weak_ptr uid:node.id] autorelease]; }