mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-11-05 13:26:48 +08:00
Merge remote-tracking branch 'origin/refactor/circular-deps' into feat/list-view-sticky-headers
This commit is contained in:
@@ -303,6 +303,9 @@ export class ActionBar extends ActionBarBase {
|
||||
navigationItem.accessibilityLabel = this.accessibilityLabel;
|
||||
navigationItem.accessibilityLanguage = this.accessibilityLanguage;
|
||||
navigationItem.accessibilityHint = this.accessibilityHint;
|
||||
|
||||
// Configure large title support for this navigation item
|
||||
this.checkLargeTitleSupport(navigationItem);
|
||||
}
|
||||
|
||||
private populateMenuItems(navigationItem: UINavigationItem) {
|
||||
@@ -506,6 +509,8 @@ export class ActionBar extends ActionBarBase {
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('ActionBar._onTitlePropertyChanged', this.title);
|
||||
|
||||
if (page.frame) {
|
||||
page.frame._updateActionBar(page);
|
||||
}
|
||||
@@ -669,4 +674,26 @@ export class ActionBar extends ActionBarBase {
|
||||
this.navBar.prefersLargeTitles = value;
|
||||
}
|
||||
}
|
||||
|
||||
private checkLargeTitleSupport(navigationItem: UINavigationItem) {
|
||||
const navBar = this.navBar;
|
||||
if (!navBar) {
|
||||
return;
|
||||
}
|
||||
// Configure large title display mode only when not using a custom titleView
|
||||
if (SDK_VERSION >= 11) {
|
||||
if (this.iosLargeTitle) {
|
||||
// Always show large title for this navigation item when large titles are enabled
|
||||
navigationItem.largeTitleDisplayMode = UINavigationItemLargeTitleDisplayMode.Always;
|
||||
} else {
|
||||
if (SDK_VERSION >= 26) {
|
||||
// Explicitly disable large titles for this navigation item
|
||||
// Due to overlapping title issue in iOS 26
|
||||
navigationItem.largeTitleDisplayMode = UINavigationItemLargeTitleDisplayMode.Never;
|
||||
} else {
|
||||
navigationItem.largeTitleDisplayMode = UINavigationItemLargeTitleDisplayMode.Automatic;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import type { Point, Position } from './view-interfaces';
|
||||
import { ViewCommon, isEnabledProperty, originXProperty, originYProperty, isUserInteractionEnabledProperty, testIDProperty } from './view-common';
|
||||
import { ViewCommon, isEnabledProperty, originXProperty, originYProperty, isUserInteractionEnabledProperty, testIDProperty, iosGlassEffectProperty, GlassEffectType, GlassEffectVariant } from './view-common';
|
||||
import { isAccessibilityServiceEnabled } from '../../../application';
|
||||
import { updateA11yPropertiesCallback } from '../../../application/helpers-common';
|
||||
import { ShowModalOptions, hiddenProperty } from '../view-base';
|
||||
import { Trace } from '../../../trace';
|
||||
import { layout, ios as iosUtils, SDK_VERSION, getWindow } from '../../../utils';
|
||||
import { layout, ios as iosUtils, getWindow } from '../../../utils';
|
||||
import { SDK_VERSION, supportsGlass } from '../../../utils/constants';
|
||||
import { IOSHelper } from './view-helper';
|
||||
import { ios as iosBackground, Background } from '../../styling/background';
|
||||
import { perspectiveProperty, visibilityProperty, opacityProperty, rotateProperty, rotateXProperty, rotateYProperty, scaleXProperty, scaleYProperty, translateXProperty, translateYProperty, zIndexProperty, backgroundInternalProperty } from '../../styling/style-properties';
|
||||
@@ -15,6 +16,7 @@ import { CoreTypes } from '../../../core-types';
|
||||
import type { ModalTransition } from '../../transition/modal-transition';
|
||||
import { SharedTransition } from '../../transition/shared-transition';
|
||||
import { NativeScriptUIView } from '../../utils';
|
||||
import { Color } from '../../../color';
|
||||
|
||||
export * from './view-common';
|
||||
export * from './view-helper';
|
||||
@@ -51,6 +53,12 @@ export class View extends ViewCommon {
|
||||
*/
|
||||
_nativeBackgroundState: 'unset' | 'invalid' | 'drawn';
|
||||
|
||||
/**
|
||||
* Glass effect configuration
|
||||
*/
|
||||
private _glassEffectView: UIVisualEffectView;
|
||||
private _glassEffectMeasure: NodeJS.Timeout;
|
||||
|
||||
get isLayoutRequired(): boolean {
|
||||
return (this._privateFlags & PFLAG_LAYOUT_REQUIRED) === PFLAG_LAYOUT_REQUIRED;
|
||||
}
|
||||
@@ -887,6 +895,60 @@ export class View extends ViewCommon {
|
||||
}
|
||||
}
|
||||
|
||||
[iosGlassEffectProperty.setNative](value: GlassEffectType) {
|
||||
if (!this.nativeViewProtected || !supportsGlass()) {
|
||||
return;
|
||||
}
|
||||
if (this._glassEffectView) {
|
||||
this._glassEffectView.removeFromSuperview();
|
||||
this._glassEffectView = null;
|
||||
}
|
||||
if (!value) {
|
||||
return;
|
||||
}
|
||||
let effect: UIGlassEffect;
|
||||
if (typeof value === 'string') {
|
||||
effect = UIGlassEffect.effectWithStyle(this.toUIGlassStyle(value));
|
||||
} else {
|
||||
if (value.variant === 'identity') {
|
||||
return;
|
||||
}
|
||||
effect = UIGlassEffect.effectWithStyle(this.toUIGlassStyle(value.variant));
|
||||
if (value.interactive) {
|
||||
effect.interactive = true;
|
||||
}
|
||||
if (value.tint) {
|
||||
effect.tintColor = typeof value.tint === 'string' ? new Color(value.tint).ios : value.tint;
|
||||
}
|
||||
}
|
||||
this._glassEffectView = UIVisualEffectView.alloc().initWithEffect(effect);
|
||||
// let touches pass to content
|
||||
this._glassEffectView.userInteractionEnabled = false;
|
||||
this._glassEffectView.clipsToBounds = true;
|
||||
// size & autoresize
|
||||
if (this._glassEffectMeasure) {
|
||||
clearTimeout(this._glassEffectMeasure);
|
||||
}
|
||||
this._glassEffectMeasure = setTimeout(() => {
|
||||
const size = this.nativeViewProtected.bounds.size;
|
||||
this._glassEffectView.frame = CGRectMake(0, 0, size.width, size.height);
|
||||
this._glassEffectView.autoresizingMask = 2;
|
||||
this.nativeViewProtected.insertSubviewAtIndex(this._glassEffectView, 0);
|
||||
});
|
||||
}
|
||||
|
||||
public toUIGlassStyle(value?: GlassEffectVariant) {
|
||||
if (supportsGlass()) {
|
||||
switch (value) {
|
||||
case 'regular':
|
||||
return UIGlassEffectStyle?.Regular ?? 0;
|
||||
case 'clear':
|
||||
return UIGlassEffectStyle?.Clear ?? 1;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
public sendAccessibilityEvent(options: Partial<AccessibilityEventOptions>): void {
|
||||
if (!isAccessibilityServiceEnabled()) {
|
||||
return;
|
||||
|
||||
@@ -1288,6 +1288,7 @@ export const isUserInteractionEnabledProperty = new Property<ViewCommon, boolean
|
||||
});
|
||||
isUserInteractionEnabledProperty.register(ViewCommon);
|
||||
|
||||
// Apple only
|
||||
export const iosOverflowSafeAreaProperty = new Property<ViewCommon, boolean>({
|
||||
name: 'iosOverflowSafeArea',
|
||||
defaultValue: false,
|
||||
@@ -1308,6 +1309,17 @@ export const iosIgnoreSafeAreaProperty = new InheritedProperty({
|
||||
});
|
||||
iosIgnoreSafeAreaProperty.register(ViewCommon);
|
||||
|
||||
/**
|
||||
* Glass effects
|
||||
*/
|
||||
export type GlassEffectVariant = 'regular' | 'clear' | 'identity';
|
||||
export type GlassEffectConfig = { variant?: GlassEffectVariant; interactive?: boolean; tint: string | Color };
|
||||
export type GlassEffectType = GlassEffectVariant | GlassEffectConfig;
|
||||
export const iosGlassEffectProperty = new Property<ViewCommon, GlassEffectType>({
|
||||
name: 'iosGlassEffect',
|
||||
});
|
||||
iosGlassEffectProperty.register(ViewCommon);
|
||||
|
||||
export const visionHoverStyleProperty = new Property<ViewCommon, string | VisionHoverOptions>({
|
||||
name: 'visionHoverStyle',
|
||||
valueChanged(view, oldValue, newValue) {
|
||||
@@ -1324,6 +1336,7 @@ const visionIgnoreHoverStyleProperty = new Property<ViewCommon, boolean>({
|
||||
valueConverter: booleanConverter,
|
||||
});
|
||||
visionIgnoreHoverStyleProperty.register(ViewCommon);
|
||||
// Apple only end
|
||||
|
||||
const touchAnimationProperty = new Property<ViewCommon, boolean | TouchAnimationOptions>({
|
||||
name: 'touchAnimation',
|
||||
|
||||
@@ -9,15 +9,6 @@ export enum NavigationType {
|
||||
replace,
|
||||
}
|
||||
|
||||
export interface TransitionState {
|
||||
enterTransitionListener: any;
|
||||
exitTransitionListener: any;
|
||||
reenterTransitionListener: any;
|
||||
returnTransitionListener: any;
|
||||
transitionName: string;
|
||||
entry: BackstackEntry;
|
||||
}
|
||||
|
||||
export interface ViewEntry {
|
||||
moduleName?: string;
|
||||
create?: () => View;
|
||||
@@ -34,6 +25,17 @@ export interface NavigationEntry extends ViewEntry {
|
||||
clearHistory?: boolean;
|
||||
}
|
||||
|
||||
export interface BackstackEntry {
|
||||
entry: NavigationEntry;
|
||||
resolvedPage: Page;
|
||||
navDepth: number;
|
||||
fragmentTag: string;
|
||||
fragment?: any;
|
||||
viewSavedState?: any;
|
||||
frameId?: number;
|
||||
recreated?: boolean;
|
||||
}
|
||||
|
||||
export interface NavigationContext {
|
||||
entry?: BackstackEntry;
|
||||
/**
|
||||
@@ -91,6 +93,15 @@ export interface NavigationData extends EventData {
|
||||
isBack?: boolean;
|
||||
}
|
||||
|
||||
export interface TransitionState {
|
||||
enterTransitionListener: any;
|
||||
exitTransitionListener: any;
|
||||
reenterTransitionListener: any;
|
||||
returnTransitionListener: any;
|
||||
transitionName: string;
|
||||
entry: BackstackEntry;
|
||||
}
|
||||
|
||||
export interface AndroidFrame extends Observable {
|
||||
rootViewGroup: any /* android.view.ViewGroup */;
|
||||
activity: any /* androidx.appcompat.app.AppCompatActivity */;
|
||||
|
||||
@@ -16,7 +16,7 @@ export { ControlStateChangeListener } from './core/control-state-change';
|
||||
export { ViewBase, eachDescendant, getAncestor, getViewById, booleanConverter, querySelectorAll } from './core/view-base';
|
||||
export type { ShowModalOptions } from './core/view-base';
|
||||
export { View, CSSType, ContainerView, ViewHelper, AndroidHelper, IOSHelper, isUserInteractionEnabledProperty, PseudoClassHandler, CustomLayoutView } from './core/view';
|
||||
export type { Template, KeyedTemplate, AddArrayFromBuilder, AddChildFromBuilder } from './core/view';
|
||||
export type { Template, KeyedTemplate, AddArrayFromBuilder, AddChildFromBuilder, GlassEffectConfig, GlassEffectType, GlassEffectVariant } from './core/view';
|
||||
export type { ShownModallyData, Size } from './core/view/view-interfaces';
|
||||
export { Property, CoercibleProperty, InheritedProperty, CssProperty, InheritedCssProperty, ShorthandProperty, CssAnimationProperty, makeParser, makeValidator } from './core/properties';
|
||||
export { unsetValue } from './core/properties/property-shared';
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { SwitchBase, checkedProperty, offBackgroundColorProperty } from './switch-common';
|
||||
import { colorProperty, backgroundColorProperty, backgroundInternalProperty } from '../styling/style-properties';
|
||||
import { Color } from '../../color';
|
||||
import { layout } from '../../utils';
|
||||
import { SDK_VERSION } from '../../utils/constants';
|
||||
|
||||
export * from './switch-common';
|
||||
@@ -29,15 +28,12 @@ class SwitchChangeHandlerImpl extends NSObject {
|
||||
};
|
||||
}
|
||||
|
||||
const zeroSize = { width: 0, height: 0 };
|
||||
export class Switch extends SwitchBase {
|
||||
nativeViewProtected: UISwitch;
|
||||
private _handler: NSObject;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.width = 51;
|
||||
this.height = 31;
|
||||
}
|
||||
|
||||
public createNativeView() {
|
||||
@@ -92,17 +88,6 @@ export class Switch extends SwitchBase {
|
||||
return this.nativeViewProtected;
|
||||
}
|
||||
|
||||
public onMeasure(widthMeasureSpec: number, heightMeasureSpec: number): void {
|
||||
// It can't be anything different from 51x31
|
||||
const nativeSize = this.nativeViewProtected.sizeThatFits(zeroSize);
|
||||
this.width = nativeSize.width;
|
||||
this.height = nativeSize.height;
|
||||
|
||||
const widthAndState = Switch.resolveSizeAndState(layout.toDevicePixels(nativeSize.width), layout.toDevicePixels(51), layout.EXACTLY, 0);
|
||||
const heightAndState = Switch.resolveSizeAndState(layout.toDevicePixels(nativeSize.height), layout.toDevicePixels(31), layout.EXACTLY, 0);
|
||||
this.setMeasuredDimension(widthAndState, heightAndState);
|
||||
}
|
||||
|
||||
[checkedProperty.getDefault](): boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user