如何操作 React Native - Native UI 组件的属性?
How to manipulate properties of React Native - Native UI Component?
我正在开发 React Native 应用程序。
该应用包含基于网络的视图和本机 ui 视图(组件)。
虽然基于 Web 的视图和本机 ui 视图的渲染都有效,但我无法操作本机 ui 视图的属性,例如背景颜色.
不得不说我的项目结构并没有那么简单,因为我做了很多桥接,从React到Objective-C,从Objective-C到Swift等等绕一圈。
简单介绍一下我的项目结构:
MyUIView.h
#import <UIKit/UIKit.h>
// Define which methods and properties have to be implemented in MyUIView
@interface MyUIView : UIView
@end
MyUIView.m
#import "MyUIView.h"
// Represents the native MyUIView
@implementation MyUIView
-(instancetype) init {
self = [super init];
if (self) {
[self setUp];
}
return self;
}
-(void) setUp {
UIView * myUIView = [[UIView alloc] initWithFrame:CGRectMake(-50, -250, 100, 100)];
[myUIView setBackgroundColor:[UIColor grayColor]];
[self addSubview:myAudioRecorderUIView];
}
@end
MyUIManager.h
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#import <React/RCTViewManager.h>
@interface MyUIManager : RCTViewManager
@property (nonatomic, strong) UIView *myUIView;
- (void) changeBackgroundColor: (UIColor*)color;
@end
MyUIManager.m
#import "MyUIManager.h"
#import "reactnative-Swift.h"
#import "MyUIView.h"
#import <UIKit/UIKit.h>
@import UIKit;
// Controls the rendering of native view in the React part of our application
@implementation MyUIManager
MyUIManager *myUIManager;
MyUIView *myUIView;
+ (void) initialize {
myUIManager = [MyUIManager allocWithZone: nil];
myUIView = [[MyUIView alloc] init];
}
+ (id) allocWithZone:(NSZone *)zone {
static MyUIManager *sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [super allocWithZone:zone];
});
return sharedInstance;
}
- (void) changeBackgroundColor: (UIColor*)color {
dispatch_sync(dispatch_get_main_queue(), ^{
self.myUIView.backgroundColor = UIColor.redColor;
});
}
RCT_EXPORT_MODULE()
- (UIView *) view
{
return myUIView;
}
@end
MyViewController.swift
import Foundation
import UIKit
@objc open class MyViewController : UIViewController {
let myUIManager: MyUIManager = MyUIManager();
@objc func changeColor() {
myUIManager.changeBackgroundColor(UIColor.red)
}
}
我期望的是,从我的 Swift class 调用 changeColor 方法会更改我的原生 ui 视图的颜色,因为调用 myUIManager 的 changeBackgroundColor 的颜色然后设置。但是颜色确实发生了变化。它保持灰色,就像在 MyUIView.m.
的 setUp 方法中定义的一样
有什么建议吗?
必须做一些调整才能使其正常工作,最重要的是将应该操作的视图包装到另一个视图中,然后 return 父视图而不是子视图:
MyUIView.m
#import "MyUIView.h"
// Represents the native MyUIView
@implementation MyUIView
-(instancetype) init {
self = [super init];
if (self) {
[self setUp];
}
return self;
}
- (instancetype)initWithFrame:(CGRect)frame {
NSLog(@"init with frame: %@", NSStringFromCGRect(frame));
self = [super initWithFrame:frame];
if ( self ) {
[self setUp];
}
return self;
}
- (void)setUp {
self.backgroundColor = [UIColor grayColor];
}
- (void)layoutSubviews {
NSLog(@"layout subviews");
}
@end
MyUIManager.h
#import <UIKit/UIKit.h>
#import <React/RCTViewManager.h>
@interface MyUIManager : RCTViewManager
@property (nonatomic) UIView *myParentUIView;
@property (nonatomic) UIView *myUIView;
- (void) changeBackgroundColor: (UIColor*)color;
@end
MyUIManager.m
#import "MyUIManager.h"
#import "reactnative-Swift.h"
#import "MyUIManager.h"
#import "MyUIView.h"
#import <UIKit/UIKit.h>
// Controls the rendering of native view in the React part of our application
@implementation MyUIManager
MyUIView *myParentUIView;
MyUIView *myUIView;
// Instantiate MyUIView (parent and child)
+ (void) initialize {
myParentUIView = [[MyUIView alloc] initWithFrame:CGRectMake(0, 0, 0, 0)];
myUIView = [[MyUIView alloc] initWithFrame:CGRectMake(-50, -250, 100, 100)];
[myParentUIView addSubview:myUIView];
}
// Change background color of view
- (void) changeBackgroundColor: (UIColor*)color {
dispatch_sync(dispatch_get_main_queue(), ^{
myParentUIView.subviews.firstObject.backgroundColor = color;
});
}
RCT_EXPORT_MODULE()
- (UIView *)view {
return myParentUIView;
}
@end
我正在开发 React Native 应用程序。
该应用包含基于网络的视图和本机 ui 视图(组件)。
虽然基于 Web 的视图和本机 ui 视图的渲染都有效,但我无法操作本机 ui 视图的属性,例如背景颜色.
不得不说我的项目结构并没有那么简单,因为我做了很多桥接,从React到Objective-C,从Objective-C到Swift等等绕一圈。
简单介绍一下我的项目结构:
MyUIView.h
#import <UIKit/UIKit.h>
// Define which methods and properties have to be implemented in MyUIView
@interface MyUIView : UIView
@end
MyUIView.m
#import "MyUIView.h"
// Represents the native MyUIView
@implementation MyUIView
-(instancetype) init {
self = [super init];
if (self) {
[self setUp];
}
return self;
}
-(void) setUp {
UIView * myUIView = [[UIView alloc] initWithFrame:CGRectMake(-50, -250, 100, 100)];
[myUIView setBackgroundColor:[UIColor grayColor]];
[self addSubview:myAudioRecorderUIView];
}
@end
MyUIManager.h
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#import <React/RCTViewManager.h>
@interface MyUIManager : RCTViewManager
@property (nonatomic, strong) UIView *myUIView;
- (void) changeBackgroundColor: (UIColor*)color;
@end
MyUIManager.m
#import "MyUIManager.h"
#import "reactnative-Swift.h"
#import "MyUIView.h"
#import <UIKit/UIKit.h>
@import UIKit;
// Controls the rendering of native view in the React part of our application
@implementation MyUIManager
MyUIManager *myUIManager;
MyUIView *myUIView;
+ (void) initialize {
myUIManager = [MyUIManager allocWithZone: nil];
myUIView = [[MyUIView alloc] init];
}
+ (id) allocWithZone:(NSZone *)zone {
static MyUIManager *sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [super allocWithZone:zone];
});
return sharedInstance;
}
- (void) changeBackgroundColor: (UIColor*)color {
dispatch_sync(dispatch_get_main_queue(), ^{
self.myUIView.backgroundColor = UIColor.redColor;
});
}
RCT_EXPORT_MODULE()
- (UIView *) view
{
return myUIView;
}
@end
MyViewController.swift
import Foundation
import UIKit
@objc open class MyViewController : UIViewController {
let myUIManager: MyUIManager = MyUIManager();
@objc func changeColor() {
myUIManager.changeBackgroundColor(UIColor.red)
}
}
我期望的是,从我的 Swift class 调用 changeColor 方法会更改我的原生 ui 视图的颜色,因为调用 myUIManager 的 changeBackgroundColor 的颜色然后设置。但是颜色确实发生了变化。它保持灰色,就像在 MyUIView.m.
的 setUp 方法中定义的一样有什么建议吗?
必须做一些调整才能使其正常工作,最重要的是将应该操作的视图包装到另一个视图中,然后 return 父视图而不是子视图:
MyUIView.m
#import "MyUIView.h"
// Represents the native MyUIView
@implementation MyUIView
-(instancetype) init {
self = [super init];
if (self) {
[self setUp];
}
return self;
}
- (instancetype)initWithFrame:(CGRect)frame {
NSLog(@"init with frame: %@", NSStringFromCGRect(frame));
self = [super initWithFrame:frame];
if ( self ) {
[self setUp];
}
return self;
}
- (void)setUp {
self.backgroundColor = [UIColor grayColor];
}
- (void)layoutSubviews {
NSLog(@"layout subviews");
}
@end
MyUIManager.h
#import <UIKit/UIKit.h>
#import <React/RCTViewManager.h>
@interface MyUIManager : RCTViewManager
@property (nonatomic) UIView *myParentUIView;
@property (nonatomic) UIView *myUIView;
- (void) changeBackgroundColor: (UIColor*)color;
@end
MyUIManager.m
#import "MyUIManager.h"
#import "reactnative-Swift.h"
#import "MyUIManager.h"
#import "MyUIView.h"
#import <UIKit/UIKit.h>
// Controls the rendering of native view in the React part of our application
@implementation MyUIManager
MyUIView *myParentUIView;
MyUIView *myUIView;
// Instantiate MyUIView (parent and child)
+ (void) initialize {
myParentUIView = [[MyUIView alloc] initWithFrame:CGRectMake(0, 0, 0, 0)];
myUIView = [[MyUIView alloc] initWithFrame:CGRectMake(-50, -250, 100, 100)];
[myParentUIView addSubview:myUIView];
}
// Change background color of view
- (void) changeBackgroundColor: (UIColor*)color {
dispatch_sync(dispatch_get_main_queue(), ^{
myParentUIView.subviews.firstObject.backgroundColor = color;
});
}
RCT_EXPORT_MODULE()
- (UIView *)view {
return myParentUIView;
}
@end