Как манипулировать свойствами React Native - Native UI Component?

Я работаю над приложением React Native.

Приложение состоит как из веб-представлений, так и из представлений пользовательского интерфейса (компонентов).

Хотя рендеринг веб-представлений, а также собственных представлений пользовательского интерфейса работает, я не могу манипулировать свойствами собственного представления пользовательского интерфейса, такими как, например, цвет фона.

Я должен сказать, что структура моего проекта не так проста, потому что я провел много мостов, от 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)
  }
}

Я ожидаю, что вызов метода changeColor из моего класса Swift изменяет цвет моего собственного представления пользовательского интерфейса, так как changeBackgroundColor из myUIManager вызывается там, где затем устанавливается цвет. Однако цвет меняется. Он остается серым, как это было определено в методе setUp MyUIView.m.

Какие-либо предложения?

1 ответ

Решение

Нужно сделать некоторые изменения, чтобы заставить его работать, самое главное - обернуть представление, которым нужно манипулировать, в другое представление и вернуть потом родительское представление вместо дочернего:

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
Другие вопросы по тегам