React Native本机UI组件宽度和高度

w7t8yxp5  于 2022-11-17  发布在  React
关注(0)|答案(4)|浏览(195)

我正在iOS上创建一个原生UI组件,我希望它的大小可以根据内容的大小进行扩展。似乎我必须设置一个固定的宽度和高度,以便渲染视图。有什么解决办法吗?
// JS中

import React from 'react';
import { View, requireNativeComponent } from 'react-native';

class StyledText extends React.Component {
render() {
    return (
        <View style={this.props.style}>
// without the height and width the compnent won't show up
            <StyledLabelReactBridge styledText={'some text'} style={{height: 100, width: 100, backgroundColor: 'red'}}/>
        </View>
    );
}
}

StyledText.propTypes = {
styledText: React.PropTypes.string,
style: View.propTypes.style
};

const StyledLabelReactBridge = requireNativeComponent('StyledLabelReactBridge', StyledText);

module.exports = StyledText;

//目标-C

@implementation StyledLabelReactBridgeManager

RCT_EXPORT_MODULE()

- (UIView *)view
{
return [[NewStyledLabel alloc] init];
}

RCT_CUSTOM_VIEW_PROPERTY(styledText, NSString, NewStyledLabel)
{
if (![json isKindOfClass:[NSString class]])
     return;

[view setStyledText:[NewStyledText textFromXHTML:json]];
}

@end
svgewumm

svgewumm1#

您需要覆盖xcode中的reactSetFrame以接收内容大小更改。

#import "React/UIView+React.h"

@implementation YourView {
    - (void)reactSetFrame:(CGRect)frame {
        [super reactSetFrame: frame];
        /* everytime content size changes, you will get its frame here. */
    }
}
oaxa6hgo

oaxa6hgo2#

首先,您应该创建RCTShadowView子类,如

#import <React/RCTShadowView.h>

@interface RNGuessLikeContainerShadowView : RCTShadowView

@end

@implementation RNGuessLikeContainerShadowView

- (void)setLocalData:(NSObject *)localData {
    if ([localData isKindOfClass:[NSNumber class]]) {
        [self setIntrinsicContentSize:CGSizeMake(UIScreen.mainScreen.bounds.size.width, ((NSNumber *)localData).floatValue)];
    }
}

@end

然后创建RCTViewManager子类,并返回自定义类示例的阴影视图和视图

#import <React/RCTUIManager.h>
#import <React/RCTUIManagerUtils.h>

@interface RNGuessLikeModule: RCTViewManager <RNGuessLikeContainerViewHeightUpdater>

@end

@implementation RNGuessLikeModule

RCT_EXPORT_MODULE(RNGuessLikeModule)

RCT_EXPORT_VIEW_PROPERTY(objects, NSString);

- (UIView *)view {
    RNGuessLikeContainerView *_view = [RNGuessLikeContainerView new];
    _view.delegate = self;
    return _view;
}

- (RCTShadowView *)shadowView {
    return [RNGuessLikeContainerShadowView new];
}

- (void)didUpdateWithHeight:(CGFloat)height view:(RNGuessLikeContainerView *)view {
    RCTExecuteOnUIManagerQueue(^{
        RCTShadowView *shadowView = [self.bridge.uiManager shadowViewForReactTag:view.reactTag];
        [shadowView setLocalData:@(height)];
        [self.bridge.uiManager setNeedsLayout];
    });
}

@end

在我代码中,我将自定义的原生UI视图委托给RCTViewManager的子类RNGuessLikeModule,当rn模块的数据通过时,您可以在自定义视图中计算大小

@objc
public protocol RNGuessLikeContainerViewHeightUpdater {
    func didUpdate(height: CGFloat, view: RNGuessLikeContainerView)
}

public final class RNGuessLikeContainerView: UIView, GuessLikeItemsComponentContainer {
    
