Skip to content

Commit

Permalink
Mound children under AutoLayoutView
Browse files Browse the repository at this point in the history
  • Loading branch information
j-piasecki committed Jun 7, 2024
1 parent ddb6c6a commit eb5cfad
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 25 deletions.
24 changes: 5 additions & 19 deletions ios/Sources/AutoLayoutView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,6 @@ import UIKit
private var lastMaxBound: CGFloat = 0
/// Tracks where first pixel is drawn in the visible window
private var lastMinBound: CGFloat = 0

private var viewsToLayout: [UIView] {
#if RCT_NEW_ARCH_ENABLED
return superview?.subviews ?? []
#else
return subviews
#endif
}

override public func layoutSubviews() {
fixLayout()
Expand Down Expand Up @@ -101,21 +93,15 @@ import UIKit
/// Performance: Sort is needed. Given relatively low number of views in RecyclerListView render tree this should be a non issue.
private func fixLayout() {
guard
viewsToLayout.count > 1,
subviews.count > 1,
// Fixing layout during animation can interfere with it.
layer.animationKeys()?.isEmpty ?? true,
!disableAutoLayout
else { return }
let cellContainers = viewsToLayout
let cellContainers = subviews
.compactMap { subview -> CellContainerComponentView? in
if let cellContainer = subview as? CellContainerComponentView {
return cellContainer
} else if subview is AutoLayoutView {
// On the new architecture, AutoLayoutView is wrapped with the ComponentView and all children will
// also be mounted under ComponentView. viewsToLayout property takes it under consideration,
// returning children of AutoLayoutViewComponentView when on Fabric. Because of that AutoLayoutView
// will be on the list and we want to ignore it.
return nil
} else {
assertionFailure("CellRendererComponent outer view should always be CellContainer. Learn more here: https://shopify.github.io/flash-list/docs/usage#cellrenderercomponent.")
return nil
Expand Down Expand Up @@ -285,10 +271,10 @@ import UIKit
}

private func footerDiff() -> CGFloat {
if viewsToLayout.count == 0 {
if subviews.count == 0 {
lastMaxBoundOverall = 0
} else if viewsToLayout.count == 1 {
let firstChild = viewsToLayout[0]
} else if subviews.count == 1 {
let firstChild = subviews[0]
lastMaxBoundOverall = horizontal ? firstChild.frame.maxX : firstChild.frame.maxY
}
let autoLayoutEnd = horizontal ? frame.width : frame.height
Expand Down
17 changes: 11 additions & 6 deletions ios/Sources/AutoLayoutViewComponentView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,8 @@ - (instancetype)initWithFrame:(CGRect)frame
static const auto defaultProps = std::make_shared<const AutoLayoutViewProps>();
_props = defaultProps;
_autoLayoutView = [[AutoLayoutView alloc] initWithFrame:self.bounds];

// Due to using ComponentView as wrapper, AutoLayoutView's children get moved to the ComponentView and
// AutoLayoutView is positioned above them consuming all events. Turning off userInteraction prevents that.
_autoLayoutView.userInteractionEnabled = false;

self.contentView = _autoLayoutView;

__weak AutoLayoutViewComponentView* weakSelf = self;
_autoLayoutView.onBlankAreaEventHandler = ^(CGFloat start, CGFloat end) {
AutoLayoutViewComponentView *strongSelf = weakSelf;
Expand All @@ -55,6 +50,16 @@ - (instancetype)initWithFrame:(CGRect)frame
return self;
}

- (void)mountChildComponentView:(UIView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index
{
[_autoLayoutView mountChildComponentView:childComponentView index:index];
}

- (void)unmountChildComponentView:(UIView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index
{
[_autoLayoutView unmountChildComponentView:childComponentView index:index];
}

#pragma mark - RCTComponentViewProtocol

+ (ComponentDescriptorProvider)componentDescriptorProvider
Expand Down

0 comments on commit eb5cfad

Please sign in to comment.