Skip to content

iOS layout issue on orientation change with Frame inside RadSideDrawer #11265

@felixkrautschuk

Description

@felixkrautschuk

Issue Description

We want to show a main menu (fullscreen) and the user should be able to navigate inside that menu
-> RadSideDrawer with a Frame defaultPage="menu-page" as drawerContent

While everything works as expected on Android, we see a weird layout issue on iOS when the menu is opened and the device orientation changed. It is hard to explain and to understand, but fortunately I am able to make it reproducable in a sample app.

So the app structure is:
app-root:

<Frame id="frameRoot" defaultPage="main-page"/>

home-page:

<Page xmlns:nsDrawer="nativescript-ui-sidedrawer">
    <nsDrawer:RadSideDrawer layoutChanged="onLayoutChanged">

        <nsDrawer:RadSideDrawer.drawerContent>
            <GridLayout rows="*" columns="*">
                <Frame id="frameRadSideDrawer" defaultPage="menu-page"/>
            </GridLayout>
        </nsDrawer:RadSideDrawer.drawerContent>

        <nsDrawer:RadSideDrawer.mainContent>
            ...
        </nsDrawer:RadSideDrawer.mainContent>
    </nsDrawer:RadSideDrawer>
</Page>

menu-page:

<Page>
    <GridLayout rows="auto,*">
        ...
        <ScrollView row="1">
            <StackLayout padding="15">
                <Label text="Test 1" marginTop="10"/>
                <Label text="Test 2" marginTop="10"/>
                ...

                <StackLayout id="innerStackLayout" marginTop="10" backgroundColor="green">
                    <Label text="Test 5"/>
                </StackLayout>

                <Label text="Test 6" marginTop="10"/>
            </StackLayout>
        </ScrollView>
    </GridLayout>
</Page>

To give the RadSideDrawer drawerContent the correct size after orientation changes, updating the drawerContentSize property is enough on Android, but on iOS I also have to do this in the layoutChanged event:

export function onLayoutChanged(args) {
  const height = args.object.getActualSize().height;
  menuDrawer.drawerContentSize = height;

  if(isIOS) {
    const menuDrawerDefaultIOS = menuDrawer.ios.defaultSideDrawer;

    menuDrawerDefaultIOS.frame = CGRectMake(
      menuDrawer.ios.frame.origin.x,
      menuDrawer.ios.frame.origin.y,
      menuDrawer.ios.frame.size.width,
      height
    );
  }
}

on iOS orientation change looks like that:
https://github.com/user-attachments/assets/fa51ea11-0fa3-4de7-ae1e-ce70ba53ee03

So fore some reason, the position of the inner StackLayout (green) is positioned wrong and it is getting the wrong size (see logs below), so it is overlapping the rest of the content.
But only on orientation change while the drawer is open.
When opening the drawer while already in landscape mode, the layout is correct. Changing to portrait mode is still correct, changing back to landscape is messing up the layout again.

Some further observations:
The issue does NOT occur, when temporary:

  • removing the ScrollView from menu-page content
  • removing that inner StackLayout around Label 5 -> all Labels are displayed correctly without overlapping
  • remove the Frame in drawer content and put the menu-page content directly (but we need Frame for navigation inside the menu in our real app)
  • use the menu page outside RadSideDrawer

So the scenario
RadSideDrawer drawerContent -> Frame -> Page -> ScrollView -> some inner Layout container
seems to break layouting somehow on orientation change

Maybe the issue belongs more to the nativescript-ui-feedback repo but as it seems to be dead somehow, I decided to post it here.

Thank you for any advice!

Reproduction

ns-drawer-frame-ios.zip

Relevant log output (if applicable)

------------------------------------------
  page navigated portrait
  inner measured 1116 61
  inner actual size {
    "width": 372,
    "height": 20.333333333333332
  }
  inner location on screen {
    "x": 15,
    "y": 292.66666666666663
  }
  NativeScript debugger has opened inspector socket on port 18183 for org.nativescript.nsdrawerframeios.
Successfully synced application org.nativescript.nsdrawerframeios on device EA9C7EBC-E7D2-4D5C-8F3A-0459BEF1A059.
  ------------------------------------------
  drawer opened
  ------------------------------------------
  orientation change landscape
  inner measured 2160 61
  inner actual size {
    "width": 720,
    "height": 203
  }
  inner location on screen {
    "x": 77,
    "y": 48
  }
  ------------------------------------------
  orientation change portrait
  inner measured 2160 61
  inner actual size {
    "width": 720,
    "height": 203
  }
  inner location on screen {
    "x": 77,
    "y": 48
  }
  ------------------------------------------
  drawer closed
  ------------------------------------------
  orientation change landscape
  inner measured 2160 61
  inner actual size {
    "width": 720,
    "height": 20.333333333333332
  }
  inner location on screen {
    "x": 77,
    "y": 230.66666666666666
  }
  ------------------------------------------
  drawer opened
  ------------------------------------------
  orientation change portrait
  inner measured 2160 61
  inner actual size {
    "width": 720,
    "height": 20.333333333333332
  }
  inner location on screen {
    "x": 77,
    "y": 230.66666666666666
  }
  ------------------------------------------
  orientation change landscape
  inner measured 2160 61
  inner actual size {
    "width": 720,
    "height": 203
  }
  inner location on screen {
    "x": 77,
    "y": 48
  }
  ------------------------------------------
  drawer closed

Environment

OS: macOS 26.5.1
CPU: (12) x64 Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
Shell: /bin/zsh
node: 24.15.0
npm: 11.16.0
nativescript: 9.0.6

# android
java: 17.0.11
ndk: Not Found
apis: 35, 36, 36, 37
build_tools: 34.0.0, 35.0.0, 35.0.1, 36.0.0, 36.1.0, 37.0.0
system_images: 
  - android-36.1 | Google Play Intel x86_64 Atom
  - android-36.1 | Pre-Release 16 KB Page Size Google Play Intel x86_64 Atom
  - android-37.0 | 16 KB Page Size Google Play Intel x86_64 Atom

# ios
xcode: 26.5/17F42
cocoapods: 1.16.2
python: 2.7.18
python3: 3.13.0
ruby: 2.6.10
platforms: 
  - DriverKit 25.5
  - iOS 26.5
  - macOS 26.5
  - tvOS 26.5
  - visionOS 26.5
  - watchOS 26.5

Dependencies

"dependencies": {
  "@nativescript/core": "^9.0.20",
  "nativescript-ui-sidedrawer": "^15.2.4"
},
"devDependencies": {
  "@nativescript/android": "^9.0.4",
  "@nativescript/ios": "^9.0.3",
  "@nativescript/types": "~9.0.0",
  "@nativescript/webpack": "^5.0.35",
  "typescript": "~5.4.0"
}

Please accept these terms

Metadata

Metadata

Assignees

No one assigned

    Labels

    bug-pending-triageReported bug, pending triage to confirm.

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions