diff --git a/iOS/DiDiPrism/Src/Core/Instruction/Parser/PrismBaseInstructionParser+Protected.h b/iOS/DiDiPrism/Src/Core/Instruction/Parser/PrismBaseInstructionParser+Protected.h index 73690d5..00586c7 100644 --- a/iOS/DiDiPrism/Src/Core/Instruction/Parser/PrismBaseInstructionParser+Protected.h +++ b/iOS/DiDiPrism/Src/Core/Instruction/Parser/PrismBaseInstructionParser+Protected.h @@ -16,7 +16,7 @@ NS_ASSUME_NONNULL_BEGIN cellSectionOrOriginX:(CGFloat)cellSectionOrOriginX cellRowOrOriginY:(CGFloat)cellRowOrOriginY fromSuperView:(UIView*)superView; -- (UIResponder*)searchResponderWithClassName:(NSString*)className superResponder:(UIResponder*)superResponder; +- (NSArray*)searchRespondersWithClassName:(NSString*)className superResponders:(NSArray*)superResponders; - (void)scrollToIdealOffsetWithScrollView:(UIScrollView*)scrollView targetElement:(UIView*)targetElement; - (void)highlightTheElement:(UIView*)element withCompletion:(void(^)(void))block; - (BOOL)isAreaInfoEqualBetween:(NSString*)one withAnother:(NSString*)another allowCompatibleMode:(BOOL)allowCompatibleMode; diff --git a/iOS/DiDiPrism/Src/Core/Instruction/Parser/PrismBaseInstructionParser+Protected.m b/iOS/DiDiPrism/Src/Core/Instruction/Parser/PrismBaseInstructionParser+Protected.m index 5b9845e..269a203 100644 --- a/iOS/DiDiPrism/Src/Core/Instruction/Parser/PrismBaseInstructionParser+Protected.m +++ b/iOS/DiDiPrism/Src/Core/Instruction/Parser/PrismBaseInstructionParser+Protected.m @@ -189,34 +189,37 @@ - (UIView*)searchScrollViewCellWithScrollViewClassName:(NSString*)scrollViewClas return nil; } -- (UIResponder*)searchResponderWithClassName:(NSString*)className superResponder:(UIResponder*)superResponder { - if ([superResponder isKindOfClass:[UIViewController class]]) { - UIViewController *viewController = (UIViewController*)superResponder; - for (UIViewController *responder in viewController.childViewControllers) { - // 场景:一个viewController下有4个同样的子viewController。 - if ([responder isKindOfClass:NSClassFromString(className)] && responder.view.superview) { - if ([superResponder isKindOfClass:[UINavigationController class]]) { - UINavigationController *navController = (UINavigationController*)superResponder; - if (navController.topViewController == responder - || navController.visibleViewController == responder) { - return responder; +- (NSArray*)searchRespondersWithClassName:(NSString*)className superResponders:(NSArray*)superResponders { + NSMutableArray *allResponders = [NSMutableArray array]; + for (UIResponder *superResponder in superResponders) { + if ([superResponder isKindOfClass:[UIViewController class]]) { + UIViewController *viewController = (UIViewController*)superResponder; + for (UIViewController *responder in viewController.childViewControllers) { + // 场景:一个viewController下有4个同样的子viewController。 + if ([responder isKindOfClass:NSClassFromString(className)] && responder.view.superview) { + if ([superResponder isKindOfClass:[UINavigationController class]]) { + UINavigationController *navController = (UINavigationController*)superResponder; + if (navController.topViewController == responder + || navController.visibleViewController == responder) { + [allResponders addObject:responder]; + } + } + else { + [allResponders addObject:responder]; } - } - else { - return responder; } } } - } - else if ([superResponder isKindOfClass:[UIView class]]) { - UIView *view = (UIView*)superResponder; - for (UIResponder *responder in [view subviews]) { - if ([responder isKindOfClass:NSClassFromString(className)]) { - return responder; + else if ([superResponder isKindOfClass:[UIView class]]) { + UIView *view = (UIView*)superResponder; + for (UIResponder *responder in [view subviews]) { + if ([responder isKindOfClass:NSClassFromString(className)]) { + [allResponders addObject:responder]; + } } } } - return nil; + return [allResponders copy]; } - (void)scrollToIdealOffsetWithScrollView:(UIScrollView*)scrollView targetElement:(UIView*)targetElement { diff --git a/iOS/DiDiPrism/Src/Core/Instruction/Parser/PrismCellInstructionParser.m b/iOS/DiDiPrism/Src/Core/Instruction/Parser/PrismCellInstructionParser.m index 3cb6dfc..1837768 100644 --- a/iOS/DiDiPrism/Src/Core/Instruction/Parser/PrismCellInstructionParser.m +++ b/iOS/DiDiPrism/Src/Core/Instruction/Parser/PrismCellInstructionParser.m @@ -29,36 +29,47 @@ - (PrismInstructionParseResult)parseWithFormatter:(PrismInstructionFormatter *)f return PrismInstructionParseResultFail; } + NSArray *allPossibleResponder = [NSArray arrayWithObject:responder]; for (NSInteger index = 2; index < viewPathArray.count; index++) { Class class = NSClassFromString(viewPathArray[index]); if (!class) { break; } - UIResponder *result = [self searchResponderWithClassName:viewPathArray[index] superResponder:responder]; - if (!result) { + NSArray *result = [self searchRespondersWithClassName:viewPathArray[index] superResponders:allPossibleResponder]; + if (!result.count) { break; } - responder = result; + allPossibleResponder = result; } - // 解析列表信息 - NSArray *viewListArray = [formatter instructionFragmentWithType:PrismInstructionFragmentTypeViewList]; - UIView *targetView = [responder isKindOfClass:[UIViewController class]] ? [(UIViewController*)responder view] : (UIView*)responder; - for (NSInteger index = 1; index < viewListArray.count; index = index + 4) { - if ([NSClassFromString(viewListArray[index]) isSubclassOfClass:[UIScrollView class]]) { - NSString *scrollViewClassName = viewListArray[index]; - NSString *cellClassName = viewListArray[index + 1]; - CGFloat cellSectionOrOriginX = viewListArray[index + 2].floatValue; - CGFloat cellRowOrOriginY = viewListArray[index + 3].floatValue; - UIView *scrollViewCell = [self searchScrollViewCellWithScrollViewClassName:scrollViewClassName - cellClassName:cellClassName - cellSectionOrOriginX:cellSectionOrOriginX - cellRowOrOriginY:cellRowOrOriginY - fromSuperView:targetView]; - if (!scrollViewCell) { - return PrismInstructionParseResultFail; + UIView *targetView = nil; + + for (UIResponder *possibleResponder in allPossibleResponder) { + + // 解析列表信息 + NSArray *viewListArray = [formatter instructionFragmentWithType:PrismInstructionFragmentTypeViewList]; + targetView = [possibleResponder isKindOfClass:[UIViewController class]] ? [(UIViewController*)possibleResponder view] : (UIView*)possibleResponder; + for (NSInteger index = 1; index < viewListArray.count; index = index + 4) { + if ([NSClassFromString(viewListArray[index]) isSubclassOfClass:[UIScrollView class]]) { + NSString *scrollViewClassName = viewListArray[index]; + NSString *cellClassName = viewListArray[index + 1]; + CGFloat cellSectionOrOriginX = viewListArray[index + 2].floatValue; + CGFloat cellRowOrOriginY = viewListArray[index + 3].floatValue; + UIView *scrollViewCell = [self searchScrollViewCellWithScrollViewClassName:scrollViewClassName + cellClassName:cellClassName + cellSectionOrOriginX:cellSectionOrOriginX + cellRowOrOriginY:cellRowOrOriginY + fromSuperView:targetView]; + if (!scrollViewCell) { + targetView = nil; + break; + } + targetView = scrollViewCell; } - targetView = scrollViewCell; + } + + if (targetView) { + break; } } diff --git a/iOS/DiDiPrism/Src/Core/Instruction/Parser/PrismControlInstructionParser.m b/iOS/DiDiPrism/Src/Core/Instruction/Parser/PrismControlInstructionParser.m index e5e7760..4794081 100644 --- a/iOS/DiDiPrism/Src/Core/Instruction/Parser/PrismControlInstructionParser.m +++ b/iOS/DiDiPrism/Src/Core/Instruction/Parser/PrismControlInstructionParser.m @@ -32,109 +32,125 @@ - (PrismInstructionParseResult)parseWithFormatter:(PrismInstructionFormatter *)f return PrismInstructionParseResultFail; } + NSArray *allPossibleResponder = [NSArray arrayWithObject:responder]; for (NSInteger index = 2; index < viewPathArray.count; index++) { Class class = NSClassFromString(viewPathArray[index]); // 针对弹窗,vp的最后一位会记录控件信息,略过。因为后续逻辑会考虑。 if (!class || [class isSubclassOfClass:[UIControl class]]) { break; } - UIResponder *result = [self searchResponderWithClassName:viewPathArray[index] superResponder:responder]; - if (!result) { + NSArray *result = [self searchRespondersWithClassName:viewPathArray[index] superResponders:allPossibleResponder]; + if (!result.count) { break; } - responder = result; + allPossibleResponder = result; } - // 解析列表信息 - NSArray *viewListArray = [formatter instructionFragmentWithType:PrismInstructionFragmentTypeViewList]; - UIView *targetView = [responder isKindOfClass:[UIViewController class]] ? [(UIViewController*)responder view] : (UIView*)responder; UIView *lastScrollView = nil; - for (NSInteger index = 1; index < viewListArray.count; index = index + 4) { - if ([NSClassFromString(viewListArray[index]) isSubclassOfClass:[UIScrollView class]]) { - // 兼容模式直接省略对列表信息的解析。 - if (!self.isCompatibleMode) { - NSString *scrollViewClassName = viewListArray[index]; - NSString *cellClassName = viewListArray[index + 1]; - CGFloat cellSectionOrOriginX = viewListArray[index + 2].floatValue; - CGFloat cellRowOrOriginY = viewListArray[index + 3].floatValue; - UIView *scrollViewCell = [self searchScrollViewCellWithScrollViewClassName:scrollViewClassName - cellClassName:cellClassName - cellSectionOrOriginX:cellSectionOrOriginX - cellRowOrOriginY:cellRowOrOriginY - fromSuperView:targetView]; - if (!scrollViewCell) { - return PrismInstructionParseResultFail; + + for (UIResponder *possibleResponder in allPossibleResponder) { + + lastScrollView = nil; + UIView *targetView = [possibleResponder isKindOfClass:[UIViewController class]] ? [(UIViewController*)possibleResponder view] : (UIView*)possibleResponder; + // 解析列表信息 + NSArray *viewListArray = [formatter instructionFragmentWithType:PrismInstructionFragmentTypeViewList]; + for (NSInteger index = 1; index < viewListArray.count; index = index + 4) { + if ([NSClassFromString(viewListArray[index]) isSubclassOfClass:[UIScrollView class]]) { + // 兼容模式直接省略对列表信息的解析。 + if (!self.isCompatibleMode) { + NSString *scrollViewClassName = viewListArray[index]; + NSString *cellClassName = viewListArray[index + 1]; + CGFloat cellSectionOrOriginX = viewListArray[index + 2].floatValue; + CGFloat cellRowOrOriginY = viewListArray[index + 3].floatValue; + UIView *scrollViewCell = [self searchScrollViewCellWithScrollViewClassName:scrollViewClassName + cellClassName:cellClassName + cellSectionOrOriginX:cellSectionOrOriginX + cellRowOrOriginY:cellRowOrOriginY + fromSuperView:targetView]; + if (!scrollViewCell) { + targetView = nil; + lastScrollView = nil; + break; + } + targetView = scrollViewCell; + lastScrollView = scrollViewCell.superview; } - targetView = scrollViewCell; - lastScrollView = scrollViewCell.superview; } } - } - - // 解析区位信息+功能信息 - NSArray *viewQuadrantArray = [formatter instructionFragmentWithType:PrismInstructionFragmentTypeViewQuadrant]; - NSArray *viewRepresentativeContentArray = [formatter instructionFragmentWithType:PrismInstructionFragmentTypeViewRepresentativeContent]; - NSArray *viewFunctionArray = [formatter instructionFragmentWithType:PrismInstructionFragmentTypeViewFunction]; + if (!targetView) { + continue; + } + + // 解析区位信息+功能信息 + NSArray *viewQuadrantArray = [formatter instructionFragmentWithType:PrismInstructionFragmentTypeViewQuadrant]; + NSArray *viewRepresentativeContentArray = [formatter instructionFragmentWithType:PrismInstructionFragmentTypeViewRepresentativeContent]; + NSArray *viewFunctionArray = [formatter instructionFragmentWithType:PrismInstructionFragmentTypeViewFunction]; - NSString *areaInfo = [viewQuadrantArray prism_stringWithIndex:1]; - if (viewRepresentativeContentArray.count && viewFunctionArray.count) { - NSMutableString *representativeContent = [NSMutableString string]; - for (NSInteger index = 1; index < viewRepresentativeContentArray.count; index++) { - if (index > 1) { - [representativeContent appendString:kConnectorFlag]; + NSString *areaInfo = [viewQuadrantArray prism_stringWithIndex:1]; + if (viewRepresentativeContentArray.count && viewFunctionArray.count) { + NSMutableString *representativeContent = [NSMutableString string]; + for (NSInteger index = 1; index < viewRepresentativeContentArray.count; index++) { + if (index > 1) { + [representativeContent appendString:kConnectorFlag]; + } + [representativeContent appendString:[viewRepresentativeContentArray prism_stringWithIndex:index]]; } - [representativeContent appendString:[viewRepresentativeContentArray prism_stringWithIndex:index]]; - } - Class targetClass = NSClassFromString([viewFunctionArray prism_objectAtIndex:1]); - NSString *targetAction = [viewFunctionArray prism_stringWithIndex:2]; - targetControl = [self searchControlWithArea:areaInfo withRepresentativeContent:[representativeContent copy] withTargetClass:targetClass withAction:targetAction fromSuperView:targetView]; - // 有列表的场景,考虑到列表中的元素index可能会变化,可以做一定的兼容。 - if (!targetControl && lastScrollView) { - for (UIView *subview in lastScrollView.subviews) { - UIControl *resultControl = [self searchControlWithArea:areaInfo withRepresentativeContent:[representativeContent copy] withTargetClass:targetClass withAction:targetAction fromSuperView:subview]; - if (resultControl) { - targetControl = resultControl; - break; + Class targetClass = NSClassFromString([viewFunctionArray prism_objectAtIndex:1]); + NSString *targetAction = [viewFunctionArray prism_stringWithIndex:2]; + targetControl = [self searchControlWithArea:areaInfo withRepresentativeContent:[representativeContent copy] withTargetClass:targetClass withAction:targetAction fromSuperView:targetView]; + // 有列表的场景,考虑到列表中的元素index可能会变化,可以做一定的兼容。 + if (!targetControl && lastScrollView) { + for (UIView *subview in lastScrollView.subviews) { + UIControl *resultControl = [self searchControlWithArea:areaInfo withRepresentativeContent:[representativeContent copy] withTargetClass:targetClass withAction:targetAction fromSuperView:subview]; + if (resultControl) { + targetControl = resultControl; + break; + } } } } - } - // target + selector - else if (viewFunctionArray.count) { - Class targetClass = NSClassFromString([viewFunctionArray prism_objectAtIndex:1]); - NSString *targetAction = [viewFunctionArray prism_stringWithIndex:2]; - targetControl = [self searchControlWithArea:areaInfo withTargetClass:targetClass withAction:targetAction fromSuperView:targetView]; - // 有列表的场景,考虑到列表中的元素index可能会变化,可以做一定的兼容。 - if (!targetControl && lastScrollView) { - for (UIView *subview in lastScrollView.subviews) { - targetControl = [self searchControlWithArea:areaInfo withTargetClass:targetClass withAction:targetAction fromSuperView:subview]; - if (targetControl) { - break; + // target + selector + else if (viewFunctionArray.count) { + Class targetClass = NSClassFromString([viewFunctionArray prism_objectAtIndex:1]); + NSString *targetAction = [viewFunctionArray prism_stringWithIndex:2]; + targetControl = [self searchControlWithArea:areaInfo withTargetClass:targetClass withAction:targetAction fromSuperView:targetView]; + // 有列表的场景,考虑到列表中的元素index可能会变化,可以做一定的兼容。 + if (!targetControl && lastScrollView) { + for (UIView *subview in lastScrollView.subviews) { + targetControl = [self searchControlWithArea:areaInfo withTargetClass:targetClass withAction:targetAction fromSuperView:subview]; + if (targetControl) { + break; + } } } } - } - // title or image - else if (viewRepresentativeContentArray.count) { - NSMutableString *viewContent = [NSMutableString string]; - for (NSInteger index = 1; index < viewRepresentativeContentArray.count; index++) { - if (index > 1) { - [viewContent appendString:kConnectorFlag]; + // title or image + else if (viewRepresentativeContentArray.count) { + NSMutableString *viewContent = [NSMutableString string]; + for (NSInteger index = 1; index < viewRepresentativeContentArray.count; index++) { + if (index > 1) { + [viewContent appendString:kConnectorFlag]; + } + [viewContent appendString:[viewRepresentativeContentArray prism_stringWithIndex:index]]; } - [viewContent appendString:[viewRepresentativeContentArray prism_stringWithIndex:index]]; - } - targetControl = [self searchControlWithArea:areaInfo withRepresentativeContent:[viewContent copy] fromSuperView:targetView]; - // 有列表的场景,考虑到列表中的元素index可能会变化,可以做一定的兼容。 - if (!targetControl && lastScrollView) { - for (UIView *subview in lastScrollView.subviews) { - targetControl = [self searchControlWithArea:areaInfo withRepresentativeContent:[viewContent copy] fromSuperView:subview]; - if (targetControl) { - break; + targetControl = [self searchControlWithArea:areaInfo withRepresentativeContent:[viewContent copy] fromSuperView:targetView]; + // 有列表的场景,考虑到列表中的元素index可能会变化,可以做一定的兼容。 + if (!targetControl && lastScrollView) { + for (UIView *subview in lastScrollView.subviews) { + targetControl = [self searchControlWithArea:areaInfo withRepresentativeContent:[viewContent copy] fromSuperView:subview]; + if (targetControl) { + break; + } } } } + + if (targetControl) { + break; + } } + if (targetControl) { [self scrollToIdealOffsetWithScrollView:(UIScrollView*)lastScrollView targetElement:targetControl]; [self highlightTheElement:targetControl withCompletion:^{ diff --git a/iOS/DiDiPrism/Src/Core/Instruction/Parser/PrismEdgePanGestureInstructionParser.m b/iOS/DiDiPrism/Src/Core/Instruction/Parser/PrismEdgePanGestureInstructionParser.m index e6112cd..f950f8d 100644 --- a/iOS/DiDiPrism/Src/Core/Instruction/Parser/PrismEdgePanGestureInstructionParser.m +++ b/iOS/DiDiPrism/Src/Core/Instruction/Parser/PrismEdgePanGestureInstructionParser.m @@ -29,32 +29,44 @@ - (PrismInstructionParseResult)parseWithFormatter:(PrismInstructionFormatter *)f if (!viewPathArray.lastObject.length) { viewPathArray = [viewPathArray subarrayWithRange:NSMakeRange(0, viewPathArray.count - 1)]; } + + NSArray *allPossibleResponder = [NSArray arrayWithObject:responder]; NSInteger index = 2; for (; index < viewPathArray.count; index++) { Class class = NSClassFromString(viewPathArray[index]); if (!class) { break; } - UIResponder *result = [self searchResponderWithClassName:viewPathArray[index] superResponder:responder]; - if (!result) { + NSArray *result = [self searchRespondersWithClassName:viewPathArray[index] superResponders:allPossibleResponder]; + if (!result.count) { break; } - responder = result; + allPossibleResponder = result; } if (index < viewPathArray.count) { return PrismInstructionParseResultError; } + UIScreenEdgePanGestureRecognizer *edgePanGesture = nil; UIViewController *targetViewController = nil; - if ([responder isKindOfClass:[UIView class]]) { - UIView *view = (UIView*)responder; - targetViewController = [view prism_viewController]; - } - else { - targetViewController = (UIViewController*)responder; + + for (UIResponder *possibleResponder in allPossibleResponder) { + + if ([possibleResponder isKindOfClass:[UIView class]]) { + UIView *view = (UIView*)possibleResponder; + targetViewController = [view prism_viewController]; + } + else { + targetViewController = (UIViewController*)possibleResponder; + } + UIView *targetView = targetViewController.view; + edgePanGesture = [self searchEdgePanGestureFromSuperView:targetView]; + + if (edgePanGesture) { + break; + } } - UIView *targetView = targetViewController.view; - UIScreenEdgePanGestureRecognizer *edgePanGesture = [self searchEdgePanGestureFromSuperView:targetView]; + if (edgePanGesture) { if ([targetViewController isKindOfClass:[UINavigationController class]]) { [(UINavigationController*)targetViewController popViewControllerAnimated:YES]; diff --git a/iOS/DiDiPrism/Src/Core/Instruction/Parser/PrismLongPressGestureInstructionParser.m b/iOS/DiDiPrism/Src/Core/Instruction/Parser/PrismLongPressGestureInstructionParser.m index eb89b01..b682aad 100644 --- a/iOS/DiDiPrism/Src/Core/Instruction/Parser/PrismLongPressGestureInstructionParser.m +++ b/iOS/DiDiPrism/Src/Core/Instruction/Parser/PrismLongPressGestureInstructionParser.m @@ -26,90 +26,100 @@ - (PrismInstructionParseResult)parseWithFormatter:(PrismInstructionFormatter *)f return PrismInstructionParseResultFail; } + NSArray *allPossibleResponder = [NSArray arrayWithObject:responder]; for (NSInteger index = 2; index < viewPathArray.count; index++) { Class class = NSClassFromString(viewPathArray[index]); if (!class) { break; } - UIResponder *result = [self searchResponderWithClassName:viewPathArray[index] superResponder:responder]; - if (!result) { + NSArray *result = [self searchRespondersWithClassName:viewPathArray[index] superResponders:allPossibleResponder]; + if (!result.count) { break; } - responder = result; + allPossibleResponder = result; } - // 解析列表信息 - NSArray *viewListArray = [formatter instructionFragmentWithType:PrismInstructionFragmentTypeViewList]; + UILongPressGestureRecognizer *longPressGesture = nil; UIView *lastScrollView = nil; - UIView *targetView = [responder isKindOfClass:[UIViewController class]] ? [(UIViewController*)responder view] : (UIView*)responder; - for (NSInteger index = 1; index < viewListArray.count; index = index + 4) { - if ([NSClassFromString(viewListArray[index]) isSubclassOfClass:[UIScrollView class]]) { - // 兼容模式直接省略对列表信息的解析。 - if (!self.isCompatibleMode) { - NSString *scrollViewClassName = viewListArray[index]; - NSString *cellClassName = viewListArray[index + 1]; - CGFloat cellSectionOrOriginX = viewListArray[index + 2].floatValue; - CGFloat cellRowOrOriginY = viewListArray[index + 3].floatValue; - UIView *scrollViewCell = [self searchScrollViewCellWithScrollViewClassName:scrollViewClassName - cellClassName:cellClassName - cellSectionOrOriginX:cellSectionOrOriginX - cellRowOrOriginY:cellRowOrOriginY - fromSuperView:targetView]; - if (!scrollViewCell) { - return PrismInstructionParseResultFail; + + for (UIResponder *possibleResponder in allPossibleResponder) { + + lastScrollView = nil; + // 解析列表信息 + NSArray *viewListArray = [formatter instructionFragmentWithType:PrismInstructionFragmentTypeViewList]; + UIView *targetView = [possibleResponder isKindOfClass:[UIViewController class]] ? [(UIViewController*)possibleResponder view] : (UIView*)possibleResponder; + for (NSInteger index = 1; index < viewListArray.count; index = index + 4) { + if ([NSClassFromString(viewListArray[index]) isSubclassOfClass:[UIScrollView class]]) { + // 兼容模式直接省略对列表信息的解析。 + if (!self.isCompatibleMode) { + NSString *scrollViewClassName = viewListArray[index]; + NSString *cellClassName = viewListArray[index + 1]; + CGFloat cellSectionOrOriginX = viewListArray[index + 2].floatValue; + CGFloat cellRowOrOriginY = viewListArray[index + 3].floatValue; + UIView *scrollViewCell = [self searchScrollViewCellWithScrollViewClassName:scrollViewClassName + cellClassName:cellClassName + cellSectionOrOriginX:cellSectionOrOriginX + cellRowOrOriginY:cellRowOrOriginY + fromSuperView:targetView]; + if (!scrollViewCell) { + return PrismInstructionParseResultFail; + } + targetView = scrollViewCell; + lastScrollView = scrollViewCell.superview; } - targetView = scrollViewCell; - lastScrollView = scrollViewCell.superview; } } - } - - // 解析区位信息+功能信息 - NSArray *viewQuadrantArray = [formatter instructionFragmentWithType:PrismInstructionFragmentTypeViewQuadrant]; - NSArray *viewRepresentativeContentArray = [formatter instructionFragmentWithType:PrismInstructionFragmentTypeViewRepresentativeContent]; - NSArray *viewFunctionArray = [formatter instructionFragmentWithType:PrismInstructionFragmentTypeViewFunction]; + + // 解析区位信息+功能信息 + NSArray *viewQuadrantArray = [formatter instructionFragmentWithType:PrismInstructionFragmentTypeViewQuadrant]; + NSArray *viewRepresentativeContentArray = [formatter instructionFragmentWithType:PrismInstructionFragmentTypeViewRepresentativeContent]; + NSArray *viewFunctionArray = [formatter instructionFragmentWithType:PrismInstructionFragmentTypeViewFunction]; - NSString *areaInfo = [viewQuadrantArray prism_stringWithIndex:1]; - UILongPressGestureRecognizer *longPressGesture = nil; - // vr = 参考信息 - // 且 - // ( - // vf = WEEX标签信息 + selector + action - // 或 - // vf = selector + action - // ) - NSMutableString *representativeContent = [NSMutableString string]; - for (NSInteger index = 1; index < viewRepresentativeContentArray.count; index++) { - if (index > 1) { - [representativeContent appendString:kConnectorFlag]; + NSString *areaInfo = [viewQuadrantArray prism_stringWithIndex:1]; + // vr = 参考信息 + // 且 + // ( + // vf = WEEX标签信息 + selector + action + // 或 + // vf = selector + action + // ) + NSMutableString *representativeContent = [NSMutableString string]; + for (NSInteger index = 1; index < viewRepresentativeContentArray.count; index++) { + if (index > 1) { + [representativeContent appendString:kConnectorFlag]; + } + [representativeContent appendString:[viewRepresentativeContentArray prism_stringWithIndex:index]]; } - [representativeContent appendString:[viewRepresentativeContentArray prism_stringWithIndex:index]]; - } - - NSMutableString *functionName = [NSMutableString string]; - for (NSInteger index = 1; index < viewFunctionArray.count; index++) { - if (index > 1) { - [functionName appendString:kConnectorFlag]; + + NSMutableString *functionName = [NSMutableString string]; + for (NSInteger index = 1; index < viewFunctionArray.count; index++) { + if (index > 1) { + [functionName appendString:kConnectorFlag]; + } + [functionName appendString:[viewFunctionArray prism_stringWithIndex:index]]; } - [functionName appendString:[viewFunctionArray prism_stringWithIndex:index]]; - } - - longPressGesture = [self searchLongPressGestureFromSuperView:targetView withAreaInfo:areaInfo withRepresentativeContent:[representativeContent copy] withFunctionName:functionName]; - if (!longPressGesture) { - // 有列表的场景,考虑到列表中的元素index可能会变化,可以做一定的兼容。 - if (representativeContent.length && lastScrollView) { - for (UIView *subview in lastScrollView.subviews) { - UITapGestureRecognizer *resultGesture = [self searchLongPressGestureFromSuperView:subview withAreaInfo:areaInfo withRepresentativeContent:[representativeContent copy] withFunctionName:functionName]; - if (resultGesture) { - longPressGesture = resultGesture; - break; + + longPressGesture = [self searchLongPressGestureFromSuperView:targetView withAreaInfo:areaInfo withRepresentativeContent:[representativeContent copy] withFunctionName:functionName]; + if (!longPressGesture) { + // 有列表的场景,考虑到列表中的元素index可能会变化,可以做一定的兼容。 + if (representativeContent.length && lastScrollView) { + for (UIView *subview in lastScrollView.subviews) { + UITapGestureRecognizer *resultGesture = [self searchLongPressGestureFromSuperView:subview withAreaInfo:areaInfo withRepresentativeContent:[representativeContent copy] withFunctionName:functionName]; + if (resultGesture) { + longPressGesture = resultGesture; + break; + } } } } - } - if (!longPressGesture) { - // 兜底处理 - longPressGesture = [self searchLongPressGestureFromSuperView:targetView withAreaInfo:areaInfo withRepresentativeContent:nil withFunctionName:functionName]; + if (!longPressGesture) { + // 兜底处理 + longPressGesture = [self searchLongPressGestureFromSuperView:targetView withAreaInfo:areaInfo withRepresentativeContent:nil withFunctionName:functionName]; + } + + if (longPressGesture) { + break; + } } if (longPressGesture) { diff --git a/iOS/DiDiPrism/Src/Core/Instruction/Parser/PrismTapGestureInstructionParser.m b/iOS/DiDiPrism/Src/Core/Instruction/Parser/PrismTapGestureInstructionParser.m index 7a7e567..1561fac 100644 --- a/iOS/DiDiPrism/Src/Core/Instruction/Parser/PrismTapGestureInstructionParser.m +++ b/iOS/DiDiPrism/Src/Core/Instruction/Parser/PrismTapGestureInstructionParser.m @@ -31,90 +31,100 @@ - (PrismInstructionParseResult)parseWithFormatter:(PrismInstructionFormatter *)f return PrismInstructionParseResultFail; } + NSArray *allPossibleResponder = [NSArray arrayWithObject:responder]; for (NSInteger index = 2; index < viewPathArray.count; index++) { Class class = NSClassFromString(viewPathArray[index]); if (!class) { break; } - UIResponder *result = [self searchResponderWithClassName:viewPathArray[index] superResponder:responder]; - if (!result) { + NSArray *result = [self searchRespondersWithClassName:viewPathArray[index] superResponders:allPossibleResponder]; + if (!result.count) { break; } - responder = result; + allPossibleResponder = result; } - // 解析列表信息 - NSArray *viewListArray = [formatter instructionFragmentWithType:PrismInstructionFragmentTypeViewList]; + UITapGestureRecognizer *tapGesture = nil; UIView *lastScrollView = nil; - UIView *targetView = [responder isKindOfClass:[UIViewController class]] ? [(UIViewController*)responder view] : (UIView*)responder; - for (NSInteger index = 1; index < viewListArray.count; index = index + 4) { - if ([NSClassFromString(viewListArray[index]) isSubclassOfClass:[UIScrollView class]]) { - // 兼容模式直接省略对列表信息的解析。 - if (!self.isCompatibleMode) { - NSString *scrollViewClassName = viewListArray[index]; - NSString *cellClassName = viewListArray[index + 1]; - CGFloat cellSectionOrOriginX = viewListArray[index + 2].floatValue; - CGFloat cellRowOrOriginY = viewListArray[index + 3].floatValue; - UIView *scrollViewCell = [self searchScrollViewCellWithScrollViewClassName:scrollViewClassName - cellClassName:cellClassName - cellSectionOrOriginX:cellSectionOrOriginX - cellRowOrOriginY:cellRowOrOriginY - fromSuperView:targetView]; - if (!scrollViewCell) { - return PrismInstructionParseResultFail; + + for (UIResponder *possibleResponder in allPossibleResponder) { + + lastScrollView = nil; + // 解析列表信息 + NSArray *viewListArray = [formatter instructionFragmentWithType:PrismInstructionFragmentTypeViewList]; + UIView *targetView = [possibleResponder isKindOfClass:[UIViewController class]] ? [(UIViewController*)possibleResponder view] : (UIView*)possibleResponder; + for (NSInteger index = 1; index < viewListArray.count; index = index + 4) { + if ([NSClassFromString(viewListArray[index]) isSubclassOfClass:[UIScrollView class]]) { + // 兼容模式直接省略对列表信息的解析。 + if (!self.isCompatibleMode) { + NSString *scrollViewClassName = viewListArray[index]; + NSString *cellClassName = viewListArray[index + 1]; + CGFloat cellSectionOrOriginX = viewListArray[index + 2].floatValue; + CGFloat cellRowOrOriginY = viewListArray[index + 3].floatValue; + UIView *scrollViewCell = [self searchScrollViewCellWithScrollViewClassName:scrollViewClassName + cellClassName:cellClassName + cellSectionOrOriginX:cellSectionOrOriginX + cellRowOrOriginY:cellRowOrOriginY + fromSuperView:targetView]; + if (!scrollViewCell) { + return PrismInstructionParseResultFail; + } + targetView = scrollViewCell; + lastScrollView = scrollViewCell.superview; } - targetView = scrollViewCell; - lastScrollView = scrollViewCell.superview; } } - } - - // 解析区位信息+功能信息 - NSArray *viewQuadrantArray = [formatter instructionFragmentWithType:PrismInstructionFragmentTypeViewQuadrant]; - NSArray *viewRepresentativeContentArray = [formatter instructionFragmentWithType:PrismInstructionFragmentTypeViewRepresentativeContent]; - NSArray *viewFunctionArray = [formatter instructionFragmentWithType:PrismInstructionFragmentTypeViewFunction]; + + // 解析区位信息+功能信息 + NSArray *viewQuadrantArray = [formatter instructionFragmentWithType:PrismInstructionFragmentTypeViewQuadrant]; + NSArray *viewRepresentativeContentArray = [formatter instructionFragmentWithType:PrismInstructionFragmentTypeViewRepresentativeContent]; + NSArray *viewFunctionArray = [formatter instructionFragmentWithType:PrismInstructionFragmentTypeViewFunction]; - NSString *areaInfo = [viewQuadrantArray prism_stringWithIndex:1]; - UITapGestureRecognizer *tapGesture = nil; - // vr = 参考信息 - // 且 - // ( - // vf = WEEX标签信息 + selector + action - // 或 - // vf = selector + action - // ) - NSMutableString *representativeContent = [NSMutableString string]; - for (NSInteger index = 1; index < viewRepresentativeContentArray.count; index++) { - if (index > 1) { - [representativeContent appendString:kConnectorFlag]; + NSString *areaInfo = [viewQuadrantArray prism_stringWithIndex:1]; + // vr = 参考信息 + // 且 + // ( + // vf = WEEX标签信息 + selector + action + // 或 + // vf = selector + action + // ) + NSMutableString *representativeContent = [NSMutableString string]; + for (NSInteger index = 1; index < viewRepresentativeContentArray.count; index++) { + if (index > 1) { + [representativeContent appendString:kConnectorFlag]; + } + [representativeContent appendString:[viewRepresentativeContentArray prism_stringWithIndex:index]]; } - [representativeContent appendString:[viewRepresentativeContentArray prism_stringWithIndex:index]]; - } - - NSMutableString *functionName = [NSMutableString string]; - for (NSInteger index = 1; index < viewFunctionArray.count; index++) { - if (index > 1) { - [functionName appendString:kConnectorFlag]; + + NSMutableString *functionName = [NSMutableString string]; + for (NSInteger index = 1; index < viewFunctionArray.count; index++) { + if (index > 1) { + [functionName appendString:kConnectorFlag]; + } + [functionName appendString:[viewFunctionArray prism_stringWithIndex:index]]; } - [functionName appendString:[viewFunctionArray prism_stringWithIndex:index]]; - } - - tapGesture = [self searchTapGestureFromSuperView:targetView withAreaInfo:areaInfo withRepresentativeContent:[representativeContent copy] withFunctionName:functionName]; - if (!tapGesture) { - // 有列表的场景,考虑到列表中的元素index可能会变化,可以做一定的兼容。 - if (representativeContent.length && lastScrollView) { - for (UIView *subview in lastScrollView.subviews) { - UITapGestureRecognizer *resultGesture = [self searchTapGestureFromSuperView:subview withAreaInfo:areaInfo withRepresentativeContent:[representativeContent copy] withFunctionName:functionName]; - if (resultGesture) { - tapGesture = resultGesture; - break; + + tapGesture = [self searchTapGestureFromSuperView:targetView withAreaInfo:areaInfo withRepresentativeContent:[representativeContent copy] withFunctionName:functionName]; + if (!tapGesture) { + // 有列表的场景,考虑到列表中的元素index可能会变化,可以做一定的兼容。 + if (representativeContent.length && lastScrollView) { + for (UIView *subview in lastScrollView.subviews) { + UITapGestureRecognizer *resultGesture = [self searchTapGestureFromSuperView:subview withAreaInfo:areaInfo withRepresentativeContent:[representativeContent copy] withFunctionName:functionName]; + if (resultGesture) { + tapGesture = resultGesture; + break; + } } } } - } - if (!tapGesture) { - // 兜底处理 - tapGesture = [self searchTapGestureFromSuperView:targetView withAreaInfo:areaInfo withRepresentativeContent:nil withFunctionName:functionName]; + if (!tapGesture) { + // 兜底处理 + tapGesture = [self searchTapGestureFromSuperView:targetView withAreaInfo:areaInfo withRepresentativeContent:nil withFunctionName:functionName]; + } + + if (tapGesture) { + break; + } } if (tapGesture) {