Skip to content

Commit 7eaafa5

Browse files
authored
chore: ios relayout condition cleanup (#10241)
1 parent 8b721c1 commit 7eaafa5

3 files changed

Lines changed: 106 additions & 103 deletions

File tree

‎apps/automated/src/test-runner.ts‎

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -138,19 +138,19 @@ allTests['STACKLAYOUT'] = stackLayoutTests;
138138
import * as flexBoxLayoutTests from './ui/layouts/flexbox-layout-tests';
139139
allTests['FLEXBOXLAYOUT'] = flexBoxLayoutTests;
140140

141-
// import * as safeAreaLayoutTests from './ui/layouts/safe-area-tests';
142-
// import * as safeAreaListViewtTests from './ui/list-view/list-view-safe-area-tests';
143-
// import * as scrollViewSafeAreaTests from './ui/scroll-view/scroll-view-safe-area-tests';
144-
// import * as repeaterSafeAreaTests from './ui/repeater/repeater-safe-area-tests';
145-
// import * as webViewSafeAreaTests from './ui/web-view/web-view-safe-area-tests';
146-
147-
// if (isIOS && Utils.ios.MajorVersion > 10) {
148-
// allTests['SAFEAREALAYOUT'] = safeAreaLayoutTests;
149-
// allTests['SAFEAREA-LISTVIEW'] = safeAreaListViewtTests;
150-
// allTests['SAFEAREA-SCROLL-VIEW'] = scrollViewSafeAreaTests;
151-
// allTests['SAFEAREA-REPEATER'] = repeaterSafeAreaTests;
152-
// allTests['SAFEAREA-WEBVIEW'] = webViewSafeAreaTests;
153-
// }
141+
import * as safeAreaLayoutTests from './ui/layouts/safe-area-tests';
142+
import * as safeAreaListViewtTests from './ui/list-view/list-view-safe-area-tests';
143+
import * as scrollViewSafeAreaTests from './ui/scroll-view/scroll-view-safe-area-tests';
144+
import * as repeaterSafeAreaTests from './ui/repeater/repeater-safe-area-tests';
145+
import * as webViewSafeAreaTests from './ui/web-view/web-view-safe-area-tests';
146+
147+
if (isIOS && Utils.ios.MajorVersion > 10) {
148+
allTests['SAFEAREALAYOUT'] = safeAreaLayoutTests;
149+
allTests['SAFEAREA-LISTVIEW'] = safeAreaListViewtTests;
150+
allTests['SAFEAREA-SCROLL-VIEW'] = scrollViewSafeAreaTests;
151+
allTests['SAFEAREA-REPEATER'] = repeaterSafeAreaTests;
152+
allTests['SAFEAREA-WEBVIEW'] = webViewSafeAreaTests;
153+
}
154154

155155
import * as rootViewsCssClassesTests from './ui/styling/root-views-css-classes-tests';
156156
allTests['ROOT-VIEWS-CSS-CLASSES'] = rootViewsCssClassesTests;

‎packages/core/ui/core/view/view-helper/index.ios.ts‎

Lines changed: 45 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -92,61 +92,62 @@ class UILayoutViewController extends UIViewController {
9292
}
9393
layoutOwner(force = false) {
9494
const owner = this.owner?.deref();
95-
if (!force && !!owner.nativeViewProtected?.layer.needsLayout?.()) {
95+
if (!owner) {
96+
return;
97+
}
98+
if (!force && owner.isLayoutValid && !owner.nativeViewProtected?.layer.needsLayout?.()) {
9699
// we skip layout if the view is not yet laid out yet
97100
// this usually means that viewDidLayoutSubviews will be called again
98101
// so doing a layout pass now will layout with the wrong parameters
99102
return;
100103
}
101104

102-
if (owner) {
103-
if (majorVersion >= 11) {
104-
// Handle nested UILayoutViewController safe area application.
105-
// Currently, UILayoutViewController can be nested only in a TabView.
106-
// The TabView itself is handled by the OS, so we check the TabView's parent (usually a Page, but can be a Layout).
107-
const tabViewItem = owner.parent;
108-
const tabView = tabViewItem && tabViewItem.parent;
109-
let parent = tabView && tabView.parent;
110-
111-
// Handle Angular scenario where TabView is in a ProxyViewContainer
112-
// It is possible to wrap components in ProxyViewContainers indefinitely
113-
// Not using instanceof ProxyViewContainer to avoid circular dependency
114-
// TODO: Try moving UILayoutViewController out of view module
115-
while (parent && !parent.nativeViewProtected) {
116-
parent = parent.parent;
105+
if (majorVersion >= 11) {
106+
// Handle nested UILayoutViewController safe area application.
107+
// Currently, UILayoutViewController can be nested only in a TabView.
108+
// The TabView itself is handled by the OS, so we check the TabView's parent (usually a Page, but can be a Layout).
109+
const tabViewItem = owner.parent;
110+
const tabView = tabViewItem && tabViewItem.parent;
111+
let parent = tabView && tabView.parent;
112+
113+
// Handle Angular scenario where TabView is in a ProxyViewContainer
114+
// It is possible to wrap components in ProxyViewContainers indefinitely
115+
// Not using instanceof ProxyViewContainer to avoid circular dependency
116+
// TODO: Try moving UILayoutViewController out of view module
117+
while (parent && !parent.nativeViewProtected) {
118+
parent = parent.parent;
119+
}
120+
121+
if (parent) {
122+
const parentPageInsetsTop = parent.nativeViewProtected.safeAreaInsets.top;
123+
const parentPageInsetsBottom = parent.nativeViewProtected.safeAreaInsets.bottom;
124+
let currentInsetsTop = this.view.safeAreaInsets.top;
125+
let currentInsetsBottom = this.view.safeAreaInsets.bottom;
126+
127+
// Safe area insets include additional safe area insets too, so subtract old values
128+
if (this.additionalSafeAreaInsets) {
129+
currentInsetsTop -= this.additionalSafeAreaInsets.top;
130+
currentInsetsBottom -= this.additionalSafeAreaInsets.bottom;
117131
}
118132

119-
if (parent) {
120-
const parentPageInsetsTop = parent.nativeViewProtected.safeAreaInsets.top;
121-
const parentPageInsetsBottom = parent.nativeViewProtected.safeAreaInsets.bottom;
122-
let currentInsetsTop = this.view.safeAreaInsets.top;
123-
let currentInsetsBottom = this.view.safeAreaInsets.bottom;
124-
125-
// Safe area insets include additional safe area insets too, so subtract old values
126-
if (this.additionalSafeAreaInsets) {
127-
currentInsetsTop -= this.additionalSafeAreaInsets.top;
128-
currentInsetsBottom -= this.additionalSafeAreaInsets.bottom;
129-
}
130-
131-
const additionalInsetsTop = Math.max(parentPageInsetsTop - currentInsetsTop, 0);
132-
const additionalInsetsBottom = Math.max(parentPageInsetsBottom - currentInsetsBottom, 0);
133-
134-
if (additionalInsetsTop > 0 || additionalInsetsBottom > 0) {
135-
const additionalInsets = new UIEdgeInsets({
136-
top: additionalInsetsTop,
137-
left: 0,
138-
bottom: additionalInsetsBottom,
139-
right: 0,
140-
});
141-
this.additionalSafeAreaInsets = additionalInsets;
142-
} else {
143-
this.additionalSafeAreaInsets = null;
144-
}
133+
const additionalInsetsTop = Math.max(parentPageInsetsTop - currentInsetsTop, 0);
134+
const additionalInsetsBottom = Math.max(parentPageInsetsBottom - currentInsetsBottom, 0);
135+
136+
if (additionalInsetsTop > 0 || additionalInsetsBottom > 0) {
137+
const additionalInsets = new UIEdgeInsets({
138+
top: additionalInsetsTop,
139+
left: 0,
140+
bottom: additionalInsetsBottom,
141+
right: 0,
142+
});
143+
this.additionalSafeAreaInsets = additionalInsets;
144+
} else {
145+
this.additionalSafeAreaInsets = null;
145146
}
146147
}
147-
148-
IOSHelper.layoutView(this, owner);
149148
}
149+
150+
IOSHelper.layoutView(this, owner);
150151
}
151152

152153
public viewWillAppear(animated: boolean): void {

‎packages/core/ui/page/index.ios.ts‎

Lines changed: 48 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -312,63 +312,65 @@ class UIViewControllerImpl extends UIViewController {
312312

313313
layoutOwner(force = false) {
314314
const owner = this._owner?.deref();
315-
if (!force && !!owner.nativeViewProtected?.layer.needsLayout?.()) {
315+
if (!owner) {
316+
return;
317+
}
318+
if (!force && owner.isLayoutValid && !owner.nativeViewProtected?.layer.needsLayout?.()) {
316319
// we skip layout if the view is not yet laid out yet
317320
// this usually means that viewDidLayoutSubviews will be called again
318321
// so doing a layout pass now will layout with the wrong parameters
319322
return;
320323
}
321-
if (owner) {
322-
// layout(owner.actionBar)
323-
// layout(owner.content)
324-
325-
if (majorVersion >= 11) {
326-
// Handle nested Page safe area insets application.
327-
// A Page is nested if its Frame has a parent.
328-
// If the Page is nested, cross check safe area insets on top and bottom with Frame parent.
329-
const frame = owner.parent;
330-
// There is a legacy scenario where Page is not in a Frame - the root of a Modal View, so it has no parent.
331-
let frameParent = frame && frame.parent;
332-
333-
// Handle Angular scenario where TabView is in a ProxyViewContainer
334-
// It is possible to wrap components in ProxyViewContainers indefinitely
335-
// Not using instanceof ProxyViewContainer to avoid circular dependency
336-
// TODO: Try moving UIViewControllerImpl out of page module
337-
while (frameParent && !frameParent.nativeViewProtected) {
338-
frameParent = frameParent.parent;
339-
}
340324

341-
if (frameParent) {
342-
const parentPageInsetsTop = frameParent.nativeViewProtected.safeAreaInsets.top;
343-
const parentPageInsetsBottom = frameParent.nativeViewProtected.safeAreaInsets.bottom;
344-
let currentInsetsTop = this.view.safeAreaInsets.top;
345-
let currentInsetsBottom = this.view.safeAreaInsets.bottom;
325+
// layout(owner.actionBar)
326+
// layout(owner.content)
346327

347-
// Safe area insets include additional safe area insets too, so subtract old values
348-
if (this.additionalSafeAreaInsets) {
349-
currentInsetsTop -= this.additionalSafeAreaInsets.top;
350-
currentInsetsBottom -= this.additionalSafeAreaInsets.bottom;
351-
}
328+
if (majorVersion >= 11) {
329+
// Handle nested Page safe area insets application.
330+
// A Page is nested if its Frame has a parent.
331+
// If the Page is nested, cross check safe area insets on top and bottom with Frame parent.
332+
const frame = owner.parent;
333+
// There is a legacy scenario where Page is not in a Frame - the root of a Modal View, so it has no parent.
334+
let frameParent = frame && frame.parent;
352335

353-
const additionalInsetsTop = Math.max(parentPageInsetsTop - currentInsetsTop, 0);
354-
const additionalInsetsBottom = Math.max(parentPageInsetsBottom - currentInsetsBottom, 0);
355-
356-
if (additionalInsetsTop > 0 || additionalInsetsBottom > 0) {
357-
const additionalInsets = new UIEdgeInsets({
358-
top: additionalInsetsTop,
359-
left: 0,
360-
bottom: additionalInsetsBottom,
361-
right: 0,
362-
});
363-
this.additionalSafeAreaInsets = additionalInsets;
364-
} else {
365-
this.additionalSafeAreaInsets = null;
366-
}
367-
}
336+
// Handle Angular scenario where TabView is in a ProxyViewContainer
337+
// It is possible to wrap components in ProxyViewContainers indefinitely
338+
// Not using instanceof ProxyViewContainer to avoid circular dependency
339+
// TODO: Try moving UIViewControllerImpl out of page module
340+
while (frameParent && !frameParent.nativeViewProtected) {
341+
frameParent = frameParent.parent;
368342
}
369343

370-
IOSHelper.layoutView(this, owner);
344+
if (frameParent) {
345+
const parentPageInsetsTop = frameParent.nativeViewProtected.safeAreaInsets.top;
346+
const parentPageInsetsBottom = frameParent.nativeViewProtected.safeAreaInsets.bottom;
347+
let currentInsetsTop = this.view.safeAreaInsets.top;
348+
let currentInsetsBottom = this.view.safeAreaInsets.bottom;
349+
350+
// Safe area insets include additional safe area insets too, so subtract old values
351+
if (this.additionalSafeAreaInsets) {
352+
currentInsetsTop -= this.additionalSafeAreaInsets.top;
353+
currentInsetsBottom -= this.additionalSafeAreaInsets.bottom;
354+
}
355+
356+
const additionalInsetsTop = Math.max(parentPageInsetsTop - currentInsetsTop, 0);
357+
const additionalInsetsBottom = Math.max(parentPageInsetsBottom - currentInsetsBottom, 0);
358+
359+
if (additionalInsetsTop > 0 || additionalInsetsBottom > 0) {
360+
const additionalInsets = new UIEdgeInsets({
361+
top: additionalInsetsTop,
362+
left: 0,
363+
bottom: additionalInsetsBottom,
364+
right: 0,
365+
});
366+
this.additionalSafeAreaInsets = additionalInsets;
367+
} else {
368+
this.additionalSafeAreaInsets = null;
369+
}
370+
}
371371
}
372+
373+
IOSHelper.layoutView(this, owner);
372374
}
373375

374376
// Mind implementation for other controllerss

0 commit comments

Comments
 (0)