Skip to content

Commit fabe0ba

Browse files
author
Hristo Hristov
committed
Merge pull request NativeScript#1126 from NativeScript/hhristov/nested-frame-ios
Fixed nested frame layout for iOS
2 parents e7a7165 + 31c3668 commit fabe0ba

File tree

3 files changed

+37
-15
lines changed

3 files changed

+37
-15
lines changed

ui/core/view-common.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1116,7 +1116,7 @@ export class View extends proxy.ProxyObject implements definition.View {
11161116
return this.typeName + `<${this.id}>`;
11171117
}
11181118

1119-
return this.typeName;
1119+
return this.typeName + `(${this._domId})`;
11201120
}
11211121

11221122
public _setNativeViewFrame(nativeView: any, frame: any) {

ui/frame/frame.ios.ts

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ export class Frame extends frameCommon.Frame {
2323
public _navigateToEntry: definition.BackstackEntry;
2424
public _widthMeasureSpec: number;
2525
public _heightMeasureSpec: number;
26-
public _layoutWidth: number;
27-
public _layoutheight: number;
26+
public _right: number;
27+
public _bottom: number;
2828

2929
constructor() {
3030
super();
@@ -64,7 +64,6 @@ export class Frame extends frameCommon.Frame {
6464

6565
backstackEntry[NAV_DEPTH] = navDepth;
6666
viewController[ENTRY] = backstackEntry;
67-
this._navigateToEntry = backstackEntry;
6867

6968
this._updateActionBar(backstackEntry.resolvedPage);
7069

@@ -119,7 +118,6 @@ export class Frame extends frameCommon.Frame {
119118
if (!this._shouldSkipNativePop) {
120119
var controller = backstackEntry.resolvedPage.ios;
121120
var animated = this._getIsAnimatedNavigation(backstackEntry.entry);
122-
this._navigateToEntry = backstackEntry;
123121

124122
this._updateActionBar(backstackEntry.resolvedPage);
125123
this._ios.controller.popToViewControllerAnimated(controller, animated);
@@ -196,6 +194,11 @@ export class Frame extends frameCommon.Frame {
196194
this._heightMeasureSpec = heightMeasureSpec;
197195

198196
let result = this.measurePage(this.currentPage);
197+
if (this._navigateToEntry && this.currentPage) {
198+
let newPageSize = this.measurePage(this._navigateToEntry.resolvedPage);
199+
result.measuredWidth = Math.max(result.measuredWidth, newPageSize.measuredWidth);
200+
result.measuredHeight = Math.max(result.measuredHeight, newPageSize.measuredHeight);
201+
}
199202
let widthAndState = view.View.resolveSizeAndState(result.measuredWidth, width, widthMode, 0);
200203
let heightAndState = view.View.resolveSizeAndState(result.measuredHeight, height, heightMode, 0);
201204

@@ -206,7 +209,7 @@ export class Frame extends frameCommon.Frame {
206209

207210
// If background does not span under statusbar - reduce available height.
208211
let heightSpec: number = this._heightMeasureSpec;
209-
if (page && !page.backgroundSpanUnderStatusBar) {
212+
if (page && !page.backgroundSpanUnderStatusBar && !this.parent) {
210213
let height = utils.layout.getMeasureSpecSize(this._heightMeasureSpec);
211214
let heightMode = utils.layout.getMeasureSpecMode(this._heightMeasureSpec);
212215
let statusBarHeight = uiUtils.ios.getStatusBarHeight();
@@ -217,16 +220,19 @@ export class Frame extends frameCommon.Frame {
217220
}
218221

219222
public onLayout(left: number, top: number, right: number, bottom: number): void {
220-
this._layoutWidth = right - left;
221-
this._layoutheight = bottom - top;
223+
this._right = right;
224+
this._bottom = bottom;
222225
this.layoutPage(this.currentPage);
226+
if (this._navigateToEntry && this.currentPage) {
227+
this.layoutPage(this._navigateToEntry.resolvedPage);
228+
}
223229
}
224230

225231
public layoutPage(page: pages.Page): void {
226232
// If background does not span under statusbar - reduce available height and adjust top offset.
227-
let statusBarHeight = (page && !page.backgroundSpanUnderStatusBar) ? uiUtils.ios.getStatusBarHeight() : 0;
233+
let statusBarHeight = (page && !page.backgroundSpanUnderStatusBar && !this.parent) ? uiUtils.ios.getStatusBarHeight() : 0;
228234

229-
view.View.layoutChild(this, page, 0, statusBarHeight, this._layoutWidth, this._layoutheight);
235+
view.View.layoutChild(this, page, 0, statusBarHeight, this._right, this._bottom);
230236
}
231237

232238
public get navigationBarHeight(): number {
@@ -244,6 +250,14 @@ export class Frame extends frameCommon.Frame {
244250

245251
super._setNativeViewFrame(nativeView, frame);
246252
}
253+
254+
public remeasureFrame(): void {
255+
this.requestLayout();
256+
let window: UIWindow = this._nativeView.window;
257+
if (window) {
258+
window.layoutIfNeeded();
259+
}
260+
}
247261
}
248262

249263
class UINavigationControllerImpl extends UINavigationController implements UINavigationControllerDelegate {
@@ -295,8 +309,7 @@ class UINavigationControllerImpl extends UINavigationController implements UINav
295309
}
296310

297311
frame._addView(newPage);
298-
frame.measurePage(newPage);
299-
frame.layoutPage(newPage)
312+
frame.remeasureFrame();
300313
}
301314
else if (newPage.parent !== frame) {
302315
throw new Error("Page is already shown on another frame.");
@@ -355,9 +368,7 @@ class UINavigationControllerImpl extends UINavigationController implements UINav
355368

356369
frame._navigateToEntry = null;
357370
frame._currentEntry = newEntry;
358-
359-
frame.measurePage(newPage);
360-
frame.layoutPage(newPage);
371+
frame.remeasureFrame();
361372

362373
// In iOS we intentionally delay the raising of the 'loaded' event so both platforms behave identically.
363374
// The loaded event must be raised AFTER the page is part of the windows hierarchy and

ui/page/page.ios.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,11 @@ export class Page extends pageCommon.Page {
260260

261261
// If background span under statusbar reduce available height for page content.
262262
let statusBarHeight = this.backgroundSpanUnderStatusBar ? uiUtils.ios.getStatusBarHeight() : 0;
263+
264+
// If this page is inside nested frame - don't substract statusBarHeight again.
265+
if (this.frame && this.frame.parent) {
266+
statusBarHeight = 0;
267+
}
263268

264269
// Phones does not support fullScreen=false for modal pages so we reduce statusbar only when on tablet and not in fullscreen
265270
if (this._isModal && this._UIModalPresentationFormSheet && device.deviceType === DeviceType.Tablet) {
@@ -296,6 +301,12 @@ export class Page extends pageCommon.Page {
296301
}
297302

298303
let statusBarHeight = this.backgroundSpanUnderStatusBar ? uiUtils.ios.getStatusBarHeight() : 0;
304+
305+
// If this page is inside nested frame - don't substract statusBarHeight again.
306+
if (this.frame && this.frame.parent) {
307+
statusBarHeight = 0;
308+
}
309+
299310
// Phones does not support fullScreen=false for modal pages so we reduce statusbar only when on tablet and not in fullscreen
300311
if (this._isModal && this._UIModalPresentationFormSheet && device.deviceType === DeviceType.Tablet) {
301312
statusBarHeight = 0;

0 commit comments

Comments
 (0)