    @objc
    public var objects: String? {
        didSet {
            if let _objects = objects,
                let _data = _objects.data(using: .utf8, allowLossyConversion: true) {
                reload(objects: _data)
            }
        }
    }
    
    @objc
    public weak var delegate: RNGuessLikeContainerViewHeightUpdater?
    
    public var controller: UIViewController {
        return reactViewController()
    }
    public var guessLikeSceneType: GuessLikeSceneType = .邀好友赚现金红包
    public var guessLikeTitle: String?
    public var guessLikeItems: [GuessLikeItemsSectionSubItem] = []
    public var routerInfo: String?
    @objc
    public private(set) var guessLikeHeight: CGFloat = 0
    
    lazy var backend = GuessLikeItemsComponentContainerBackend(parent: self)
    
    public lazy var guessLikeContainer: UICollectionView = {
        let _container = createGuessLikeContainer()
        _container.dataSource = backend
        _container.delegate = backend
        addSubview(_container)
        return _container
    }()
    
    override public func layoutSubviews() {
        super.layoutSubviews()
        guessLikeContainer.frame = bounds
    }
    
    public func reload(objects: Data) {
        precondition(pthread_main_np() != 0, "RNGuessLikeContainerView reload method should be called on main thread")
        do {
            let _items = try JSONDecoder().decode([ItemListModel].self, from: objects)
            guessLikeItems = GuessLikeItemsSectionItem(list: _items).items
            guessLikeContainer.reloadData()
            updateHeight()
        } catch {
            debugPrint(error)
        }
    }
    
    public func append(objects: Data) {
        precondition(pthread_main_np() != 0, "RNGuessLikeContainerView append method should be called on main thread")
        if let _list = try? JSONDecoder().decode([ItemListModel].self, from: objects) {
            let _items = GuessLikeItemsSectionItem(list: _list).items
            guessLikeItems.append(contentsOf: _items)
            guessLikeContainer.reloadData()
            updateHeight()
        }
    }
    
    func updateHeight() {
        if guessLikeItems.isEmpty {
            guessLikeHeight = 0
        } else {
            var leftHeight: CGFloat = 0
            var rightHeight: CGFloat = 0
            for (index, item) in guessLikeItems.enumerated() {
                if index % 2 == 0 {
                    leftHeight += item.height + 10.0
                } else {
                    rightHeight += item.height + 10.0
                }
            }
            
            let sectionHeaderHeight: CGFloat = 50.0
            guessLikeHeight = max(leftHeight, rightHeight) + sectionHeaderHeight
        }
        if let _delegate = delegate {
            _delegate.didUpdate(height: guessLikeHeight, view: self)
        }
    }
    
    public override var intrinsicContentSize: CGSize {
        return CGSize(width: UIScreen.main.bounds.width, height: guessLikeHeight)
    }
}

然后查找绑定到自定义ui视图的shadowview并更新intrinsicContentSize
最后调用[自身.桥接.uiManager设置需要布局]
可能对您有帮助

bnl4lu3b

bnl4lu3b3#

@implementation SNBFundCardViewManager

RCT_EXPORT_MODULE(FundCard)

- (UIView *)view
{
    return [[SNBFundHomeFundCardCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@""];
}

- (dispatch_queue_t)methodQueue
{
    return dispatch_get_main_queue();
}

RCT_CUSTOM_VIEW_PROPERTY(data, NSDictionary, SNBFundHomeFundCardCell)
{
    view.rnData = json;
    // 自己撑起高度
    CGFloat height = [view.vm getCellHeight];
    [self.bridge.uiManager setIntrinsicContentSize:CGSizeMake(UIViewNoIntrinsicMetric, height) forView:view];
}
wh6knrhe

wh6knrhe4#

嗯,找不到类似“auto”的行为,但是,将组件设置为:

{{ width: '100%', height: '100%}}

使其根据父对象扩展(和收缩),这对于我的用例来说已经足够了。1'没有相同的效果。

相关问题