diff --git a/android/src/main/java/com/reactnativenavigation/views/stack/topbar/titlebar/TitleAndButtonsContainer.kt b/android/src/main/java/com/reactnativenavigation/views/stack/topbar/titlebar/TitleAndButtonsContainer.kt index adcb58481c..71fe97fbf2 100644 --- a/android/src/main/java/com/reactnativenavigation/views/stack/topbar/titlebar/TitleAndButtonsContainer.kt +++ b/android/src/main/java/com/reactnativenavigation/views/stack/topbar/titlebar/TitleAndButtonsContainer.kt @@ -155,8 +155,9 @@ class TitleAndButtonsContainer(context: Context) : ViewGroup(context) { val rightBarWidth = rightButtonBar.measuredWidth val leftBarWidth = leftButtonBar.measuredWidth val isCenter = titleComponentAlignment == Alignment.Center + val isFill = titleComponentAlignment == Alignment.Fill val titleHeightMeasureSpec = MeasureSpec.makeMeasureSpec(containerHeight, MeasureSpec.AT_MOST) - val titleWidthMeasureSpec = makeTitleAtMostWidthMeasureSpec(containerWidth, rightBarWidth, leftBarWidth, isCenter) + val titleWidthMeasureSpec = makeTitleAtMostWidthMeasureSpec(containerWidth, rightBarWidth, leftBarWidth, isCenter, isFill) if (titleComponent is TitleBarReactView) { titleComponent.centered = isCenter } diff --git a/android/src/main/java/com/reactnativenavigation/views/stack/topbar/titlebar/TitleAndButtonsMeasurer.kt b/android/src/main/java/com/reactnativenavigation/views/stack/topbar/titlebar/TitleAndButtonsMeasurer.kt index 68cccb6a2a..8e77c48613 100644 --- a/android/src/main/java/com/reactnativenavigation/views/stack/topbar/titlebar/TitleAndButtonsMeasurer.kt +++ b/android/src/main/java/com/reactnativenavigation/views/stack/topbar/titlebar/TitleAndButtonsMeasurer.kt @@ -15,11 +15,15 @@ typealias TitleRight = Int typealias TitleTop = Int typealias TitleBottom = Int -fun makeTitleAtMostWidthMeasureSpec(containerWidth: Int, rightBarWidth: Int, leftBarWidth: Int, isCenter: Boolean): Int { +fun makeTitleAtMostWidthMeasureSpec(containerWidth: Int, rightBarWidth: Int, leftBarWidth: Int, isCenter: Boolean, isFill: Boolean = false): Int { return if (isCenter) { View.MeasureSpec.makeMeasureSpec(containerWidth, View.MeasureSpec.AT_MOST) } else { - View.MeasureSpec.makeMeasureSpec(containerWidth - rightBarWidth - leftBarWidth - 2 * DEFAULT_LEFT_MARGIN_PX, View.MeasureSpec.AT_MOST) + val availableWidth = containerWidth - rightBarWidth - leftBarWidth - 2 * DEFAULT_LEFT_MARGIN_PX + View.MeasureSpec.makeMeasureSpec( + availableWidth, + if (isFill) View.MeasureSpec.EXACTLY else View.MeasureSpec.AT_MOST + ) } } diff --git a/ios/RNNReactTitleView.mm b/ios/RNNReactTitleView.mm index bfc4d5e93c..f8dae2d569 100644 --- a/ios/RNNReactTitleView.mm +++ b/ios/RNNReactTitleView.mm @@ -2,6 +2,7 @@ @implementation RNNReactTitleView { BOOL _fillParent; + CGFloat _expectedHeight; } - (NSString *)componentType { @@ -10,7 +11,7 @@ - (NSString *)componentType { - (CGSize)intrinsicContentSize { if (_fillParent) { - return UILayoutFittingExpandedSize; + return CGSizeMake(UILayoutFittingExpandedSize.width, _expectedHeight > 0 ? _expectedHeight : 44); } else { return [super intrinsicContentSize]; } @@ -19,6 +20,7 @@ - (CGSize)intrinsicContentSize { - (void)setAlignment:(NSString *)alignment inFrame:(CGRect)frame { if ([alignment isEqualToString:@"fill"]) { _fillParent = YES; + _expectedHeight = frame.size.height; self.translatesAutoresizingMaskIntoConstraints = NO; self.sizeFlexibility = RCTRootViewSizeFlexibilityNone; } else { diff --git a/playground/e2e/Options.test.js b/playground/e2e/Options.test.js index 6092ec7c10..35fc7a256f 100644 --- a/playground/e2e/Options.test.js +++ b/playground/e2e/Options.test.js @@ -55,6 +55,19 @@ describe('Options', () => { await expect(elementByLabel('Title Changed')).toBeVisible(); }); + it('TopBar custom title with subtitle should be visible', async () => { + await elementById(TestIDs.GOTO_TOPBAR_TITLE_TEST).tap(); + await expect(elementById(TestIDs.TOPBAR_TITLE_TEXT)).toBeVisible(); + await expect(elementById(TestIDs.TOPBAR_TITLE_AVATAR)).toBeVisible(); + }); + + it('TopBar custom title without subtitle should be visible', async () => { + await elementById(TestIDs.GOTO_TOPBAR_TITLE_TEST).tap(); + await elementById(TestIDs.SET_TOPBAR_WITHOUT_SUBTITLE_BTN).tap(); + await expect(elementById(TestIDs.TOPBAR_TITLE_TEXT)).toBeVisible(); + await expect(elementById(TestIDs.TOPBAR_TITLE_AVATAR)).toBeVisible(); + }); + it('Popping screen with yellow box should not crash', async () => { await elementById(TestIDs.SHOW_YELLOW_BOX_BTN).tap(); await elementById(TestIDs.PUSH_BTN).tap(); diff --git a/playground/src/screens/OptionsScreen.tsx b/playground/src/screens/OptionsScreen.tsx index 4910b86d35..985fa7e465 100644 --- a/playground/src/screens/OptionsScreen.tsx +++ b/playground/src/screens/OptionsScreen.tsx @@ -20,9 +20,10 @@ const { GOTO_SEARCHBAR_MODAL, REPLACE_TAB_TEST_ID, REPLACED_TAB, + GOTO_TOPBAR_TITLE_TEST, } = testIDs; -interface Props extends NavigationProps {} +interface Props extends NavigationProps { } export default class Options extends NavigationComponent { static options() { @@ -75,6 +76,11 @@ export default class Options extends NavigationComponent { testID={SET_REACT_TITLE_VIEW} onPress={this.setReactTitleView} /> +