mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-11-05 13:26:48 +08:00
feat: glass effects containers
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
import { Observable, EventData, Page, CoreTypes, GlassEffectConfig } from '@nativescript/core';
|
import { Observable, EventData, Page, CoreTypes, GlassEffectConfig, View, GlassEffectType, TouchAnimationOptions, Label, Image } from '@nativescript/core';
|
||||||
|
|
||||||
let page: Page;
|
let page: Page;
|
||||||
|
|
||||||
@@ -7,10 +7,154 @@ export function navigatingTo(args: EventData) {
|
|||||||
page.bindingContext = new GlassEffectModel();
|
page.bindingContext = new GlassEffectModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const originalTransform = Symbol('originalTransform');
|
||||||
|
|
||||||
export class GlassEffectModel extends Observable {
|
export class GlassEffectModel extends Observable {
|
||||||
iosGlassEffectInteractive: GlassEffectConfig = {
|
iosGlassEffectInteractive: GlassEffectConfig = {
|
||||||
interactive: true,
|
interactive: true,
|
||||||
tint: '#faabab',
|
tint: '#faabab',
|
||||||
variant: 'clear',
|
variant: 'clear',
|
||||||
};
|
};
|
||||||
|
currentEffect: GlassEffectConfig = {
|
||||||
|
variant: 'none',
|
||||||
|
interactive: false,
|
||||||
|
// tint: '#ccc',
|
||||||
|
};
|
||||||
|
|
||||||
|
toggleGlassEffect(args) {
|
||||||
|
const btn = args.object as View;
|
||||||
|
this.currentEffect =
|
||||||
|
this.currentEffect.variant === 'none'
|
||||||
|
? {
|
||||||
|
variant: 'clear',
|
||||||
|
interactive: true,
|
||||||
|
// tint: '#faabab',
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
variant: 'none',
|
||||||
|
interactive: false,
|
||||||
|
// tint: '#ccc',
|
||||||
|
};
|
||||||
|
btn.iosGlassEffect = this.currentEffect;
|
||||||
|
}
|
||||||
|
|
||||||
|
images = ['res://bg1.jpg', 'res://bg2.jpg', 'res://bg3.jpg'];
|
||||||
|
currentImage = this.images[0];
|
||||||
|
cycleImage() {
|
||||||
|
if (!this.image) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let currentIndex = this.images.indexOf(this.currentImage);
|
||||||
|
currentIndex++;
|
||||||
|
if (currentIndex === this.images.length) {
|
||||||
|
currentIndex = 0;
|
||||||
|
}
|
||||||
|
this.currentImage = this.images[currentIndex];
|
||||||
|
// this.notifyPropertyChange('currentImage', this.currentImage);
|
||||||
|
this.image.animate({ opacity: 0, duration: 300, curve: CoreTypes.AnimationCurve.easeInOut }).then(() => {
|
||||||
|
this.image.src = this.currentImage;
|
||||||
|
setTimeout(() => {
|
||||||
|
this.image.animate({ opacity: 1, duration: 800, curve: CoreTypes.AnimationCurve.easeInOut });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
image: Image;
|
||||||
|
loadedImage(args) {
|
||||||
|
this.image = args.object as Image;
|
||||||
|
}
|
||||||
|
|
||||||
|
glassMerged = false;
|
||||||
|
glassTargets = {};
|
||||||
|
loadedGlass(args) {
|
||||||
|
const glass = args.object as View;
|
||||||
|
switch (glass.id) {
|
||||||
|
case 'glass1':
|
||||||
|
glass.translateX = -40;
|
||||||
|
break;
|
||||||
|
case 'glass2':
|
||||||
|
glass.translateX = 40;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
this.glassTargets[glass.id] = glass;
|
||||||
|
}
|
||||||
|
|
||||||
|
glassTargetLabels: { [key: string]: Label } = {};
|
||||||
|
loadedGlassLabels(args) {
|
||||||
|
const label = args.object as Label;
|
||||||
|
this.glassTargetLabels[label.id] = label;
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleMergeGlass() {
|
||||||
|
if (!this.glassTargets['glass1'] || !this.glassTargets['glass2']) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.glassMerged = !this.glassMerged;
|
||||||
|
const glass1 = this.glassTargets['glass1'];
|
||||||
|
const glass2 = this.glassTargets['glass2'];
|
||||||
|
glass1.animate({ translate: { x: this.glassMerged ? -40 : 0, y: 0 }, duration: 300, curve: CoreTypes.AnimationCurve.easeInOut }).catch(() => {});
|
||||||
|
glass2.animate({ translate: { x: this.glassMerged ? 40 : 0, y: 0 }, duration: 300, curve: CoreTypes.AnimationCurve.easeInOut }).catch(() => {});
|
||||||
|
|
||||||
|
this.glassTargetLabels['share'].animate({ opacity: this.glassMerged ? 1 : 0, duration: 300, curve: CoreTypes.AnimationCurve.easeInOut }).catch(() => {});
|
||||||
|
|
||||||
|
this.glassTargetLabels['like'].text = this.glassMerged ? 'Done' : 'Like';
|
||||||
|
}
|
||||||
|
|
||||||
|
touchAnimation: TouchAnimationOptions = {
|
||||||
|
down: (view: View) => {
|
||||||
|
if (__APPLE__) {
|
||||||
|
UIView.animateWithDurationDelayUsingSpringWithDampingInitialSpringVelocityOptionsAnimationsCompletion(
|
||||||
|
0.3,
|
||||||
|
0,
|
||||||
|
0.5,
|
||||||
|
3,
|
||||||
|
UIViewAnimationOptions.CurveEaseInOut | UIViewAnimationOptions.AllowUserInteraction,
|
||||||
|
() => {
|
||||||
|
if (view?.ios) {
|
||||||
|
view[originalTransform] = view[originalTransform] ?? view.ios.transform;
|
||||||
|
|
||||||
|
view.ios.transform = CGAffineTransformConcat(view[originalTransform], CGAffineTransformMakeScale(0.97, 0.97));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
null,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
view
|
||||||
|
?.animate({
|
||||||
|
scale: { x: 0.97, y: 0.97 },
|
||||||
|
duration: 120,
|
||||||
|
curve: CoreTypes.AnimationCurve.easeInOut,
|
||||||
|
})
|
||||||
|
.then(() => {})
|
||||||
|
.catch(() => {});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
up: (view: View) => {
|
||||||
|
if (__APPLE__) {
|
||||||
|
UIView.animateWithDurationDelayUsingSpringWithDampingInitialSpringVelocityOptionsAnimationsCompletion(
|
||||||
|
0.3,
|
||||||
|
0,
|
||||||
|
0.5,
|
||||||
|
3,
|
||||||
|
UIViewAnimationOptions.CurveEaseInOut | UIViewAnimationOptions.AllowUserInteraction,
|
||||||
|
() => {
|
||||||
|
if (view?.ios) {
|
||||||
|
view.ios.transform = view[originalTransform] ?? CGAffineTransformMakeScale(1, 1);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
null,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
view
|
||||||
|
?.animate({
|
||||||
|
scale: { x: 1, y: 1 },
|
||||||
|
duration: 120,
|
||||||
|
curve: CoreTypes.AnimationCurve.easeInOut,
|
||||||
|
})
|
||||||
|
.then(() => {})
|
||||||
|
.catch(() => {});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,27 +1,55 @@
|
|||||||
<Page xmlns="http://schemas.nativescript.org/tns.xsd" navigatingTo="navigatingTo" class="page">
|
<Page xmlns="http://schemas.nativescript.org/tns.xsd" navigatingTo="navigatingTo" class="page">
|
||||||
<Page.actionBar>
|
<Page.actionBar>
|
||||||
<ActionBar title="Glass Effects" class="action-bar">
|
<ActionBar title="Glass Effects" color="white">
|
||||||
</ActionBar>
|
</ActionBar>
|
||||||
</Page.actionBar>
|
</Page.actionBar>
|
||||||
|
|
||||||
<GridLayout>
|
|
||||||
|
|
||||||
<Image src="https://cdn.wallpapersafari.com/89/64/c6MnRY.jpg" stretch="aspectFill" iosOverflowSafeArea="true" />
|
|
||||||
|
|
||||||
<GridLayout rows="*,auto,auto,auto,*">
|
<GridLayout backgroundColor="#000">
|
||||||
|
|
||||||
<GridLayout row="1" width="300" height="150" iosGlassEffect="regular" horizontalAlignment="center" verticalAlignment="middle">
|
<!-- <Image src="https://wallpapers.com/images/hd/yosemite-iphone-1440-x-2560-9t7u3ctc1hmq35p4.jpg" stretch="aspectFill" iosOverflowSafeArea="true" /> -->
|
||||||
|
<Image src="res://bg1.jpg" stretch="aspectFill" iosOverflowSafeArea="true" loaded="{{loadedImage}}" />
|
||||||
|
<!-- <ContentView backgroundColor="#000" height="300" verticalAlignment="bottom"/> -->
|
||||||
|
|
||||||
|
<ScrollView >
|
||||||
|
<StackLayout>
|
||||||
|
<GridLayout height="400" tap="{{cycleImage}}"/>
|
||||||
|
<GridLayout rows="*,auto,auto,auto,auto,auto,*">
|
||||||
|
|
||||||
|
<Button row="2" text="Toggle Glass" tap="{{toggleGlassEffect}}" horizontalAlignment="center" verticalAlignment="middle" class="c-white font-weight-bold m-y-20 p-4" fontSize="22" borderRadius="32" width="300" height="100" touchAnimation="{{touchAnimation}}" iosGlassEffect="{{currentEffect}}"/>
|
||||||
|
|
||||||
|
<LiquidGlass row="3" width="300" height="100" borderRadius="32">
|
||||||
|
<Label text="Glass Interactive" fontSize="22" class="p-4 font-weight-bold text-center" />
|
||||||
|
</LiquidGlass>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
<LiquidGlassContainer row="4" tap="{{toggleMergeGlass}}" horizontalAlignment="center" verticalAlignment="middle" class="m-t-20" width="300" height="100">
|
||||||
|
<LiquidGlass id="glass1" loaded="{{loadedGlass}}" borderRadius="50" width="100" height="100">
|
||||||
|
<Label id="share" text="Share" fontSize="22" class="font-weight-bold text-center" width="100" height="100" loaded="{{loadedGlassLabels}}" />
|
||||||
|
</LiquidGlass>
|
||||||
|
<LiquidGlass id="glass2" loaded="{{loadedGlass}}" borderRadius="50" width="100" height="100">
|
||||||
|
<Label id="like" text="Like" fontSize="22" class="font-weight-bold text-center" loaded="{{loadedGlassLabels}}" />
|
||||||
|
</LiquidGlass>
|
||||||
|
</LiquidGlassContainer> -->
|
||||||
|
|
||||||
|
|
||||||
|
<!-- <GridLayout row="1" width="300" height="150" iosGlassEffect="regular" horizontalAlignment="center" verticalAlignment="middle">
|
||||||
<Label class="text-center c-white" fontWeight="bold" fontSize="18" text="Glass Effects Regular" />
|
<Label class="text-center c-white" fontWeight="bold" fontSize="18" text="Glass Effects Regular" />
|
||||||
</GridLayout>
|
</GridLayout> -->
|
||||||
|
|
||||||
<GridLayout row="2" width="300" height="150" iosGlassEffect="clear" horizontalAlignment="center" verticalAlignment="middle" class="m-t-10">
|
<!-- <GridLayout row="3" width="300" height="150" iosGlassEffect="clear" horizontalAlignment="center" verticalAlignment="middle" class="m-t-10" borderRadius="50">
|
||||||
<Label class="text-center c-white" fontWeight="bold" fontSize="18" text="Glass Effects Clear" />
|
<Label class="text-center c-white" fontWeight="bold" fontSize="18" text="Glass Effects Clear" />
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
|
|
||||||
<GridLayout row="3" width="300" height="150" iosGlassEffect="{{iosGlassEffectInteractive}}" horizontalAlignment="center" verticalAlignment="middle" class="m-t-10">
|
<GridLayout row="4" width="300" height="150" iosGlassEffect="{{iosGlassEffectInteractive}}" horizontalAlignment="center" verticalAlignment="middle" class="m-t-10" borderRadius="50">
|
||||||
<Label class="text-center c-white" fontWeight="bold" fontSize="18" text="Glass Effects Interactive" />
|
<Label class="text-center c-white" fontWeight="bold" fontSize="18" text="Glass Effects Interactive" />
|
||||||
</GridLayout>
|
</GridLayout> -->
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
|
|
||||||
|
<GridLayout height="600"/>
|
||||||
|
</StackLayout>
|
||||||
|
|
||||||
|
</ScrollView>
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
</Page>
|
</Page>
|
||||||
|
|||||||
@@ -2,10 +2,11 @@ import { ControlStateChangeListener } from '../core/control-state-change';
|
|||||||
import { ButtonBase } from './button-common';
|
import { ButtonBase } from './button-common';
|
||||||
import { View, PseudoClassHandler } from '../core/view';
|
import { View, PseudoClassHandler } from '../core/view';
|
||||||
import { borderTopWidthProperty, borderRightWidthProperty, borderBottomWidthProperty, borderLeftWidthProperty, paddingLeftProperty, paddingTopProperty, paddingRightProperty, paddingBottomProperty } from '../styling/style-properties';
|
import { borderTopWidthProperty, borderRightWidthProperty, borderBottomWidthProperty, borderLeftWidthProperty, paddingLeftProperty, paddingTopProperty, paddingRightProperty, paddingBottomProperty } from '../styling/style-properties';
|
||||||
import { textAlignmentProperty, whiteSpaceProperty, textOverflowProperty } from '../text-base';
|
import { textAlignmentProperty, whiteSpaceProperty, textOverflowProperty, textProperty } from '../text-base';
|
||||||
|
import { resetSymbol } from '../text-base/text-base-common';
|
||||||
import { layout } from '../../utils';
|
import { layout } from '../../utils';
|
||||||
|
import { SDK_VERSION } from '../../utils/constants';
|
||||||
import { CoreTypes } from '../../core-types';
|
import { CoreTypes } from '../../core-types';
|
||||||
import { Color } from '../../color';
|
|
||||||
|
|
||||||
export * from './button-common';
|
export * from './button-common';
|
||||||
|
|
||||||
@@ -208,6 +209,34 @@ export class Button extends ButtonBase {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// [textProperty.setNative](value: string | number | symbol) {
|
||||||
|
// if (SDK_VERSION >= 26) {
|
||||||
|
// const config = UIButtonConfiguration.plainButtonConfiguration();
|
||||||
|
// // const attrs = {};
|
||||||
|
// // attrs[NSFontAttributeName] = UIFont.preferredFontForTextStyle(UIFontTextStyleHeadline);
|
||||||
|
// // config.attributedTitle = NSAttributedString.alloc().initWithStringAttributes(this.text, {
|
||||||
|
// // [NSFontAttributeName]: UIFont.preferredFontForTextStyle(UIFontTextStyleHeadline),
|
||||||
|
// // } as any);
|
||||||
|
// //attributes: AttributeContainer([
|
||||||
|
// // .font : UIFont.preferredFont(forTextStyle: .headline)
|
||||||
|
// // ])
|
||||||
|
// this.nativeViewProtected.tintColor = UIColor.labelColor;
|
||||||
|
// config.contentInsets = NSDirectionalEdgeInsetsFromString('8,12,8,12');
|
||||||
|
// // semantic; flips as needed over glass
|
||||||
|
// config.baseForegroundColor = UIColor.labelColor;
|
||||||
|
// this.nativeViewProtected.configuration = config;
|
||||||
|
// this._requestLayoutOnTextChanged();
|
||||||
|
// } else {
|
||||||
|
// const reset = value === resetSymbol;
|
||||||
|
// if (!reset && this.formattedText) {
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// this._setNativeText(reset);
|
||||||
|
// this._requestLayoutOnTextChanged();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
[textAlignmentProperty.setNative](value: CoreTypes.TextAlignmentType) {
|
[textAlignmentProperty.setNative](value: CoreTypes.TextAlignmentType) {
|
||||||
switch (value) {
|
switch (value) {
|
||||||
case 'left':
|
case 'left':
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
import { Point, Position, View as ViewDefinition } from '.';
|
import { Point, Position, View as ViewDefinition } from '.';
|
||||||
|
|
||||||
// Requires
|
// Requires
|
||||||
import { ViewCommon, isEnabledProperty, originXProperty, originYProperty, isUserInteractionEnabledProperty, testIDProperty, iosGlassEffectProperty, GlassEffectType, GlassEffectVariant } from './view-common';
|
import { ViewCommon, isEnabledProperty, originXProperty, originYProperty, isUserInteractionEnabledProperty, testIDProperty, iosGlassEffectProperty, GlassEffectType, GlassEffectVariant, GlassEffectConfig } from './view-common';
|
||||||
import { ShowModalOptions, hiddenProperty } from '../view-base';
|
import { ShowModalOptions, hiddenProperty } from '../view-base';
|
||||||
import { Trace } from '../../../trace';
|
import { Trace } from '../../../trace';
|
||||||
import { layout, ios as iosUtils } from '../../../utils';
|
import { layout, ios as iosUtils } from '../../../utils';
|
||||||
@@ -901,29 +901,28 @@ export class View extends ViewCommon implements ViewDefinition {
|
|||||||
if (!this.nativeViewProtected || !supportsGlass()) {
|
if (!this.nativeViewProtected || !supportsGlass()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (this._glassEffectView) {
|
let effect: UIGlassEffect | UIVisualEffect;
|
||||||
this._glassEffectView.removeFromSuperview();
|
const config: GlassEffectConfig | null = typeof value !== 'string' ? value : null;
|
||||||
this._glassEffectView = null;
|
const variant = config ? config.variant : (value as GlassEffectVariant);
|
||||||
}
|
const defaultDuration = 0.3;
|
||||||
if (!value) {
|
const duration = config ? (config.animateChangeDuration ?? defaultDuration) : defaultDuration;
|
||||||
return;
|
|
||||||
}
|
if (!value || ['identity', 'none'].includes(variant)) {
|
||||||
let effect: UIGlassEffect;
|
// empty effect
|
||||||
if (typeof value === 'string') {
|
effect = UIVisualEffect.new();
|
||||||
effect = UIGlassEffect.effectWithStyle(this.toUIGlassStyle(value));
|
|
||||||
} else {
|
} else {
|
||||||
if (value.variant === 'identity') {
|
effect = UIGlassEffect.effectWithStyle(this.toUIGlassStyle(variant));
|
||||||
return;
|
if (config) {
|
||||||
}
|
(effect as UIGlassEffect).interactive = !!config.interactive;
|
||||||
effect = UIGlassEffect.effectWithStyle(this.toUIGlassStyle(value.variant));
|
if (config.tint) {
|
||||||
if (value.interactive) {
|
(effect as UIGlassEffect).tintColor = typeof config.tint === 'string' ? new Color(config.tint).ios : config.tint;
|
||||||
effect.interactive = true;
|
|
||||||
}
|
|
||||||
if (value.tint) {
|
|
||||||
effect.tintColor = typeof value.tint === 'string' ? new Color(value.tint).ios : value.tint;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this._glassEffectView) {
|
||||||
this._glassEffectView = UIVisualEffectView.alloc().initWithEffect(effect);
|
this._glassEffectView = UIVisualEffectView.alloc().initWithEffect(effect);
|
||||||
|
// this._glassEffectView.overrideUserInterfaceStyle = UIUserInterfaceStyle.Light;
|
||||||
// let touches pass to content
|
// let touches pass to content
|
||||||
this._glassEffectView.userInteractionEnabled = false;
|
this._glassEffectView.userInteractionEnabled = false;
|
||||||
this._glassEffectView.clipsToBounds = true;
|
this._glassEffectView.clipsToBounds = true;
|
||||||
@@ -937,6 +936,12 @@ export class View extends ViewCommon implements ViewDefinition {
|
|||||||
this._glassEffectView.autoresizingMask = 2;
|
this._glassEffectView.autoresizingMask = 2;
|
||||||
this.nativeViewProtected.insertSubviewAtIndex(this._glassEffectView, 0);
|
this.nativeViewProtected.insertSubviewAtIndex(this._glassEffectView, 0);
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
// animate effect changes
|
||||||
|
UIView.animateWithDurationAnimations(duration, () => {
|
||||||
|
this._glassEffectView.effect = effect;
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public toUIGlassStyle(value?: GlassEffectVariant) {
|
public toUIGlassStyle(value?: GlassEffectVariant) {
|
||||||
|
|||||||
@@ -105,6 +105,11 @@ export abstract class ViewCommon extends ViewBase implements ViewDefinition {
|
|||||||
public visionHoverStyle: string | VisionHoverOptions;
|
public visionHoverStyle: string | VisionHoverOptions;
|
||||||
public visionIgnoreHoverStyle: boolean;
|
public visionIgnoreHoverStyle: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* iOS 26+ Glass
|
||||||
|
*/
|
||||||
|
iosGlassEffect: GlassEffectType;
|
||||||
|
|
||||||
protected _closeModalCallback: Function;
|
protected _closeModalCallback: Function;
|
||||||
public _manager: any;
|
public _manager: any;
|
||||||
public _modalParent: ViewCommon;
|
public _modalParent: ViewCommon;
|
||||||
@@ -1317,8 +1322,16 @@ iosIgnoreSafeAreaProperty.register(ViewCommon);
|
|||||||
/**
|
/**
|
||||||
* Glass effects
|
* Glass effects
|
||||||
*/
|
*/
|
||||||
export type GlassEffectVariant = 'regular' | 'clear' | 'identity';
|
export type GlassEffectVariant = 'regular' | 'clear' | 'identity' | 'none';
|
||||||
export type GlassEffectConfig = { variant?: GlassEffectVariant; interactive?: boolean; tint: string | Color };
|
export type GlassEffectConfig = {
|
||||||
|
variant?: GlassEffectVariant;
|
||||||
|
interactive?: boolean;
|
||||||
|
tint?: string | Color;
|
||||||
|
/**
|
||||||
|
* Duration in milliseconds to animate effect changes (default is 300ms)
|
||||||
|
*/
|
||||||
|
animateChangeDuration?: number;
|
||||||
|
};
|
||||||
export type GlassEffectType = GlassEffectVariant | GlassEffectConfig;
|
export type GlassEffectType = GlassEffectVariant | GlassEffectConfig;
|
||||||
export const iosGlassEffectProperty = new Property<ViewCommon, GlassEffectType>({
|
export const iosGlassEffectProperty = new Property<ViewCommon, GlassEffectType>({
|
||||||
name: 'iosGlassEffect',
|
name: 'iosGlassEffect',
|
||||||
|
|||||||
2
packages/core/ui/layouts/index.d.ts
vendored
2
packages/core/ui/layouts/index.d.ts
vendored
@@ -6,3 +6,5 @@ export { RootLayout, getRootLayout, getRootLayoutById, RootLayoutOptions, ShadeC
|
|||||||
export { StackLayout } from './stack-layout';
|
export { StackLayout } from './stack-layout';
|
||||||
export { WrapLayout } from './wrap-layout';
|
export { WrapLayout } from './wrap-layout';
|
||||||
export { LayoutBase } from './layout-base';
|
export { LayoutBase } from './layout-base';
|
||||||
|
export { LiquidGlass } from './liquid-glass';
|
||||||
|
export { LiquidGlassContainer } from './liquid-glass-container';
|
||||||
|
|||||||
@@ -7,3 +7,5 @@ export type { RootLayoutOptions, ShadeCoverOptions } from './root-layout';
|
|||||||
export { StackLayout } from './stack-layout';
|
export { StackLayout } from './stack-layout';
|
||||||
export { WrapLayout } from './wrap-layout';
|
export { WrapLayout } from './wrap-layout';
|
||||||
export { LayoutBase } from './layout-base';
|
export { LayoutBase } from './layout-base';
|
||||||
|
export { LiquidGlass } from './liquid-glass';
|
||||||
|
export { LiquidGlassContainer } from './liquid-glass-container';
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
import { LiquidGlassContainerCommon } from './liquid-glass-container-common';
|
||||||
|
|
||||||
|
export class LiquidGlassContainer extends LiquidGlassContainerCommon {}
|
||||||
3
packages/core/ui/layouts/liquid-glass-container/index.d.ts
vendored
Normal file
3
packages/core/ui/layouts/liquid-glass-container/index.d.ts
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
import { LiquidGlassContainerCommon } from './liquid-glass-container-common';
|
||||||
|
|
||||||
|
export class LiquidGlassContainer extends LiquidGlassContainerCommon {}
|
||||||
41
packages/core/ui/layouts/liquid-glass-container/index.ios.ts
Normal file
41
packages/core/ui/layouts/liquid-glass-container/index.ios.ts
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
import type { NativeScriptUIView } from '../../utils';
|
||||||
|
import { View } from '../../core/view';
|
||||||
|
import { LiquidGlassContainerCommon } from './liquid-glass-container-common';
|
||||||
|
|
||||||
|
export class LiquidGlassContainer extends LiquidGlassContainerCommon {
|
||||||
|
public nativeViewProtected: UIVisualEffectView;
|
||||||
|
|
||||||
|
createNativeView() {
|
||||||
|
const effect = UIGlassContainerEffect.alloc().init();
|
||||||
|
effect.spacing = 8;
|
||||||
|
const glassEffectView = UIVisualEffectView.alloc().initWithEffect(effect);
|
||||||
|
glassEffectView.overrideUserInterfaceStyle = UIUserInterfaceStyle.Dark;
|
||||||
|
glassEffectView.clipsToBounds = true;
|
||||||
|
|
||||||
|
return glassEffectView;
|
||||||
|
}
|
||||||
|
|
||||||
|
public _addViewToNativeVisualTree(child: View, atIndex: number): boolean {
|
||||||
|
const parentNativeView = this.nativeViewProtected;
|
||||||
|
const childNativeView: NativeScriptUIView = <NativeScriptUIView>child.nativeViewProtected;
|
||||||
|
|
||||||
|
if (parentNativeView && childNativeView) {
|
||||||
|
if (typeof atIndex !== 'number' || atIndex >= parentNativeView.subviews.count) {
|
||||||
|
// parentNativeView.addSubview(childNativeView);
|
||||||
|
this.nativeViewProtected.contentView.addSubview(childNativeView);
|
||||||
|
} else {
|
||||||
|
// parentNativeView.insertSubviewAtIndex(childNativeView, atIndex);
|
||||||
|
this.nativeViewProtected.contentView.insertSubviewAtIndex(childNativeView, atIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add outer shadow layer manually as it belongs to parent layer tree (this is needed for reusable views)
|
||||||
|
if (childNativeView.outerShadowContainerLayer && !childNativeView.outerShadowContainerLayer.superlayer) {
|
||||||
|
parentNativeView.layer.insertSublayerBelow(childNativeView.outerShadowContainerLayer, childNativeView.layer);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
import { GridLayout } from '../grid-layout';
|
||||||
|
|
||||||
|
export class LiquidGlassContainerCommon extends GridLayout {}
|
||||||
3
packages/core/ui/layouts/liquid-glass/index.android.ts
Normal file
3
packages/core/ui/layouts/liquid-glass/index.android.ts
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
import { LiquidGlassCommon } from './liquid-glass-common';
|
||||||
|
|
||||||
|
export class LiquidGlass extends LiquidGlassCommon {}
|
||||||
3
packages/core/ui/layouts/liquid-glass/index.d.ts
vendored
Normal file
3
packages/core/ui/layouts/liquid-glass/index.d.ts
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
import { LiquidGlassCommon } from './liquid-glass-common';
|
||||||
|
|
||||||
|
export class LiquidGlass extends LiquidGlassCommon {}
|
||||||
41
packages/core/ui/layouts/liquid-glass/index.ios.ts
Normal file
41
packages/core/ui/layouts/liquid-glass/index.ios.ts
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
import type { NativeScriptUIView } from '../../utils';
|
||||||
|
import { View } from '../../core/view';
|
||||||
|
import { LiquidGlassCommon } from './liquid-glass-common';
|
||||||
|
|
||||||
|
export class LiquidGlass extends LiquidGlassCommon {
|
||||||
|
public nativeViewProtected: UIVisualEffectView;
|
||||||
|
|
||||||
|
createNativeView() {
|
||||||
|
const effect = UIGlassEffect.effectWithStyle(UIGlassEffectStyle.Clear);
|
||||||
|
effect.interactive = true;
|
||||||
|
const glassEffectView = UIVisualEffectView.alloc().initWithEffect(effect);
|
||||||
|
glassEffectView.overrideUserInterfaceStyle = UIUserInterfaceStyle.Dark;
|
||||||
|
glassEffectView.clipsToBounds = true;
|
||||||
|
|
||||||
|
return glassEffectView;
|
||||||
|
}
|
||||||
|
|
||||||
|
public _addViewToNativeVisualTree(child: View, atIndex: number): boolean {
|
||||||
|
const parentNativeView = this.nativeViewProtected;
|
||||||
|
const childNativeView: NativeScriptUIView = <NativeScriptUIView>child.nativeViewProtected;
|
||||||
|
|
||||||
|
if (parentNativeView && childNativeView) {
|
||||||
|
if (typeof atIndex !== 'number' || atIndex >= parentNativeView.subviews.count) {
|
||||||
|
// parentNativeView.addSubview(childNativeView);
|
||||||
|
this.nativeViewProtected.contentView.addSubview(childNativeView);
|
||||||
|
} else {
|
||||||
|
// parentNativeView.insertSubviewAtIndex(childNativeView, atIndex);
|
||||||
|
this.nativeViewProtected.contentView.insertSubviewAtIndex(childNativeView, atIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add outer shadow layer manually as it belongs to parent layer tree (this is needed for reusable views)
|
||||||
|
if (childNativeView.outerShadowContainerLayer && !childNativeView.outerShadowContainerLayer.superlayer) {
|
||||||
|
parentNativeView.layer.insertSublayerBelow(childNativeView.outerShadowContainerLayer, childNativeView.layer);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
import { GridLayout } from '../grid-layout';
|
||||||
|
|
||||||
|
export class LiquidGlassCommon extends GridLayout {}
|
||||||
@@ -12,14 +12,12 @@ import { Span } from './span';
|
|||||||
import { colorProperty, fontInternalProperty, fontScaleInternalProperty, Length } from '../styling/style-properties';
|
import { colorProperty, fontInternalProperty, fontScaleInternalProperty, Length } from '../styling/style-properties';
|
||||||
import { StrokeCSSValues } from '../styling/css-stroke';
|
import { StrokeCSSValues } from '../styling/css-stroke';
|
||||||
import { isString, isNullOrUndefined } from '../../utils/types';
|
import { isString, isNullOrUndefined } from '../../utils/types';
|
||||||
import { iOSNativeHelper, layout } from '../../utils';
|
import { layout } from '../../utils';
|
||||||
import { Trace } from '../../trace';
|
import { SDK_VERSION } from '../../utils/constants';
|
||||||
import { CoreTypes } from '../../core-types';
|
import { CoreTypes } from '../../core-types';
|
||||||
|
|
||||||
export * from './text-base-common';
|
export * from './text-base-common';
|
||||||
|
|
||||||
const majorVersion = iOSNativeHelper.MajorVersion;
|
|
||||||
|
|
||||||
@NativeClass
|
@NativeClass
|
||||||
class UILabelClickHandlerImpl extends NSObject {
|
class UILabelClickHandlerImpl extends NSObject {
|
||||||
private _owner: WeakRef<TextBase>;
|
private _owner: WeakRef<TextBase>;
|
||||||
@@ -350,7 +348,7 @@ export class TextBase extends TextBaseCommon {
|
|||||||
const text = getTransformedText(isNullOrUndefined(this.text) ? '' : `${this.text}`, this.textTransform);
|
const text = getTransformedText(isNullOrUndefined(this.text) ? '' : `${this.text}`, this.textTransform);
|
||||||
this.nativeTextViewProtected.nativeScriptSetTextDecorationAndTransformTextDecorationLetterSpacingLineHeight(text, this.style.textDecoration || '', letterSpacing, lineHeight);
|
this.nativeTextViewProtected.nativeScriptSetTextDecorationAndTransformTextDecorationLetterSpacingLineHeight(text, this.style.textDecoration || '', letterSpacing, lineHeight);
|
||||||
|
|
||||||
if (!this.style?.color && majorVersion >= 13 && UIColor.labelColor) {
|
if (!this.style?.color && SDK_VERSION >= 13 && UIColor.labelColor) {
|
||||||
this._setColor(UIColor.labelColor);
|
this._setColor(UIColor.labelColor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
tools/assets/App_Resources/iOS/bg1.jpg
Normal file
BIN
tools/assets/App_Resources/iOS/bg1.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 782 KiB |
BIN
tools/assets/App_Resources/iOS/bg2.jpg
Normal file
BIN
tools/assets/App_Resources/iOS/bg2.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.2 MiB |
BIN
tools/assets/App_Resources/iOS/bg3.jpg
Normal file
BIN
tools/assets/App_Resources/iOS/bg3.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.2 MiB |
Reference in New Issue
Block a user