187 lines
5.2 KiB
Plaintext
187 lines
5.2 KiB
Plaintext
//
|
|
// Created by Jovanni Lo (@lodev09)
|
|
// Copyright (c) 2024-present. All rights reserved.
|
|
//
|
|
// This source code is licensed under the MIT license found in the
|
|
// LICENSE file in the root directory of this source tree.
|
|
//
|
|
|
|
#ifdef RCT_NEW_ARCH_ENABLED
|
|
|
|
#import "TrueSheetContainerView.h"
|
|
#import "TrueSheetContentView.h"
|
|
#import "TrueSheetFooterView.h"
|
|
#import "TrueSheetHeaderView.h"
|
|
|
|
#import <react/renderer/components/TrueSheetSpec/ComponentDescriptors.h>
|
|
#import <react/renderer/components/TrueSheetSpec/EventEmitters.h>
|
|
#import <react/renderer/components/TrueSheetSpec/Props.h>
|
|
#import <react/renderer/components/TrueSheetSpec/RCTComponentViewHelpers.h>
|
|
|
|
#import <React/RCTConversions.h>
|
|
#import <React/RCTLog.h>
|
|
|
|
using namespace facebook::react;
|
|
|
|
@interface TrueSheetContainerView () <TrueSheetContentViewDelegate, TrueSheetHeaderViewDelegate>
|
|
@end
|
|
|
|
@implementation TrueSheetContainerView {
|
|
TrueSheetContentView *_contentView;
|
|
TrueSheetHeaderView *_headerView;
|
|
TrueSheetFooterView *_footerView;
|
|
BOOL _scrollViewPinningSet;
|
|
}
|
|
|
|
#pragma mark - Initialization
|
|
|
|
+ (ComponentDescriptorProvider)componentDescriptorProvider {
|
|
return concreteComponentDescriptorProvider<TrueSheetContainerViewComponentDescriptor>();
|
|
}
|
|
|
|
- (instancetype)initWithFrame:(CGRect)frame {
|
|
if (self = [super initWithFrame:frame]) {
|
|
static const auto defaultProps = std::make_shared<const TrueSheetContainerViewProps>();
|
|
_props = defaultProps;
|
|
|
|
self.backgroundColor = [UIColor clearColor];
|
|
_contentView = nil;
|
|
_headerView = nil;
|
|
_footerView = nil;
|
|
_scrollViewPinningSet = NO;
|
|
}
|
|
return self;
|
|
}
|
|
|
|
#pragma mark - Layout
|
|
|
|
- (CGFloat)contentHeight {
|
|
return _contentView ? _contentView.frame.size.height : 0;
|
|
}
|
|
|
|
- (CGFloat)headerHeight {
|
|
return _headerView ? _headerView.frame.size.height : 0;
|
|
}
|
|
|
|
- (void)layoutFooter {
|
|
if (_footerView) {
|
|
CGFloat height = _footerView.frame.size.height;
|
|
if (height > 0) {
|
|
[_footerView setupConstraintsWithHeight:height];
|
|
}
|
|
}
|
|
}
|
|
|
|
- (void)setScrollViewPinningEnabled:(BOOL)scrollViewPinningEnabled {
|
|
_scrollViewPinningEnabled = scrollViewPinningEnabled;
|
|
_scrollViewPinningSet = YES;
|
|
}
|
|
|
|
- (void)setupContentScrollViewPinning {
|
|
if (_scrollViewPinningSet && _contentView) {
|
|
[_contentView setupScrollViewPinning:_scrollViewPinningEnabled withHeaderView:_headerView];
|
|
}
|
|
}
|
|
|
|
#pragma mark - Child Component Mounting
|
|
|
|
- (void)mountChildComponentView:(UIView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index {
|
|
[super mountChildComponentView:childComponentView index:index];
|
|
|
|
if ([childComponentView isKindOfClass:[TrueSheetContentView class]]) {
|
|
if (_contentView != nil) {
|
|
RCTLogWarn(@"TrueSheet: Container can only have one content component.");
|
|
return;
|
|
}
|
|
_contentView = (TrueSheetContentView *)childComponentView;
|
|
_contentView.delegate = self;
|
|
}
|
|
|
|
if ([childComponentView isKindOfClass:[TrueSheetHeaderView class]]) {
|
|
if (_headerView != nil) {
|
|
RCTLogWarn(@"TrueSheet: Container can only have one header component.");
|
|
return;
|
|
}
|
|
_headerView = (TrueSheetHeaderView *)childComponentView;
|
|
_headerView.delegate = self;
|
|
|
|
if (_contentView) {
|
|
[self setupContentScrollViewPinning];
|
|
}
|
|
[self headerViewDidChangeSize:_headerView.frame.size];
|
|
}
|
|
|
|
if ([childComponentView isKindOfClass:[TrueSheetFooterView class]]) {
|
|
if (_footerView != nil) {
|
|
RCTLogWarn(@"TrueSheet: Container can only have one footer component.");
|
|
return;
|
|
}
|
|
_footerView = (TrueSheetFooterView *)childComponentView;
|
|
}
|
|
}
|
|
|
|
- (void)unmountChildComponentView:(UIView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index {
|
|
if ([childComponentView isKindOfClass:[TrueSheetContentView class]]) {
|
|
_contentView.delegate = nil;
|
|
_contentView = nil;
|
|
}
|
|
|
|
if ([childComponentView isKindOfClass:[TrueSheetHeaderView class]]) {
|
|
_headerView.delegate = nil;
|
|
_headerView = nil;
|
|
|
|
if (_contentView) {
|
|
[self setupContentScrollViewPinning];
|
|
}
|
|
[self headerViewDidChangeSize:CGSizeZero];
|
|
}
|
|
|
|
if ([childComponentView isKindOfClass:[TrueSheetFooterView class]]) {
|
|
_footerView = nil;
|
|
}
|
|
|
|
[super unmountChildComponentView:childComponentView index:index];
|
|
}
|
|
|
|
- (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const &)oldProps {
|
|
[super updateProps:props oldProps:oldProps];
|
|
}
|
|
|
|
#pragma mark - TrueSheetContentViewDelegate
|
|
|
|
- (void)contentViewDidChangeSize:(CGSize)newSize {
|
|
if ([self.delegate respondsToSelector:@selector(containerViewContentDidChangeSize:)]) {
|
|
[self.delegate containerViewContentDidChangeSize:newSize];
|
|
}
|
|
}
|
|
|
|
- (void)contentViewDidChangeChildren {
|
|
[self setupContentScrollViewPinning];
|
|
}
|
|
|
|
#pragma mark - TrueSheetHeaderViewDelegate
|
|
|
|
- (void)headerViewDidChangeSize:(CGSize)newSize {
|
|
if ([self.delegate respondsToSelector:@selector(containerViewHeaderDidChangeSize:)]) {
|
|
[self.delegate containerViewHeaderDidChangeSize:newSize];
|
|
}
|
|
}
|
|
|
|
#pragma mark - Keyboard Handling
|
|
|
|
- (void)setupKeyboardHandler {
|
|
[_footerView setupKeyboardHandler];
|
|
}
|
|
|
|
- (void)cleanupKeyboardHandler {
|
|
[_footerView cleanupKeyboardHandler];
|
|
}
|
|
|
|
@end
|
|
|
|
Class<RCTComponentViewProtocol> TrueSheetContainerViewCls(void) {
|
|
return TrueSheetContainerView.class;
|
|
}
|
|
|
|
#endif
|