1 |
|
2 | import { ViewCommon, isEnabledProperty, originXProperty, originYProperty, isUserInteractionEnabledProperty, testIDProperty } from './view-common';
|
3 | import { hiddenProperty } from '../view-base';
|
4 | import { Trace } from '../../../trace';
|
5 | import { layout, ios as iosUtils, SDK_VERSION } from '../../../utils';
|
6 | import { IOSHelper } from './view-helper';
|
7 | import { ios as iosBackground } from '../../styling/background';
|
8 | import { perspectiveProperty, visibilityProperty, opacityProperty, rotateProperty, rotateXProperty, rotateYProperty, scaleXProperty, scaleYProperty, translateXProperty, translateYProperty, zIndexProperty, backgroundInternalProperty } from '../../styling/style-properties';
|
9 | import { profile } from '../../../profiling';
|
10 | import { accessibilityEnabledProperty, accessibilityHiddenProperty, accessibilityHintProperty, accessibilityIdentifierProperty, accessibilityLabelProperty, accessibilityLanguageProperty, accessibilityLiveRegionProperty, accessibilityMediaSessionProperty, accessibilityRoleProperty, accessibilityStateProperty, accessibilityValueProperty, accessibilityIgnoresInvertColorsProperty } from '../../../accessibility/accessibility-properties';
|
11 | import { IOSPostAccessibilityNotificationType, isAccessibilityServiceEnabled, updateAccessibilityProperties } from '../../../accessibility';
|
12 | import { CoreTypes } from '../../../core-types';
|
13 | import { SharedTransition } from '../../transition/shared-transition';
|
14 | export * from './view-common';
|
15 |
|
16 | export * from './view-helper';
|
17 |
|
18 | export * from '../properties';
|
19 | const PFLAG_FORCE_LAYOUT = 1;
|
20 | const PFLAG_MEASURED_DIMENSION_SET = 1 << 1;
|
21 | const PFLAG_LAYOUT_REQUIRED = 1 << 2;
|
22 | export class View extends ViewCommon {
|
23 | constructor() {
|
24 | super(...arguments);
|
25 | this._isLaidOut = false;
|
26 | this._hasTransform = false;
|
27 | this._hasPendingTransform = false;
|
28 | this._privateFlags = PFLAG_LAYOUT_REQUIRED | PFLAG_FORCE_LAYOUT;
|
29 | this._suspendCATransaction = false;
|
30 | }
|
31 | get isLayoutRequired() {
|
32 | return (this._privateFlags & PFLAG_LAYOUT_REQUIRED) === PFLAG_LAYOUT_REQUIRED;
|
33 | }
|
34 | get isLayoutRequested() {
|
35 | return (this._privateFlags & PFLAG_FORCE_LAYOUT) === PFLAG_FORCE_LAYOUT;
|
36 | }
|
37 | disposeNativeView() {
|
38 | super.disposeNativeView();
|
39 | this._cachedFrame = null;
|
40 | this._isLaidOut = false;
|
41 | this._hasTransform = false;
|
42 | this._hasPendingTransform = false;
|
43 | }
|
44 | requestLayout() {
|
45 | this._privateFlags |= PFLAG_FORCE_LAYOUT;
|
46 | super.requestLayout();
|
47 | const nativeView = this.nativeViewProtected;
|
48 | if (nativeView && nativeView.setNeedsLayout) {
|
49 | nativeView.setNeedsLayout();
|
50 | }
|
51 | if (this.viewController && this.viewController.view !== nativeView) {
|
52 | this.viewController.view.setNeedsLayout();
|
53 | }
|
54 | }
|
55 | measure(widthMeasureSpec, heightMeasureSpec) {
|
56 | const measureSpecsChanged = this._setCurrentMeasureSpecs(widthMeasureSpec, heightMeasureSpec);
|
57 | const forceLayout = (this._privateFlags & PFLAG_FORCE_LAYOUT) === PFLAG_FORCE_LAYOUT;
|
58 | if (this.nativeViewProtected && (forceLayout || measureSpecsChanged)) {
|
59 |
|
60 | this._privateFlags &= ~PFLAG_MEASURED_DIMENSION_SET;
|
61 |
|
62 | this.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
63 | this._privateFlags |= PFLAG_LAYOUT_REQUIRED;
|
64 |
|
65 |
|
66 | if ((this._privateFlags & PFLAG_MEASURED_DIMENSION_SET) !== PFLAG_MEASURED_DIMENSION_SET) {
|
67 | if (Trace.isEnabled()) {
|
68 | Trace.write('onMeasure() did not set the measured dimension by calling setMeasuredDimension() ' + this, Trace.categories.Layout, Trace.messageType.error);
|
69 | }
|
70 | }
|
71 | }
|
72 | }
|
73 | layout(left, top, right, bottom, setFrame = true) {
|
74 | const { boundsChanged, sizeChanged } = this._setCurrentLayoutBounds(left, top, right, bottom);
|
75 | if (setFrame) {
|
76 | this.layoutNativeView(left, top, right, bottom);
|
77 | }
|
78 | const needsLayout = boundsChanged || (this._privateFlags & PFLAG_LAYOUT_REQUIRED) === PFLAG_LAYOUT_REQUIRED;
|
79 | if (needsLayout) {
|
80 | let position = { left, top, right, bottom };
|
81 | if (this.nativeViewProtected && SDK_VERSION > 10) {
|
82 |
|
83 |
|
84 | const frame = this.nativeViewProtected.frame;
|
85 | position = IOSHelper.getPositionFromFrame(frame);
|
86 | }
|
87 | this.onLayout(position.left, position.top, position.right, position.bottom);
|
88 | this._privateFlags &= ~PFLAG_LAYOUT_REQUIRED;
|
89 | }
|
90 | this.updateBackground(sizeChanged, needsLayout);
|
91 | if (this._hasPendingTransform) {
|
92 | this.updateNativeTransform();
|
93 | this._hasPendingTransform = false;
|
94 | }
|
95 | this._privateFlags &= ~PFLAG_FORCE_LAYOUT;
|
96 | }
|
97 | updateBackground(sizeChanged, needsLayout) {
|
98 | if (sizeChanged) {
|
99 | this._onSizeChanged();
|
100 | }
|
101 | else if (this._nativeBackgroundState === 'invalid') {
|
102 | const background = this.style.backgroundInternal;
|
103 | this._redrawNativeBackground(background);
|
104 | }
|
105 | else {
|
106 |
|
107 | if (needsLayout) {
|
108 | this.layoutOuterShadows();
|
109 | }
|
110 | }
|
111 | }
|
112 | layoutOuterShadows() {
|
113 | const nativeView = this.nativeViewProtected;
|
114 | if (nativeView?.outerShadowContainerLayer) {
|
115 | CATransaction.setDisableActions(true);
|
116 | nativeView.outerShadowContainerLayer.bounds = nativeView.bounds;
|
117 | nativeView.outerShadowContainerLayer.position = nativeView.center;
|
118 | CATransaction.setDisableActions(false);
|
119 | }
|
120 | }
|
121 | setMeasuredDimension(measuredWidth, measuredHeight) {
|
122 | super.setMeasuredDimension(measuredWidth, measuredHeight);
|
123 | this._privateFlags |= PFLAG_MEASURED_DIMENSION_SET;
|
124 | }
|
125 | onMeasure(widthMeasureSpec, heightMeasureSpec) {
|
126 | const view = this.nativeViewProtected;
|
127 | const width = layout.getMeasureSpecSize(widthMeasureSpec);
|
128 | const widthMode = layout.getMeasureSpecMode(widthMeasureSpec);
|
129 | const height = layout.getMeasureSpecSize(heightMeasureSpec);
|
130 | const heightMode = layout.getMeasureSpecMode(heightMeasureSpec);
|
131 | let nativeWidth = 0;
|
132 | let nativeHeight = 0;
|
133 | if (view) {
|
134 | const nativeSize = layout.measureNativeView(view, width, widthMode, height, heightMode);
|
135 | nativeWidth = nativeSize.width;
|
136 | nativeHeight = nativeSize.height;
|
137 | }
|
138 | const measureWidth = Math.max(nativeWidth, this.effectiveMinWidth);
|
139 | const measureHeight = Math.max(nativeHeight, this.effectiveMinHeight);
|
140 | const widthAndState = View.resolveSizeAndState(measureWidth, width, widthMode, 0);
|
141 | const heightAndState = View.resolveSizeAndState(measureHeight, height, heightMode, 0);
|
142 | this.setMeasuredDimension(widthAndState, heightAndState);
|
143 | }
|
144 | onLayout(left, top, right, bottom) {
|
145 |
|
146 | }
|
147 | _setNativeViewFrame(nativeView, frame) {
|
148 | const oldFrame = this._cachedFrame || nativeView.frame;
|
149 | if (!CGRectEqualToRect(oldFrame, frame)) {
|
150 | if (Trace.isEnabled()) {
|
151 | Trace.write(this + ' :_setNativeViewFrame: ' + JSON.stringify(IOSHelper.getPositionFromFrame(frame)), Trace.categories.Layout);
|
152 | }
|
153 | this._cachedFrame = frame;
|
154 | let adjustedFrame = null;
|
155 | let transform = null;
|
156 | if (this._hasTransform) {
|
157 |
|
158 | transform = nativeView.layer.transform;
|
159 | nativeView.layer.transform = CATransform3DIdentity;
|
160 | nativeView.frame = frame;
|
161 | }
|
162 | else {
|
163 | nativeView.frame = frame;
|
164 | }
|
165 | adjustedFrame = this.applySafeAreaInsets(frame);
|
166 | if (adjustedFrame) {
|
167 | nativeView.frame = adjustedFrame;
|
168 | }
|
169 | if (this._hasTransform) {
|
170 |
|
171 | nativeView.layer.transform = transform;
|
172 | }
|
173 | const boundsOrigin = nativeView.bounds.origin;
|
174 | const boundsFrame = adjustedFrame || frame;
|
175 | nativeView.bounds = CGRectMake(boundsOrigin.x, boundsOrigin.y, boundsFrame.size.width, boundsFrame.size.height);
|
176 | nativeView.layoutIfNeeded();
|
177 | this._raiseLayoutChangedEvent();
|
178 | this._isLaidOut = true;
|
179 | }
|
180 | else if (!this._isLaidOut) {
|
181 |
|
182 | this._raiseLayoutChangedEvent();
|
183 |
|
184 |
|
185 | this._isLaidOut = true;
|
186 | }
|
187 | }
|
188 | get isLayoutValid() {
|
189 | if (this.nativeViewProtected) {
|
190 | return this._isLayoutValid;
|
191 | }
|
192 | return false;
|
193 | }
|
194 | layoutNativeView(left, top, right, bottom) {
|
195 | if (!this.nativeViewProtected) {
|
196 | return;
|
197 | }
|
198 | const nativeView = this.nativeViewProtected;
|
199 | const frame = IOSHelper.getFrameFromPosition({
|
200 | left,
|
201 | top,
|
202 | right,
|
203 | bottom,
|
204 | });
|
205 | this._setNativeViewFrame(nativeView, frame);
|
206 | }
|
207 | _layoutParent() {
|
208 | if (this.nativeViewProtected) {
|
209 | const frame = this.nativeViewProtected.frame;
|
210 | const origin = frame.origin;
|
211 | const size = frame.size;
|
212 | const left = layout.toDevicePixels(origin.x);
|
213 | const top = layout.toDevicePixels(origin.y);
|
214 | const width = layout.toDevicePixels(size.width);
|
215 | const height = layout.toDevicePixels(size.height);
|
216 | this._setLayoutFlags(left, top, width + left, height + top);
|
217 | }
|
218 | super._layoutParent();
|
219 | }
|
220 | _setLayoutFlags(left, top, right, bottom) {
|
221 | const width = right - left;
|
222 | const height = bottom - top;
|
223 | const widthSpec = layout.makeMeasureSpec(width, layout.EXACTLY);
|
224 | const heightSpec = layout.makeMeasureSpec(height, layout.EXACTLY);
|
225 | this._setCurrentMeasureSpecs(widthSpec, heightSpec);
|
226 | this._privateFlags &= ~PFLAG_FORCE_LAYOUT;
|
227 | this.setMeasuredDimension(width, height);
|
228 | const { boundsChanged, sizeChanged } = this._setCurrentLayoutBounds(left, top, right, bottom);
|
229 | this.updateBackground(sizeChanged, boundsChanged);
|
230 | this._privateFlags &= ~PFLAG_LAYOUT_REQUIRED;
|
231 | }
|
232 | focus() {
|
233 | if (this.ios) {
|
234 | return this.ios.becomeFirstResponder();
|
235 | }
|
236 | return false;
|
237 | }
|
238 | applySafeAreaInsets(frame) {
|
239 | if (!__VISIONOS__ && SDK_VERSION <= 10) {
|
240 | return null;
|
241 | }
|
242 | if (this.iosIgnoreSafeArea) {
|
243 | return frame;
|
244 | }
|
245 | if (!this.iosOverflowSafeArea || !this.iosOverflowSafeAreaEnabled) {
|
246 | return IOSHelper.shrinkToSafeArea(this, frame);
|
247 | }
|
248 | else if (this.nativeViewProtected && this.nativeViewProtected.window) {
|
249 | return IOSHelper.expandBeyondSafeArea(this, frame);
|
250 | }
|
251 | return null;
|
252 | }
|
253 | getSafeAreaInsets() {
|
254 | const safeAreaInsets = this.nativeViewProtected && this.nativeViewProtected.safeAreaInsets;
|
255 | const insets = { left: 0, top: 0, right: 0, bottom: 0 };
|
256 | if (this.iosIgnoreSafeArea) {
|
257 | return insets;
|
258 | }
|
259 | if (safeAreaInsets) {
|
260 | insets.left = layout.round(layout.toDevicePixels(safeAreaInsets.left));
|
261 | insets.top = layout.round(layout.toDevicePixels(safeAreaInsets.top));
|
262 | insets.right = layout.round(layout.toDevicePixels(safeAreaInsets.right));
|
263 | insets.bottom = layout.round(layout.toDevicePixels(safeAreaInsets.bottom));
|
264 | }
|
265 | return insets;
|
266 | }
|
267 | getLocationInWindow() {
|
268 | if (!this.nativeViewProtected || !this.nativeViewProtected.window) {
|
269 | return undefined;
|
270 | }
|
271 | const pointInWindow = this.nativeViewProtected.convertPointToView(this.nativeViewProtected.bounds.origin, null);
|
272 | return {
|
273 | x: pointInWindow.x,
|
274 | y: pointInWindow.y,
|
275 | };
|
276 | }
|
277 | getLocationOnScreen() {
|
278 | if (!this.nativeViewProtected || !this.nativeViewProtected.window) {
|
279 | return undefined;
|
280 | }
|
281 | const pointInWindow = this.nativeViewProtected.convertPointToView(this.nativeViewProtected.bounds.origin, null);
|
282 | const pointOnScreen = this.nativeViewProtected.window.convertPointToWindow(pointInWindow, null);
|
283 | return {
|
284 | x: pointOnScreen.x,
|
285 | y: pointOnScreen.y,
|
286 | };
|
287 | }
|
288 | getLocationRelativeTo(otherView) {
|
289 | if (!this.nativeViewProtected || !this.nativeViewProtected.window || !otherView.nativeViewProtected || !otherView.nativeViewProtected.window || this.nativeViewProtected.window !== otherView.nativeViewProtected.window) {
|
290 | return undefined;
|
291 | }
|
292 | const myPointInWindow = this.nativeViewProtected.convertPointToView(this.nativeViewProtected.bounds.origin, null);
|
293 | const otherPointInWindow = otherView.nativeViewProtected.convertPointToView(otherView.nativeViewProtected.bounds.origin, null);
|
294 | return {
|
295 | x: myPointInWindow.x - otherPointInWindow.x,
|
296 | y: myPointInWindow.y - otherPointInWindow.y,
|
297 | };
|
298 | }
|
299 | _onSizeChanged() {
|
300 | const nativeView = this.nativeViewProtected;
|
301 | if (!nativeView) {
|
302 | return;
|
303 | }
|
304 | const background = this.style.backgroundInternal;
|
305 | const backgroundDependsOnSize = (background.image && background.image !== 'none') || background.clipPath || !background.hasUniformBorder() || background.hasBorderRadius() || background.hasBoxShadow();
|
306 | if (this._nativeBackgroundState === 'invalid' || (this._nativeBackgroundState === 'drawn' && backgroundDependsOnSize)) {
|
307 | this._redrawNativeBackground(background);
|
308 | }
|
309 | }
|
310 | updateNativeTransform() {
|
311 | if (!this.isLayoutValid) {
|
312 | this._hasPendingTransform = true;
|
313 | return;
|
314 | }
|
315 | const scaleX = this.scaleX || 1e-6;
|
316 | const scaleY = this.scaleY || 1e-6;
|
317 | const perspective = this.perspective || 300;
|
318 | const nativeView = this.nativeViewProtected;
|
319 | let transform = new CATransform3D(CATransform3DIdentity);
|
320 |
|
321 | if (this.rotateX || this.rotateY) {
|
322 | transform.m34 = -1 / perspective;
|
323 | }
|
324 | transform = CATransform3DTranslate(transform, this.translateX, this.translateY, 0);
|
325 | transform = iosUtils.applyRotateTransform(transform, this.rotateX, this.rotateY, this.rotate);
|
326 | transform = CATransform3DScale(transform, scaleX, scaleY, 1);
|
327 | const needsTransform = !CATransform3DEqualToTransform(this.nativeViewProtected.layer.transform, transform) || (nativeView.outerShadowContainerLayer && !CATransform3DEqualToTransform(nativeView.outerShadowContainerLayer.transform, transform));
|
328 | if (needsTransform) {
|
329 | const updateSuspended = this._isPresentationLayerUpdateSuspended();
|
330 | if (!updateSuspended) {
|
331 | CATransaction.begin();
|
332 | }
|
333 |
|
334 | CATransaction.setDisableActions(true);
|
335 | this.nativeViewProtected.layer.transform = transform;
|
336 | if (nativeView.outerShadowContainerLayer) {
|
337 | nativeView.outerShadowContainerLayer.transform = transform;
|
338 | }
|
339 | this._hasTransform = this.nativeViewProtected && !CATransform3DEqualToTransform(this.nativeViewProtected.transform3D, CATransform3DIdentity);
|
340 | CATransaction.setDisableActions(false);
|
341 | if (!updateSuspended) {
|
342 | CATransaction.commit();
|
343 | }
|
344 | }
|
345 | }
|
346 | updateOriginPoint(originX, originY) {
|
347 | const nativeView = this.nativeViewProtected;
|
348 | const newPoint = CGPointMake(originX, originY);
|
349 |
|
350 | CATransaction.setDisableActions(true);
|
351 | nativeView.layer.anchorPoint = newPoint;
|
352 |
|
353 | if (this._cachedFrame) {
|
354 | const frame = this._cachedFrame;
|
355 | this._cachedFrame = null;
|
356 | this._setNativeViewFrame(nativeView, frame);
|
357 | }
|
358 |
|
359 | if (nativeView.outerShadowContainerLayer) {
|
360 |
|
361 | const frame = nativeView.frame;
|
362 | nativeView.outerShadowContainerLayer.anchorPoint = newPoint;
|
363 | nativeView.outerShadowContainerLayer.position = CGPointMake(frame.origin.x + frame.size.width * originX, frame.origin.y + frame.size.height * originY);
|
364 | }
|
365 | CATransaction.setDisableActions(false);
|
366 | }
|
367 |
|
368 |
|
369 |
|
370 | _suspendPresentationLayerUpdates() {
|
371 | this._suspendCATransaction = true;
|
372 | }
|
373 | _resumePresentationLayerUpdates() {
|
374 | this._suspendCATransaction = false;
|
375 | }
|
376 | _isPresentationLayerUpdateSuspended() {
|
377 | return this._suspendCATransaction || this._suspendNativeUpdatesCount > 0;
|
378 | }
|
379 | _showNativeModalView(parent, options) {
|
380 | const parentWithController = IOSHelper.getParentWithViewController(parent);
|
381 | if (!parentWithController) {
|
382 | Trace.write(`Could not find parent with viewController for ${parent} while showing modal view.`, Trace.categories.ViewHierarchy, Trace.messageType.error);
|
383 | return;
|
384 | }
|
385 | const parentController = parentWithController.viewController;
|
386 | if (parentController.presentedViewController) {
|
387 | Trace.write('Parent is already presenting view controller. Close the current modal page before showing another one!', Trace.categories.ViewHierarchy, Trace.messageType.error);
|
388 | return;
|
389 | }
|
390 | if (!parentController.view || !parentController.view.window) {
|
391 | Trace.write('Parent page is not part of the window hierarchy.', Trace.categories.ViewHierarchy, Trace.messageType.error);
|
392 | return;
|
393 | }
|
394 | this._setupAsRootView({});
|
395 | super._showNativeModalView(parentWithController, options);
|
396 | let controller = this.viewController;
|
397 | if (!controller) {
|
398 | const nativeView = this.ios || this.nativeViewProtected;
|
399 | controller = IOSHelper.UILayoutViewController.initWithOwner(new WeakRef(this));
|
400 | if (nativeView instanceof UIView) {
|
401 | controller.view.addSubview(nativeView);
|
402 | }
|
403 | this.viewController = controller;
|
404 | }
|
405 | if (options.transition) {
|
406 | controller.modalPresentationStyle = 4 ;
|
407 | if (options.transition.instance) {
|
408 | this._transitioningDelegate = UIViewControllerTransitioningDelegateImpl.initWithOwner(new WeakRef(options.transition.instance));
|
409 | controller.transitioningDelegate = this._transitioningDelegate;
|
410 | this.transitionId = options.transition.instance.id;
|
411 | const transitionState = SharedTransition.getState(options.transition.instance.id);
|
412 | if (transitionState?.interactive?.dismiss) {
|
413 |
|
414 |
|
415 |
|
416 | options.transition.instance.setupInteractiveGesture(this._closeModalCallback.bind(this), this);
|
417 | }
|
418 | }
|
419 | }
|
420 | else if (options.fullscreen) {
|
421 | controller.modalPresentationStyle = 0 ;
|
422 | }
|
423 | else {
|
424 | controller.modalPresentationStyle = 2 ;
|
425 |
|
426 |
|
427 | if (options.ios && options.ios.width > 0 && options.ios.height > 0) {
|
428 | controller.preferredContentSize = CGSizeMake(options.ios.width, options.ios.height);
|
429 | }
|
430 | else {
|
431 |
|
432 | const handler = () => {
|
433 | if (this.viewController) {
|
434 | const w = (this.width || this.style.width);
|
435 | const h = (this.height || this.style.height);
|
436 |
|
437 | if (w > 0 && h > 0) {
|
438 | this.viewController.preferredContentSize = CGSizeMake(w, h);
|
439 | }
|
440 | }
|
441 | this.off(View.loadedEvent, handler);
|
442 | };
|
443 | this.on(View.loadedEvent, handler);
|
444 | }
|
445 | }
|
446 | if (options.ios && options.ios.presentationStyle) {
|
447 | const presentationStyle = options.ios.presentationStyle;
|
448 | controller.modalPresentationStyle = presentationStyle;
|
449 | if (presentationStyle === 7 ) {
|
450 | this._setupPopoverControllerDelegate(controller, parent);
|
451 | }
|
452 | }
|
453 | const cancelable = options.cancelable !== undefined ? !!options.cancelable : true;
|
454 | if (SDK_VERSION >= 13) {
|
455 | if (cancelable) {
|
456 |
|
457 | this._setupAdaptiveControllerDelegate(controller);
|
458 | }
|
459 | else {
|
460 |
|
461 | controller.modalInPresentation = true;
|
462 | }
|
463 | }
|
464 | this.horizontalAlignment = 'stretch';
|
465 | this.verticalAlignment = 'stretch';
|
466 | this._raiseShowingModallyEvent();
|
467 | const animated = options.animated === undefined ? true : !!options.animated;
|
468 | if (!this._modalAnimatedOptions) {
|
469 |
|
470 | this._modalAnimatedOptions = [];
|
471 | }
|
472 | this._modalAnimatedOptions.push(animated);
|
473 |
|
474 |
|
475 |
|
476 |
|
477 |
|
478 |
|
479 | parentController.presentViewControllerAnimatedCompletion(controller, animated, null);
|
480 | const transitionCoordinator = parentController.transitionCoordinator;
|
481 | if (transitionCoordinator) {
|
482 | transitionCoordinator.animateAlongsideTransitionCompletion(null, () => {
|
483 | setTimeout(() => {
|
484 |
|
485 | this._raiseShownModallyEvent();
|
486 | });
|
487 | });
|
488 | }
|
489 | else {
|
490 |
|
491 |
|
492 |
|
493 | this._raiseShownModallyEvent();
|
494 | }
|
495 | controller = null;
|
496 | }
|
497 | _hideNativeModalView(parent, whenClosedCallback) {
|
498 | if (!parent || !parent.viewController) {
|
499 | Trace.error('Trying to hide modal view but no parent with viewController specified.');
|
500 | return;
|
501 | }
|
502 |
|
503 | if (!parent.viewController.presentedViewController) {
|
504 | whenClosedCallback();
|
505 | return;
|
506 | }
|
507 | const parentController = parent.viewController;
|
508 | let animated = true;
|
509 | if (this._modalAnimatedOptions?.length) {
|
510 | animated = this._modalAnimatedOptions.slice(-1)[0];
|
511 | }
|
512 | parentController.dismissViewControllerAnimatedCompletion(animated, () => {
|
513 | const transitionState = SharedTransition.getState(this.transitionId);
|
514 | if (!transitionState?.interactiveCancelled) {
|
515 | this._transitioningDelegate = null;
|
516 |
|
517 | if (this._modalAnimatedOptions) {
|
518 | this._modalAnimatedOptions.pop();
|
519 | }
|
520 | }
|
521 | whenClosedCallback();
|
522 | });
|
523 | }
|
524 | [isEnabledProperty.getDefault]() {
|
525 | const nativeView = this.nativeViewProtected;
|
526 | return nativeView instanceof UIControl ? nativeView.enabled : true;
|
527 | }
|
528 | [isEnabledProperty.setNative](value) {
|
529 | const nativeView = this.nativeViewProtected;
|
530 | if (nativeView instanceof UIControl) {
|
531 | nativeView.enabled = value;
|
532 | }
|
533 | }
|
534 | [originXProperty.getDefault]() {
|
535 | return this.nativeViewProtected.layer.anchorPoint.x;
|
536 | }
|
537 | [originXProperty.setNative](value) {
|
538 | this.updateOriginPoint(value, this.originY);
|
539 | }
|
540 | [originYProperty.getDefault]() {
|
541 | return this.nativeViewProtected.layer.anchorPoint.y;
|
542 | }
|
543 | [originYProperty.setNative](value) {
|
544 | this.updateOriginPoint(this.originX, value);
|
545 | }
|
546 | [testIDProperty.setNative](value) {
|
547 | this.setAccessibilityIdentifier(this.nativeViewProtected, value);
|
548 | }
|
549 | setAccessibilityIdentifier(view, value) {
|
550 | view.accessibilityIdentifier = value;
|
551 | if (this.testID && this.testID !== value)
|
552 | this.testID = value;
|
553 | if (this.accessibilityIdentifier !== value)
|
554 | this.accessibilityIdentifier = value;
|
555 | }
|
556 | [accessibilityEnabledProperty.setNative](value) {
|
557 | this.nativeViewProtected.isAccessibilityElement = !!value;
|
558 | if (value) {
|
559 | updateAccessibilityProperties(this);
|
560 | }
|
561 | }
|
562 | [accessibilityIdentifierProperty.getDefault]() {
|
563 | return this.nativeViewProtected.accessibilityIdentifier;
|
564 | }
|
565 | [accessibilityIdentifierProperty.setNative](value) {
|
566 | this.setAccessibilityIdentifier(this.nativeViewProtected, value);
|
567 | }
|
568 | [accessibilityRoleProperty.setNative](value) {
|
569 | this.accessibilityRole = value;
|
570 | updateAccessibilityProperties(this);
|
571 | }
|
572 | [accessibilityValueProperty.setNative](value) {
|
573 | value = value == null ? null : `${value}`;
|
574 | this.nativeViewProtected.accessibilityValue = value;
|
575 | }
|
576 | [accessibilityLabelProperty.setNative](value) {
|
577 | value = value == null ? null : `${value}`;
|
578 |
|
579 |
|
580 |
|
581 |
|
582 | this.nativeViewProtected.accessibilityLabel = value;
|
583 |
|
584 | }
|
585 | [accessibilityHintProperty.setNative](value) {
|
586 | value = value == null ? null : `${value}`;
|
587 | this.nativeViewProtected.accessibilityHint = value;
|
588 | }
|
589 | [accessibilityIgnoresInvertColorsProperty.setNative](value) {
|
590 | this.nativeViewProtected.accessibilityIgnoresInvertColors = !!value;
|
591 | }
|
592 | [accessibilityLanguageProperty.setNative](value) {
|
593 | value = value == null ? null : `${value}`;
|
594 | this.nativeViewProtected.accessibilityLanguage = value;
|
595 | }
|
596 | [accessibilityHiddenProperty.setNative](value) {
|
597 | this.nativeViewProtected.accessibilityElementsHidden = !!value;
|
598 | updateAccessibilityProperties(this);
|
599 | }
|
600 | [accessibilityLiveRegionProperty.setNative]() {
|
601 | updateAccessibilityProperties(this);
|
602 | }
|
603 | [accessibilityStateProperty.setNative](value) {
|
604 | this.accessibilityState = value;
|
605 | updateAccessibilityProperties(this);
|
606 | }
|
607 | [accessibilityMediaSessionProperty.setNative]() {
|
608 | updateAccessibilityProperties(this);
|
609 | }
|
610 | [isUserInteractionEnabledProperty.getDefault]() {
|
611 | return this.nativeViewProtected.userInteractionEnabled;
|
612 | }
|
613 | [isUserInteractionEnabledProperty.setNative](value) {
|
614 | this.nativeViewProtected.userInteractionEnabled = value;
|
615 | }
|
616 | [hiddenProperty.getDefault]() {
|
617 | return this.nativeViewProtected.hidden;
|
618 | }
|
619 | [hiddenProperty.setNative](value) {
|
620 | this.nativeViewProtected.hidden = value;
|
621 | }
|
622 | [visibilityProperty.getDefault]() {
|
623 | return this.nativeViewProtected.hidden ? CoreTypes.Visibility.collapse : CoreTypes.Visibility.visible;
|
624 | }
|
625 | [visibilityProperty.setNative](value) {
|
626 | const nativeView = this.nativeViewProtected;
|
627 | switch (value) {
|
628 | case CoreTypes.Visibility.visible:
|
629 | nativeView.hidden = false;
|
630 | break;
|
631 | case CoreTypes.Visibility.hidden:
|
632 | case CoreTypes.Visibility.collapse:
|
633 | nativeView.hidden = true;
|
634 | break;
|
635 | default:
|
636 | throw new Error(`Invalid visibility value: ${value}. Valid values are: "${CoreTypes.Visibility.visible}", "${CoreTypes.Visibility.hidden}", "${CoreTypes.Visibility.collapse}".`);
|
637 | }
|
638 |
|
639 | if (nativeView.outerShadowContainerLayer) {
|
640 | nativeView.outerShadowContainerLayer.hidden = nativeView.hidden;
|
641 | }
|
642 | }
|
643 | [opacityProperty.getDefault]() {
|
644 | return this.nativeViewProtected.alpha;
|
645 | }
|
646 | [opacityProperty.setNative](value) {
|
647 | const nativeView = this.nativeViewProtected;
|
648 | const updateSuspended = this._isPresentationLayerUpdateSuspended();
|
649 | if (!updateSuspended) {
|
650 | CATransaction.begin();
|
651 | }
|
652 |
|
653 | CATransaction.setDisableActions(true);
|
654 | nativeView.alpha = value;
|
655 |
|
656 | if (nativeView.outerShadowContainerLayer) {
|
657 | nativeView.outerShadowContainerLayer.opacity = value;
|
658 | }
|
659 | CATransaction.setDisableActions(false);
|
660 | if (!updateSuspended) {
|
661 | CATransaction.commit();
|
662 | }
|
663 | }
|
664 | [rotateProperty.getDefault]() {
|
665 | return 0;
|
666 | }
|
667 | [rotateProperty.setNative](value) {
|
668 | this.updateNativeTransform();
|
669 | }
|
670 | [rotateXProperty.getDefault]() {
|
671 | return 0;
|
672 | }
|
673 | [rotateXProperty.setNative](value) {
|
674 | this.updateNativeTransform();
|
675 | }
|
676 | [rotateYProperty.getDefault]() {
|
677 | return 0;
|
678 | }
|
679 | [rotateYProperty.setNative](value) {
|
680 | this.updateNativeTransform();
|
681 | }
|
682 | [perspectiveProperty.getDefault]() {
|
683 | return 300;
|
684 | }
|
685 | [perspectiveProperty.setNative](value) {
|
686 | this.updateNativeTransform();
|
687 | }
|
688 | [scaleXProperty.getDefault]() {
|
689 | return 1;
|
690 | }
|
691 | [scaleXProperty.setNative](value) {
|
692 | this.updateNativeTransform();
|
693 | }
|
694 | [scaleYProperty.getDefault]() {
|
695 | return 1;
|
696 | }
|
697 | [scaleYProperty.setNative](value) {
|
698 | this.updateNativeTransform();
|
699 | }
|
700 | [translateXProperty.getDefault]() {
|
701 | return 0;
|
702 | }
|
703 | [translateXProperty.setNative](value) {
|
704 | this.updateNativeTransform();
|
705 | }
|
706 | [translateYProperty.getDefault]() {
|
707 | return 0;
|
708 | }
|
709 | [translateYProperty.setNative](value) {
|
710 | this.updateNativeTransform();
|
711 | }
|
712 | [zIndexProperty.getDefault]() {
|
713 | return 0;
|
714 | }
|
715 | [zIndexProperty.setNative](value) {
|
716 | const nativeView = this.nativeViewProtected;
|
717 | nativeView.layer.zPosition = value;
|
718 |
|
719 | if (nativeView.outerShadowContainerLayer) {
|
720 | nativeView.outerShadowContainerLayer.zPosition = value;
|
721 | }
|
722 | }
|
723 | [backgroundInternalProperty.getDefault]() {
|
724 | return this.nativeViewProtected.backgroundColor;
|
725 | }
|
726 | [backgroundInternalProperty.setNative](value) {
|
727 | this._nativeBackgroundState = 'invalid';
|
728 | if (this.isLayoutValid) {
|
729 | this._redrawNativeBackground(value);
|
730 | }
|
731 | }
|
732 | sendAccessibilityEvent(options) {
|
733 | if (!isAccessibilityServiceEnabled()) {
|
734 | return;
|
735 | }
|
736 | if (!options.iosNotificationType) {
|
737 | return;
|
738 | }
|
739 | let notification;
|
740 | let args = this.nativeViewProtected;
|
741 | if (options?.message) {
|
742 | args = options.message;
|
743 | }
|
744 | switch (options.iosNotificationType) {
|
745 | case IOSPostAccessibilityNotificationType.Announcement: {
|
746 | notification = UIAccessibilityAnnouncementNotification;
|
747 | break;
|
748 | }
|
749 | case IOSPostAccessibilityNotificationType.Layout: {
|
750 | notification = UIAccessibilityLayoutChangedNotification;
|
751 | break;
|
752 | }
|
753 | case IOSPostAccessibilityNotificationType.Screen: {
|
754 | notification = UIAccessibilityScreenChangedNotification;
|
755 | break;
|
756 | }
|
757 | default: {
|
758 | return;
|
759 | }
|
760 | }
|
761 | UIAccessibilityPostNotification(notification, args ?? null);
|
762 | }
|
763 | accessibilityAnnouncement(msg = this.accessibilityLabel) {
|
764 | this.sendAccessibilityEvent({
|
765 | iosNotificationType: IOSPostAccessibilityNotificationType.Announcement,
|
766 | message: msg,
|
767 | });
|
768 | }
|
769 | accessibilityScreenChanged() {
|
770 | this.sendAccessibilityEvent({
|
771 | iosNotificationType: IOSPostAccessibilityNotificationType.Screen,
|
772 | });
|
773 | }
|
774 | _getCurrentLayoutBounds() {
|
775 | const nativeView = this.nativeViewProtected;
|
776 | if (nativeView && !this.isCollapsed) {
|
777 | const frame = nativeView.frame;
|
778 | const origin = frame.origin;
|
779 | const size = frame.size;
|
780 | return {
|
781 | left: Math.round(layout.toDevicePixels(origin.x)),
|
782 | top: Math.round(layout.toDevicePixels(origin.y)),
|
783 | right: Math.round(layout.toDevicePixels(origin.x + size.width)),
|
784 | bottom: Math.round(layout.toDevicePixels(origin.y + size.height)),
|
785 | };
|
786 | }
|
787 | else {
|
788 | return { left: 0, top: 0, right: 0, bottom: 0 };
|
789 | }
|
790 | }
|
791 | _redrawNativeBackground(value) {
|
792 | const updateSuspended = this._isPresentationLayerUpdateSuspended();
|
793 | if (!updateSuspended) {
|
794 | CATransaction.begin();
|
795 | }
|
796 |
|
797 | CATransaction.setDisableActions(true);
|
798 | const nativeView = this.nativeViewProtected;
|
799 | if (nativeView) {
|
800 | if (value instanceof UIColor) {
|
801 | nativeView.backgroundColor = value;
|
802 | }
|
803 | else {
|
804 | iosBackground.createBackgroundUIColor(this, (color) => {
|
805 | nativeView.backgroundColor = color;
|
806 | });
|
807 | this._setNativeClipToBounds();
|
808 | }
|
809 | }
|
810 | CATransaction.setDisableActions(false);
|
811 | if (!updateSuspended) {
|
812 | CATransaction.commit();
|
813 | }
|
814 | this._nativeBackgroundState = 'drawn';
|
815 | }
|
816 | _setNativeClipToBounds() {
|
817 | const view = this.nativeViewProtected;
|
818 | if (view) {
|
819 | const backgroundInternal = this.style.backgroundInternal;
|
820 | view.clipsToBounds = view instanceof UIScrollView || backgroundInternal.hasBorderWidth() || backgroundInternal.hasBorderRadius();
|
821 | }
|
822 | }
|
823 | _setupPopoverControllerDelegate(controller, parent) {
|
824 | const popoverPresentationController = controller.popoverPresentationController;
|
825 | this._popoverPresentationDelegate = IOSHelper.UIPopoverPresentationControllerDelegateImp.initWithOwnerAndCallback(new WeakRef(this), this._closeModalCallback);
|
826 | popoverPresentationController.delegate = this._popoverPresentationDelegate;
|
827 | let view;
|
828 | do {
|
829 | view = parent.nativeViewProtected;
|
830 | parent = parent.parent;
|
831 | } while (parent && !view);
|
832 |
|
833 |
|
834 | popoverPresentationController.sourceView = view;
|
835 | popoverPresentationController.sourceRect = CGRectMake(0, 0, view.frame.size.width, view.frame.size.height);
|
836 | }
|
837 | _setupAdaptiveControllerDelegate(controller) {
|
838 | this._adaptivePresentationDelegate = IOSHelper.UIAdaptivePresentationControllerDelegateImp.initWithOwnerAndCallback(new WeakRef(this), this._closeModalCallback);
|
839 | if (controller?.presentationController) {
|
840 | controller.presentationController.delegate = this._adaptivePresentationDelegate;
|
841 | }
|
842 | }
|
843 | }
|
844 | __decorate([
|
845 | profile,
|
846 | __metadata("design:type", Function),
|
847 | __metadata("design:paramtypes", [Number, Number, Number, Number, Object]),
|
848 | __metadata("design:returntype", void 0)
|
849 | ], View.prototype, "layout", null);
|
850 | __decorate([
|
851 | profile,
|
852 | __metadata("design:type", Function),
|
853 | __metadata("design:paramtypes", [Number, Number]),
|
854 | __metadata("design:returntype", void 0)
|
855 | ], View.prototype, "onMeasure", null);
|
856 | View.prototype._nativeBackgroundState = 'unset';
|
857 | var UIViewControllerTransitioningDelegateImpl = (function (_super) {
|
858 | __extends(UIViewControllerTransitioningDelegateImpl, _super);
|
859 | function UIViewControllerTransitioningDelegateImpl() {
|
860 | return _super !== null && _super.apply(this, arguments) || this;
|
861 | }
|
862 | UIViewControllerTransitioningDelegateImpl.initWithOwner = function (owner) {
|
863 | var delegate = UIViewControllerTransitioningDelegateImpl.new();
|
864 | delegate.owner = owner;
|
865 | return delegate;
|
866 | };
|
867 | UIViewControllerTransitioningDelegateImpl.prototype.animationControllerForDismissedController = function (dismissed) {
|
868 | var _a;
|
869 | var owner = (_a = this.owner) === null || _a === void 0 ? void 0 : _a.deref();
|
870 | if (owner === null || owner === void 0 ? void 0 : owner.iosDismissedController) {
|
871 | return owner.iosDismissedController(dismissed);
|
872 | }
|
873 | return null;
|
874 | };
|
875 | UIViewControllerTransitioningDelegateImpl.prototype.animationControllerForPresentedControllerPresentingControllerSourceController = function (presented, presenting, source) {
|
876 | var _a;
|
877 | var owner = (_a = this.owner) === null || _a === void 0 ? void 0 : _a.deref();
|
878 | if (owner === null || owner === void 0 ? void 0 : owner.iosPresentedController) {
|
879 | return owner.iosPresentedController(presented, presenting, source);
|
880 | }
|
881 | return null;
|
882 | };
|
883 | UIViewControllerTransitioningDelegateImpl.prototype.interactionControllerForDismissal = function (animator) {
|
884 | var _a;
|
885 | var owner = (_a = this.owner) === null || _a === void 0 ? void 0 : _a.deref();
|
886 | if (owner === null || owner === void 0 ? void 0 : owner.iosInteractionDismiss) {
|
887 | var transitionState = SharedTransition.getState(owner.id);
|
888 | if (transitionState === null || transitionState === void 0 ? void 0 : transitionState.interactiveBegan) {
|
889 | return owner.iosInteractionDismiss(animator);
|
890 | }
|
891 | }
|
892 | return null;
|
893 | };
|
894 | UIViewControllerTransitioningDelegateImpl.prototype.interactionControllerForPresentation = function (animator) {
|
895 | var _a;
|
896 | var owner = (_a = this.owner) === null || _a === void 0 ? void 0 : _a.deref();
|
897 | if (owner === null || owner === void 0 ? void 0 : owner.iosInteractionPresented) {
|
898 | return owner.iosInteractionPresented(animator);
|
899 | }
|
900 | return null;
|
901 | };
|
902 | UIViewControllerTransitioningDelegateImpl.ObjCProtocols = [UIViewControllerTransitioningDelegate];
|
903 | return UIViewControllerTransitioningDelegateImpl;
|
904 | }(NSObject));
|
905 | export class ContainerView extends View {
|
906 | constructor() {
|
907 | super();
|
908 | this.iosOverflowSafeArea = true;
|
909 | }
|
910 | }
|
911 | export class CustomLayoutView extends ContainerView {
|
912 | createNativeView() {
|
913 | const window = iosUtils.getWindow();
|
914 | return UIView.alloc().initWithFrame(window ? window.screen.bounds : UIScreen.mainScreen.bounds);
|
915 | }
|
916 | get ios() {
|
917 | return this.nativeViewProtected;
|
918 | }
|
919 | onMeasure(widthMeasureSpec, heightMeasureSpec) {
|
920 |
|
921 | }
|
922 | _addViewToNativeVisualTree(child, atIndex) {
|
923 | super._addViewToNativeVisualTree(child, atIndex);
|
924 | const parentNativeView = this.nativeViewProtected;
|
925 | const childNativeView = child.nativeViewProtected;
|
926 | if (parentNativeView && childNativeView) {
|
927 | if (typeof atIndex !== 'number' || atIndex >= parentNativeView.subviews.count) {
|
928 | parentNativeView.addSubview(childNativeView);
|
929 | }
|
930 | else {
|
931 | parentNativeView.insertSubviewAtIndex(childNativeView, atIndex);
|
932 | }
|
933 |
|
934 | if (childNativeView.outerShadowContainerLayer && !childNativeView.outerShadowContainerLayer.superlayer) {
|
935 | parentNativeView.layer.insertSublayerBelow(childNativeView.outerShadowContainerLayer, childNativeView.layer);
|
936 | }
|
937 | return true;
|
938 | }
|
939 | return false;
|
940 | }
|
941 | _removeViewFromNativeVisualTree(child) {
|
942 | super._removeViewFromNativeVisualTree(child);
|
943 | if (child.nativeViewProtected) {
|
944 | const nativeView = child.nativeViewProtected;
|
945 |
|
946 | if (nativeView.outerShadowContainerLayer) {
|
947 | nativeView.outerShadowContainerLayer.removeFromSuperlayer();
|
948 | }
|
949 | nativeView.removeFromSuperview();
|
950 | }
|
951 | }
|
952 | }
|
953 |
|
\ | No newline at end of file |