Well, I just wasted 2 days on that.
Simplest example : I have 2 UIView's who's being animated from the top of the screen to the bottom. After a lot of researching i found out that the only way you can "touch/trigger" touch event when UIView is being animated , is via HitTest using presentationLayer property.
Inside touchBegan method
x as! UIView
if x.layer.presentationLayer()!.hitTest(touchlocation) != nil {
x.alpha = 0
//Layer touched
}
Situation :
During the animation,the first UIView overlaps\upon the second UIView. At that point i'm "touching" the topest UIView.
Problem : HitTest return the lowest\deepest layer , So the bottom UIView layer will be the recognized one.
Question : How do i get the first/frontmost UIView layer instead of the deepest?
Based on our chat we found out what was actually happening.
Basically, to detect the touches, you were iterating over all the subviews in the view controller and performing a hitTest
on each of their presentationLayer
s to detect the touch during an animation.
There were a few problems we discovered:
hitTest
was returning a sublayer of the current subview's (x
) layer and was unknowingly being conflated with another view (y
).for
loop used to iterate over the subviews wasn't utilizing the break
statement once it found its target, resulting in the confusion in 1
above.addSubview
and subviews
are structured.Solution
Ultimately the solution came from fixing these issues by:
for x in self.view.subviews.reverse()
hitTest
was a sublayer of
the current view that was being tested (pseudo-code) if layerThatWasHit.superlayer == x.presentationLayer()
break
statement inside of the if
where the view hit was
detected to terminate the for
loop and prevent multiple executions
of the code that results in a tap on one of the animated views.