未验证 提交 a832502e 编写于 作者: C chunhtai 提交者: GitHub

Fixes iOS refuses to accept semantics rect update if UISwitch is not … (#26416)

* Fixes iOS refuses to accept semantics rect update if UISwitch is not in the view

* update
上级 a048b8da
......@@ -149,11 +149,10 @@ constexpr int32_t kRootNodeId = 0;
@end
/// A proxy class for SemanticsObject and UISwitch. For most Accessibility and
/// SemanticsObject methods it delegates to the semantics object, otherwise it
/// sends messages to the UISwitch.
@interface FlutterSwitchSemanticsObject : UISwitch
- (instancetype)initWithSemanticsObject:(SemanticsObject*)semanticsObject;
/// The semantics object for switch buttons. This class creates an UISwitch to interact with the
/// iOS.
@interface FlutterSwitchSemanticsObject : SemanticsObject
@end
/**
......
......@@ -37,96 +37,53 @@ flutter::SemanticsAction GetSemanticsActionForScrollDirection(
} // namespace
@implementation FlutterSwitchSemanticsObject {
SemanticsObject* _semanticsObject;
UISwitch* _nativeSwitch;
}
- (instancetype)initWithSemanticsObject:(SemanticsObject*)semanticsObject {
self = [super init];
- (instancetype)initWithBridge:(fml::WeakPtr<flutter::AccessibilityBridgeIos>)bridge
uid:(int32_t)uid {
self = [super initWithBridge:bridge uid:uid];
if (self) {
_semanticsObject = [semanticsObject retain];
_nativeSwitch = [[[UISwitch alloc] init] retain];
}
return self;
}
- (void)dealloc {
[_semanticsObject release];
[_nativeSwitch release];
[super dealloc];
}
- (NSMethodSignature*)methodSignatureForSelector:(SEL)sel {
NSMethodSignature* result = [super methodSignatureForSelector:sel];
if (!result) {
result = [_semanticsObject methodSignatureForSelector:sel];
result = [_nativeSwitch methodSignatureForSelector:sel];
}
return result;
}
- (void)forwardInvocation:(NSInvocation*)anInvocation {
[anInvocation setTarget:_semanticsObject];
[anInvocation setTarget:_nativeSwitch];
[anInvocation invoke];
}
// 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 UISwitch
// class, the base class.
- (CGRect)accessibilityFrame {
return [_semanticsObject accessibilityFrame];
}
- (id)accessibilityContainer {
return [_semanticsObject accessibilityContainer];
}
- (NSString*)accessibilityLabel {
return [_semanticsObject accessibilityLabel];
}
- (NSString*)accessibilityHint {
return [_semanticsObject accessibilityHint];
}
- (NSString*)accessibilityValue {
if ([_semanticsObject node].HasFlag(flutter::SemanticsFlags::kIsToggled) ||
[_semanticsObject node].HasFlag(flutter::SemanticsFlags::kIsChecked)) {
self.on = YES;
if ([self node].HasFlag(flutter::SemanticsFlags::kIsToggled) ||
[self node].HasFlag(flutter::SemanticsFlags::kIsChecked)) {
_nativeSwitch.on = YES;
} else {
self.on = NO;
_nativeSwitch.on = NO;
}
if (![_semanticsObject isAccessibilityBridgeAlive]) {
if (![self isAccessibilityBridgeAlive]) {
return nil;
} else {
return [super accessibilityValue];
return _nativeSwitch.accessibilityValue;
}
}
- (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];
- (UIAccessibilityTraits)accessibilityTraits {
return _nativeSwitch.accessibilityTraits;
}
@end // FlutterSwitchSemanticsObject
......
......@@ -252,35 +252,36 @@ class MockAccessibilityBridge : public AccessibilityBridgeIos {
XCTAssertNil(weakObject);
}
- (void)testFlutterSwitchSemanticsObjectForwardsCalls {
SemanticsObject* mockSemanticsObject = OCMClassMock([SemanticsObject class]);
FlutterSwitchSemanticsObject* switchObj =
[[FlutterSwitchSemanticsObject alloc] initWithSemanticsObject:mockSemanticsObject];
OCMStub([mockSemanticsObject accessibilityActivate]).andReturn(YES);
OCMStub([mockSemanticsObject accessibilityScroll:UIAccessibilityScrollDirectionRight])
.andReturn(NO);
OCMStub([mockSemanticsObject accessibilityPerformEscape]).andReturn(YES);
XCTAssertTrue([switchObj accessibilityActivate]);
OCMVerify([mockSemanticsObject accessibilityActivate]);
[switchObj accessibilityIncrement];
OCMVerify([mockSemanticsObject accessibilityIncrement]);
- (void)testFlutterSwitchSemanticsObjectMatchesUISwitch {
fml::WeakPtrFactory<flutter::MockAccessibilityBridge> factory(
new flutter::MockAccessibilityBridge());
fml::WeakPtr<flutter::MockAccessibilityBridge> bridge = factory.GetWeakPtr();
FlutterSwitchSemanticsObject* object = [[FlutterSwitchSemanticsObject alloc] initWithBridge:bridge
uid:1];
[switchObj accessibilityDecrement];
OCMVerify([mockSemanticsObject accessibilityDecrement]);
// Handle initial setting of node with header.
flutter::SemanticsNode node;
node.flags = static_cast<int32_t>(flutter::SemanticsFlags::kHasToggledState) |
static_cast<int32_t>(flutter::SemanticsFlags::kIsToggled);
node.label = "foo";
[object setSemanticsNode:&node];
// Create ab real UISwitch to compare the FlutterSwitchSemanticsObject with.
UISwitch* nativeSwitch = [[UISwitch alloc] init];
nativeSwitch.on = YES;
XCTAssertFalse([switchObj accessibilityScroll:UIAccessibilityScrollDirectionRight]);
OCMVerify([mockSemanticsObject accessibilityScroll:UIAccessibilityScrollDirectionRight]);
XCTAssertEqual(object.accessibilityTraits, nativeSwitch.accessibilityTraits);
XCTAssertEqual(object.accessibilityValue, nativeSwitch.accessibilityValue);
XCTAssertTrue([switchObj accessibilityPerformEscape]);
OCMVerify([mockSemanticsObject accessibilityPerformEscape]);
// Set the toggled to false;
flutter::SemanticsNode update;
update.flags = static_cast<int32_t>(flutter::SemanticsFlags::kHasToggledState);
update.label = "foo";
[object setSemanticsNode:&update];
[switchObj accessibilityElementDidBecomeFocused];
OCMVerify([mockSemanticsObject accessibilityElementDidBecomeFocused]);
nativeSwitch.on = NO;
[switchObj accessibilityElementDidLoseFocus];
OCMVerify([mockSemanticsObject accessibilityElementDidLoseFocus]);
XCTAssertEqual(object.accessibilityTraits, nativeSwitch.accessibilityTraits);
XCTAssertEqual(object.accessibilityValue, nativeSwitch.accessibilityValue);
}
@end
......@@ -257,10 +257,7 @@ static SemanticsObject* CreateObject(const flutter::SemanticsNode& node,
return [[[TextInputSemanticsObject alloc] initWithBridge:weak_ptr uid:node.id] autorelease];
} else if (node.HasFlag(flutter::SemanticsFlags::kHasToggledState) ||
node.HasFlag(flutter::SemanticsFlags::kHasCheckedState)) {
SemanticsObject* delegateObject =
[[[FlutterSemanticsObject alloc] initWithBridge:weak_ptr uid:node.id] autorelease];
return (SemanticsObject*)[[[FlutterSwitchSemanticsObject alloc]
initWithSemanticsObject:delegateObject] autorelease];
return [[[FlutterSwitchSemanticsObject alloc] initWithBridge:weak_ptr uid:node.id] autorelease];
} else {
return [[[FlutterSemanticsObject alloc] initWithBridge:weak_ptr uid:node.id] autorelease];
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册