-
Notifications
You must be signed in to change notification settings - Fork 919
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for swiping from the specified edge of the screen #1286
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Couple of discussion points on the approach, but what you have here also seems reasonable. We appreciate the contribution and adding test coverage of the scenario.
Sources/KIF/Classes/KIFUITestActor.m
Outdated
@@ -389,6 +378,49 @@ - (void)tapScreenAtPoint:(CGPoint)screenPoint | |||
}]; | |||
} | |||
|
|||
- (void)swipeFromEdge:(UIRectEdge)edge atY:(CGFloat)y |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I'd make this a % or the screen height to make it the API work more easily with different device screen sizes, like the dragFromPoint API.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you have a use case where you care about the Y coordinate used for the edge swipe? If not, I think we should start by omitting the atY:
parameter and default to using 50% of the screen height.
@@ -692,6 +701,7 @@ - (void)dragPointsAlongPaths:(NSArray<NSArray<NSValue *> *> *)arrayOfPaths { | |||
point = [self convertPoint:point fromView:self.window]; | |||
UITouch *touch = [[UITouch alloc] initAtPoint:point inView:self]; | |||
[touch setPhaseAndUpdateTimestamp:UITouchPhaseBegan]; | |||
[touch setIsFromEdge:isFromEdge]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if we should alternatively come up with a heuristic here for what constitutes an edge swipe and do it implicitly. Being explicit seems reasonable as well though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think with this we can make an API specifically for swiping at an edge, similarly to like tapping on a button or status bar instead of using x,y coordinatotes. As well as implicitly doing it from the edge if we can detect it being around where it should be. I think that'd be in line with other APIs of KIf
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought about doing it implicitly like
if (startPoint.x < 1 || startPoint.x > screen.size.width - 1) {
[touch setIsFromEdge:isFromEdge];
}
But this could be a breaking change for users who utilize the dragFromPoint
method without intending to trigger a screen edge pan gesture.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have tried to implement an alternative way based on the suggestions, which one do you prefer?
- (void)setIsFromEdge:(BOOL)isFromEdge | ||
{ | ||
NSInteger edgeType = isFromEdge ? 4 : 0; | ||
[self _setEdgeType:edgeType]; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What would happen if we directly called _UITouchSetBasicTouchPropertiesFromEvent
? Does Apple already have the appropriate heuristics to set this properly?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Apple derives the value of the property from the HIDEvent. We would need to synthesize a different HIDEvent for edge pan before calling _UITouchSetBasicTouchPropertiesFromEvent
. This introduces additional complexity and I lack the necessary knowledge to implement it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if we could replace these magic numbers with Apple enums.
@@ -630,10 +630,15 @@ - (void)dragFromPoint:(CGPoint)startPoint toPoint:(CGPoint)endPoint steps:(NSUIn | |||
} | |||
|
|||
- (void)dragFromPoint:(CGPoint)startPoint displacement:(KIFDisplacement)displacement steps:(NSUInteger)stepCount; | |||
{ | |||
[self dragFromPoint:startPoint displacement:displacement steps:stepCount isFromEdge:NO]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is kind of a breaking change, in that it would require code changes in existing tests if they had working edge gestures. As you'd called out in the issue, this has been broken since iOS 11, so seems reasonable IMO.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for taking so long to get back here, and thanks for making the revisions! One other thing that we should do before landing this is add an equivalent API to KIFUIViewTestActor
. That is the more flexible replacement of the KIFUITestActor
API, though there is still a lot of documentation indicating to use the older API.
Sources/KIF/Classes/KIFUITestActor.m
Outdated
@@ -389,6 +378,49 @@ - (void)tapScreenAtPoint:(CGPoint)screenPoint | |||
}]; | |||
} | |||
|
|||
- (void)swipeFromEdge:(UIRectEdge)edge atY:(CGFloat)y |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you have a use case where you care about the Y coordinate used for the edge swipe? If not, I think we should start by omitting the atY:
parameter and default to using 50% of the screen height.
CGFloat height = self.bounds.size.height; | ||
CGFloat edgeInset = 0.5; | ||
NSDictionary *edgeToPoint = @{ | ||
@(UIRectEdgeTop): @(CGPointMake(width / 2, 0)), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we also use edgeInset
here for the top and height - edgeInset
for the bottom?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'v made some revisions as suggested, please review again.
1. Omit the atY: parameter of swipeFromEdge 2. Add an equivalent API to KIFUIViewTestActor and add tests 3. dragFromEdge now uses edgeInset for the top and height - edgeInset for the bottom
Thanks again for the iterations here and the contribution! I'll get this merged once CI reports green. |
The tests appear to be extremely flaky right now in |
Merged as they all went green |
As discussed in issue #1281, I tried to address the problem by adding a new method to the tester. This method simulates a screen edge pan gesture by manually setting the
_edgeType
property. I wonder if there's any better solution, any feedback is greatly appreciated.