react-native/React/Views/UIView+React.m
Nick Lockwood b0b9a56ef8 Fixed ActivityIndicatorIOS layout
Summary: public

This has been broken for a while. The styles in the JS were being set on the container instead of the activity view itself.

Also, due to the way frames were set directly on layer properties instead of the view, resizing didn't work properly because the UIImageView inside the UIActivityView was not being realligned when the bounds changed. This also caused problems for other controls such as maps, where it was fixed with a method override, but the simpler solution is just to set the view center and bounds directly.

Before: {F23631143}
After: {F23631144}

Reviewed By: javache, tadeuzagallo

Differential Revision: D2575156

fb-gh-sync-id: e82e56d36648e7c924df77da1750e03037b5d5be
2015-10-23 09:13:24 -07:00

129 lines
3.2 KiB
Objective-C

/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#import "UIView+React.h"
#import <objc/runtime.h>
#import "RCTAssert.h"
#import "RCTLog.h"
@implementation UIView (React)
- (NSNumber *)reactTag
{
return objc_getAssociatedObject(self, _cmd);
}
- (void)setReactTag:(NSNumber *)reactTag
{
objc_setAssociatedObject(self, @selector(reactTag), reactTag, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (BOOL)isReactRootView
{
return RCTIsReactRootView(self.reactTag);
}
- (NSNumber *)reactTagAtPoint:(CGPoint)point
{
UIView *view = [self hitTest:point withEvent:nil];
while (view && !view.reactTag) {
view = view.superview;
}
return view.reactTag;
}
- (void)insertReactSubview:(UIView *)subview atIndex:(NSInteger)atIndex
{
[self insertSubview:subview atIndex:atIndex];
}
- (void)removeReactSubview:(UIView *)subview
{
RCTAssert(subview.superview == self, @"%@ is a not a subview of %@", subview, self);
[subview removeFromSuperview];
}
- (NSArray *)reactSubviews
{
return self.subviews;
}
- (UIView *)reactSuperview
{
return self.superview;
}
- (void)reactSetFrame:(CGRect)frame
{
// These frames are in terms of anchorPoint = topLeft, but internally the
// views are anchorPoint = center for easier scale and rotation animations.
// Convert the frame so it works with anchorPoint = center.
CGPoint position = {CGRectGetMidX(frame), CGRectGetMidY(frame)};
CGRect bounds = {CGPointZero, frame.size};
// Avoid crashes due to nan coords
if (isnan(position.x) || isnan(position.y) ||
isnan(bounds.origin.x) || isnan(bounds.origin.y) ||
isnan(bounds.size.width) || isnan(bounds.size.height)) {
RCTLogError(@"Invalid layout for (%@)%@. position: %@. bounds: %@",
self.reactTag, self, NSStringFromCGPoint(position), NSStringFromCGRect(bounds));
return;
}
self.center = position;
self.bounds = bounds;
}
- (void)reactSetInheritedBackgroundColor:(UIColor *)inheritedBackgroundColor
{
self.backgroundColor = inheritedBackgroundColor;
}
- (UIViewController *)reactViewController
{
id responder = [self nextResponder];
while (responder) {
if ([responder isKindOfClass:[UIViewController class]]) {
return responder;
}
responder = [responder nextResponder];
}
return nil;
}
- (void)reactAddControllerToClosestParent:(UIViewController *)controller
{
if (!controller.parentViewController) {
UIView *parentView = (UIView *)self.reactSuperview;
while (parentView) {
if (parentView.reactViewController) {
[parentView.reactViewController addChildViewController:controller];
[controller didMoveToParentViewController:parentView.reactViewController];
break;
}
parentView = (UIView *)parentView.reactSuperview;
}
return;
}
}
/**
* Responder overrides - to be deprecated.
*/
- (void)reactWillMakeFirstResponder {};
- (void)reactDidMakeFirstResponder {};
- (BOOL)reactRespondsToTouch:(__unused UITouch *)touch
{
return YES;
}
@end