Permalink
Browse files

Fixed issue where setting `zero scale` transfrom matrix to UIView bro…

…kes `hitTest` mechanism

Summary:
The Math Strikes Back

Several related things:
 * When we specify `scale: 0;` style for some view it ends up with calling `CATransform3DScale` with zero scale parameter.
 * In this case `CATransform3DScale` returns transform matrix full of zeros. It actually depends on representation and matrix-type (2d or 3d) but in UIView debugger it appears as [0, 0, 0, 0, ...]. And probably it is correct result.
 * By default, for hit-testing, UIKit uses specially optimized logic based on GPU/CALayer infrastructure under the hood. And the transform matrix full of zeros breaks this algorithm. I guess, it happens because zero-matrix doesn't quite make sense.

So, `scale: 0;` is a weird edge case, and in this diff, we are trying to illuminate it by replacing with epsilon value.

Related SO issues:
http://stackoverflow.com/questions/25964224/cgaffinetransformscale-not-working-with-zero-scale
http://stackoverflow.com/questions/7937369/animate-uiview-scale-to-zero

Reviewed By: blairvanderhoof

Differential Revision: D4734475

fbshipit-source-id: 7241cdffa86c05a6552860a25789e2281588ba23
  • Loading branch information...
shergin authored and facebook-github-bot committed Mar 20, 2017
1 parent 23c2a6c commit 64c327ae684690ae9cabaff412467b54095839ea
Showing with 3 additions and 3 deletions.
  1. +3 −3 React/Views/RCTConvert+Transform.m
@@ -90,15 +90,15 @@ + (CATransform3D)CATransform3D:(id)json
transform = CATransform3DRotate(transform, rotate, 0, 0, 1);
} else if ([property isEqualToString:@"scale"]) {
CGFloat scale = [value floatValue];
CGFloat scale = MAX([value floatValue], FLT_EPSILON);
transform = CATransform3DScale(transform, scale, scale, 1);
} else if ([property isEqualToString:@"scaleX"]) {
CGFloat scale = [value floatValue];
CGFloat scale = MAX([value floatValue], FLT_EPSILON);
transform = CATransform3DScale(transform, scale, 1, 1);
} else if ([property isEqualToString:@"scaleY"]) {
CGFloat scale = [value floatValue];
CGFloat scale = MAX([value floatValue], FLT_EPSILON);
transform = CATransform3DScale(transform, 1, scale, 1);
} else if ([property isEqualToString:@"translate"]) {

0 comments on commit 64c327a

Please sign in to comment.