From 64c327ae684690ae9cabaff412467b54095839ea Mon Sep 17 00:00:00 2001 From: Valentin Shergin Date: Sun, 19 Mar 2017 21:48:22 -0700 Subject: [PATCH] Fixed issue where setting `zero scale` transfrom matrix to UIView brokes `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 --- React/Views/RCTConvert+Transform.m | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/React/Views/RCTConvert+Transform.m b/React/Views/RCTConvert+Transform.m index 116391056..32a1abfb5 100644 --- a/React/Views/RCTConvert+Transform.m +++ b/React/Views/RCTConvert+Transform.m @@ -90,15 +90,15 @@ static const NSUInteger kMatrixArrayLength = 4 * 4; 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"]) {