4

我是 iOS 布局的新手,我正在尝试以编程方式将自定义视图(实际上是一个RCTRootView扩展的 React Native UIView,如果相关的话)居中,它具有固有大小的动态内容(在 javascript 领域中定义)。

我已经看到了覆盖解决方案intrinsicallySizedContent,但这似乎只与自动布局相关,RN 不使用它。我能够测量RCTRootView's 内容大小的唯一方法是将其添加到视图中,并等待几遍layoutSubViews直到它frame具有大小。这导致我做出以下努力:

尝试:在 layoutSubViews 中包装并设置包装器大小

我将RCTRootView另一个包装起来UIView并尝试覆盖layoutSubViews,一旦我有了反应原生内容的大小,就设置我的包装框架的大小。

我的包装器是这样创建并添加到导航栏中的UIViewController

  RCTBridge *bridge = ((RCTRootView*)self.view).bridge;
  RCTRootView *reactView = [[RCTRootView alloc] initWithBridge:bridge moduleName:navBarCustomView initialProperties:initialProps];
  RCCCustomTitleView *titleView = [[TitleWrapperView alloc] initWithFrame:self.navigationController.navigationBar.bounds subView:reactView];
  self.navigationItem.titleView = titleView;
  self.navigationItem.titleView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;

包装器是这样实现的:

#import "TitleWrapperView.h"
#import <React/RCTRootView.h>

@interface TitleWrapperView ()
@property (nonatomic, strong) RCTRootView *subView;
@end

@implementation TitleWrapperView // Extends UIView

-(instancetype)initWithFrame:(CGRect)frame subView:(RCTRootView*)subView {
    self = [super initWithFrame:frame];
    
    if (self) {
        self.subView = subView;
        self.subView.sizeFlexibility = RCTRootViewSizeFlexibilityWidthAndHeight;
        self.clipsToBounds = true;

        // Prevent the wrapper from being so large initially as to squash the '< Back' button down to '<'
        self.frame = CGRectZero;

        [self addSubview:subView];
    }
    
    return self;
}

-(void)layoutSubviews {
    [super layoutSubviews];
    CGRect contentViewFrame = self.subView.contentView.frame;
    if (contentViewFrame.size.width > 0) {
        // Once we have a measurement for the sub-view's content, set the wrapper's frame
        if (self.frame.size.width != contentViewFrame.size.width) {
            self.frame = contentViewFrame;
        }
    }
}
@end

这在 iOS 11+ 上有效,但在 iOS 10.3 上无效,其中当包含自定义导航(红色框)的屏幕被按下时,导航过渡将动画titleView朝左上方设置动画,而不是进入中心(结束位置,这是正确的)我希望:

在此处输入图像描述

其他方法?

可能有办法克服上面的 iOS 10 故障(我很想听听),但我相当肯定一定有更好的方法。是否可以允许任意、复杂的视图在将其添加到父级之前对其进行布局并获取其测量值?我还尝试sizeThatFits在导航栏调用的包装器中进行覆盖,并请求RCTRootViewusing的大小[subView sizeThatFits: myLargeContainer],但我0,0回来了。

我很茫然 - 任何指针都值得赞赏。

4

0 回答 0