diff --git a/renderer/native/ios/renderer/HippyUIManager.h b/renderer/native/ios/renderer/HippyUIManager.h index d10ce61ca39..63d88dd132e 100644 --- a/renderer/native/ios/renderer/HippyUIManager.h +++ b/renderer/native/ios/renderer/HippyUIManager.h @@ -33,6 +33,7 @@ @class HippyComponentMap; @protocol HippyImageProviderProtocol; +NS_ASSUME_NONNULL_BEGIN /** * Posted whenever a new root view is registered with HippyUIManager. The userInfo property @@ -156,3 +157,5 @@ HIPPY_EXTERN NSString *const HippyUIManagerDidEndBatchNotification; @property (nonatomic, strong, readonly) id customTouchHandler; @end + +NS_ASSUME_NONNULL_END diff --git a/renderer/native/ios/renderer/HippyUIManager.mm b/renderer/native/ios/renderer/HippyUIManager.mm index 8643e9f0568..2419d3928db 100644 --- a/renderer/native/ios/renderer/HippyUIManager.mm +++ b/renderer/native/ios/renderer/HippyUIManager.mm @@ -162,6 +162,18 @@ static void NativeRenderTraverseViewNodes(id view, void (^block) } } + +@interface UIView (HippyUIManagerPrivate) + +/// Bind UIView with HippyUIManager +/// This is a convenient method for UIView to get HippyUIManager instance. +/// - Parameter uiManager: HippyUIManager instance +- (void)setUiManager:(HippyUIManager *)uiManager; + +@end + +#pragma mark - + #define AssertMainQueue() NSAssert(HippyIsMainQueue(), @"This function must be called on the main thread") NSString *const HippyUIManagerDidRegisterRootViewNotification = @"HippyUIManagerDidRegisterRootViewNotification"; @@ -318,8 +330,8 @@ - (void)registerRootView:(UIView *)rootView asRootNode:(std::weak_ptr) // Register view [_viewRegistry addRootComponent:rootView rootNode:rootNode forTag:hippyTag]; - - [rootView addObserver:self forKeyPath:@"frame" + rootView.uiManager = self; + [rootView addObserver:self forKeyPath:@"frame" options:(NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew) context:NULL]; CGRect frame = rootView.frame; @@ -516,6 +528,7 @@ - (UIView *)createViewFromShadowView:(HippyShadowView *)shadowView { view.viewName = viewName; view.rootTag = rootTag; view.hippyShadowView = shadowView; + view.uiManager = self; [componentData setProps:props forView:view]; // Must be done before bgColor to prevent wrong default } } @@ -1523,7 +1536,5 @@ - (void)setCustomTouchHandler:(id)customTouchHa objc_setAssociatedObject(self, @selector(customTouchHandler), customTouchHandler, OBJC_ASSOCIATION_RETAIN); } - @end - diff --git a/renderer/native/ios/renderer/component/view/UIView+Render.h b/renderer/native/ios/renderer/component/view/UIView+Render.h new file mode 100644 index 00000000000..d7d508ba879 --- /dev/null +++ b/renderer/native/ios/renderer/component/view/UIView+Render.h @@ -0,0 +1,37 @@ +/*! + * iOS SDK + * + * Tencent is pleased to support the open source community by making + * Hippy available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +NS_ASSUME_NONNULL_BEGIN + +@class HippyUIManager; +/// UIView's UIManager category +@interface UIView (HippyUIManager) + +/// Convenient method to get HippyUIManager instance, +/// UIView's uiManager property is set when created. +- (nullable HippyUIManager *)uiManager; + +@end + +NS_ASSUME_NONNULL_END diff --git a/renderer/native/ios/renderer/component/view/UIView+Render.m b/renderer/native/ios/renderer/component/view/UIView+Render.m new file mode 100644 index 00000000000..d751e6cd7f6 --- /dev/null +++ b/renderer/native/ios/renderer/component/view/UIView+Render.m @@ -0,0 +1,38 @@ +/*! + * iOS SDK + * + * Tencent is pleased to support the open source community by making + * Hippy available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "UIView+Render.h" +#import + +@implementation UIView (HippyUIManager) + +- (HippyUIManager *)uiManager { + NSValue *weakValue = objc_getAssociatedObject(self, @selector(uiManager)); + return [weakValue nonretainedObjectValue]; +} + +- (void)setUiManager:(HippyUIManager *)uiManager { + NSValue *weakValue = [NSValue valueWithNonretainedObject:uiManager]; + objc_setAssociatedObject(self, @selector(uiManager), weakValue, OBJC_ASSOCIATION_RETAIN_NONATOMIC); +} + +@end diff --git a/tests/ios/HippyUIViewCategoryTest.m b/tests/ios/HippyUIViewCategoryTest.m index 22705653f1c..d6fb521c9b7 100644 --- a/tests/ios/HippyUIViewCategoryTest.m +++ b/tests/ios/HippyUIViewCategoryTest.m @@ -21,7 +21,18 @@ */ #import -#import "UIView+Hippy.h" +#import +#import +#import + +@interface UIView (HippyUIManagerUnitTest) + +/// Bind UIView with HippyUIManager +/// This is a convenient method for UIView to get HippyUIManager instance. +/// - Parameter uiManager: HippyUIManager instance +- (void)setUiManager:(HippyUIManager *)uiManager; + +@end @interface HippyUIViewCategoryTest : XCTestCase @@ -47,8 +58,15 @@ - (void)testGetHippyRootView { XCTAssert([testView hippyRootView] == testSuperView); testView.hippyTag = @(11); XCTAssert([testView hippyRootView] == nil); +} + +- (void)testGetHippyUIManager { + UIView *testView = [UIView new]; + XCTAssertNil([testView uiManager]); - + HippyUIManager *uiManager = [[HippyUIManager alloc] init]; + XCTAssertNoThrow(testView.uiManager = uiManager); + XCTAssertTrue(testView.uiManager == uiManager); }