Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,15 @@ - (instancetype)initWithFrame:(CGRect)frame {
return self;
}

// In some scenarios, when we add this view as a maskView of the ChildClippingView, iOS added
// this view as a subview of the ChildClippingView.
// This results this view blocking touch events on the ChildClippingView.
// So we should always ignore any touch events sent to this view.
// See https://github.com/flutter/flutter/issues/66044
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent*)event {
return NO;
}

- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSaveGState(context);
Expand Down
5 changes: 3 additions & 2 deletions testing/scenario_app/ios/Scenarios/Scenarios/AppDelegate.m
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ @implementation AppDelegate
- (BOOL)application:(UIApplication*)application
didFinishLaunchingWithOptions:(NSDictionary*)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];

if ([[[NSProcessInfo processInfo] arguments] containsObject:@"--maskview-blocking"]) {
self.window.tintColor = UIColor.systemPinkColor;
}
NSDictionary<NSString*, NSString*>* launchArgsMap = @{
// The Platform view golden test args should match `PlatformViewGoldenTestManager`.
@"--locale-initialization" : @"locale_initialization",
Expand Down Expand Up @@ -58,7 +60,6 @@ - (BOOL)application:(UIApplication*)application
*stop = YES;
}
}];

if (flutterViewControllerTestName) {
[self setupFlutterViewControllerTest:flutterViewControllerTestName];
} else if ([[[NSProcessInfo processInfo] arguments] containsObject:@"--screen-before-flutter"]) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,54 @@ - (void)testAccept {
[[XCTNSPredicateExpectation alloc] initWithPredicate:predicate object:platformView];

[platformView tap];

[self waitForExpectations:@[ expection ] timeout:kSecondsToWaitForPlatformView];
XCTAssertEqualObjects(platformView.label,
@"-gestureTouchesBegan-gestureTouchesEnded-platformViewTapped");
}

- (void)testGestureWithMaskViewBlockingPlatformView {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does this test fail if you comment out FlutterPlatformViews_Internal.mm #L99-102?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes

XCUIApplication* app = [[XCUIApplication alloc] init];
app.launchArguments = @[ @"--gesture-accept", @"--maskview-blocking" ];
[app launch];

NSPredicate* predicateToFindPlatformView =
[NSPredicate predicateWithBlock:^BOOL(id _Nullable evaluatedObject,
NSDictionary<NSString*, id>* _Nullable bindings) {
XCUIElement* element = evaluatedObject;
return [element.identifier hasPrefix:@"platform_view"];
}];
XCUIElement* platformView = [app.textViews elementMatchingPredicate:predicateToFindPlatformView];
if (![platformView waitForExistenceWithTimeout:kSecondsToWaitForPlatformView]) {
NSLog(@"%@", app.debugDescription);
XCTFail(@"Failed due to not able to find any platformView with %@ seconds",
@(kSecondsToWaitForPlatformView));
}

XCTAssertNotNil(platformView);
XCTAssertEqualObjects(platformView.label, @"");

NSPredicate* predicate = [NSPredicate
predicateWithFormat:@"label == %@",
@"-gestureTouchesBegan-gestureTouchesEnded-platformViewTapped"];
XCTNSPredicateExpectation* expection =
[[XCTNSPredicateExpectation alloc] initWithPredicate:predicate object:platformView];

XCUICoordinate* coordinate =
[self getNormalizedCoordinate:app
point:CGVectorMake(platformView.frame.origin.x + 10,
platformView.frame.origin.y + 10)];
[coordinate tap];

[self waitForExpectations:@[ expection ] timeout:kSecondsToWaitForPlatformView];
XCTAssertEqualObjects(platformView.label,
@"-gestureTouchesBegan-gestureTouchesEnded-platformViewTapped");
}

- (XCUICoordinate*)getNormalizedCoordinate:(XCUIApplication*)app point:(CGVector)vector {
XCUICoordinate* appZero = [app coordinateWithNormalizedOffset:CGVectorMake(0, 0)];
XCUICoordinate* coordinate = [appZero coordinateWithOffset:vector];
return coordinate;
}

@end
34 changes: 30 additions & 4 deletions testing/scenario_app/lib/src/platform_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -336,9 +336,9 @@ class MultiPlatformViewBackgroundForegroundScenario extends Scenario with _BaseP
MultiPlatformViewBackgroundForegroundScenario(Window window, {this.firstId, this.secondId})
: assert(window != null),
super(window) {
_nextFrame = _firstFrame;
createPlatformView(window, 'platform view 1', firstId);
createPlatformView(window, 'platform view 2', secondId);
_nextFrame = _firstFrame;
}

/// The platform view identifier to use for the first platform view.
Expand Down Expand Up @@ -532,6 +532,8 @@ class PlatformViewForTouchIOSScenario extends Scenario

int _viewId;
bool _accept;

VoidCallback _nextFrame;
/// Creates the PlatformView scenario.
///
/// The [window] parameter must not be null.
Expand All @@ -545,14 +547,24 @@ class PlatformViewForTouchIOSScenario extends Scenario
} else {
createPlatformView(window, text, id);
}
_nextFrame = _firstFrame;
}

@override
void onBeginFrame(Duration duration) {
final SceneBuilder builder = SceneBuilder();
_nextFrame();
}

builder.pushOffset(0, 0);
finishBuilderByAddingPlatformViewAndPicture(builder, _viewId);
@override
void onDrawFrame() {
// Some iOS gesture recognizers bugs are introduced in the second frame (with a different platform view rect) after laying out the platform view.
// So in this test, we load 2 frames to ensure that we cover those cases.
// See https://github.com/flutter/flutter/issues/66044
if (_nextFrame == _firstFrame) {
_nextFrame = _secondFrame;
window.scheduleFrame();
}
super.onDrawFrame();
}

@override
Expand Down Expand Up @@ -585,6 +597,20 @@ class PlatformViewForTouchIOSScenario extends Scenario
}

}

void _firstFrame() {
final SceneBuilder builder = SceneBuilder();

builder.pushOffset(0, 0);
finishBuilderByAddingPlatformViewAndPicture(builder, _viewId);
}

void _secondFrame() {
final SceneBuilder builder = SceneBuilder();

builder.pushOffset(5, 5);
finishBuilderByAddingPlatformViewAndPicture(builder, _viewId);
}
}

mixin _BasePlatformViewScenarioMixin on Scenario {
Expand Down