mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-08-17 04:41:36 +08:00
Merge pull request #3931 from NativeScript/fix-ios-animations
Fix iOS animations, transition was workin in DIP, when css class is change objects were flickering
This commit is contained in:
@ -1,5 +1,5 @@
|
||||
import { AnimationDefinition } from ".";
|
||||
import { View } from "../core/view";
|
||||
import { View, layout } from "../core/view";
|
||||
|
||||
import { AnimationBase, Properties, PropertyAnimation, CubicBezierAnimationCurve, AnimationPromise, traceWrite, traceEnabled, traceCategories } from "./animation-common";
|
||||
import {
|
||||
@ -589,7 +589,9 @@ export class Animation extends AnimationBase {
|
||||
export function _getTransformMismatchErrorMessage(view: View): string {
|
||||
// Order is important: translate, rotate, scale
|
||||
let result: CGAffineTransform = CGAffineTransformIdentity;
|
||||
result = CGAffineTransformTranslate(result, Length.toDevicePixels(view.translateX || 0, 0), Length.toDevicePixels(view.translateY || 0, 0));
|
||||
const tx = layout.toDeviceIndependentPixels(Length.toDevicePixels(view.translateX || 0, 0));
|
||||
const ty = layout.toDeviceIndependentPixels(Length.toDevicePixels(view.translateY || 0, 0));
|
||||
result = CGAffineTransformTranslate(result, tx, ty);
|
||||
result = CGAffineTransformRotate(result, (view.rotate || 0) * Math.PI / 180);
|
||||
result = CGAffineTransformScale(result, view.scaleX || 1, view.scaleY || 1);
|
||||
let viewTransform = NSStringFromCGAffineTransform(result);
|
||||
|
@ -247,6 +247,19 @@ export abstract class ViewBase extends Observable {
|
||||
|
||||
//@private
|
||||
public _styleScope: any;
|
||||
|
||||
/**
|
||||
* Determines the depth of batchUpdates.
|
||||
* When the value is 0 the current updates are not batched.
|
||||
* If the value is 1 or greater, the current updates are batched.
|
||||
* Do not set this field, the _batchUpdate method is responsible to keep the count up to date.
|
||||
*/
|
||||
public _batchUpdateScope: number;
|
||||
|
||||
/**
|
||||
* Allow multiple updates to be performed on the instance at once.
|
||||
*/
|
||||
public _batchUpdate<T>(callback: () => T): T;
|
||||
//@endprivate
|
||||
}
|
||||
|
||||
|
@ -279,6 +279,16 @@ export abstract class ViewBase extends Observable implements ViewBaseDefinition
|
||||
this._emit("unloaded");
|
||||
}
|
||||
|
||||
public _batchUpdateScope: number;
|
||||
public _batchUpdate<T>(callback: () => T): T {
|
||||
try {
|
||||
++this._batchUpdateScope;
|
||||
return callback();
|
||||
} finally {
|
||||
--this._batchUpdateScope;
|
||||
}
|
||||
}
|
||||
|
||||
private _unloadEachChild() {
|
||||
this.eachChild((child) => {
|
||||
if (child.isLoaded) {
|
||||
@ -371,13 +381,14 @@ export abstract class ViewBase extends Observable implements ViewBaseDefinition
|
||||
private _invalidateCssHandlerSuspended: boolean;
|
||||
|
||||
private applyCssState(): void {
|
||||
if (!this._cssState) {
|
||||
return;
|
||||
}
|
||||
|
||||
// this.style._beginUpdate();
|
||||
this._cssState.apply();
|
||||
// this.style._endUpdate();
|
||||
this._batchUpdate(() => {
|
||||
if (!this._cssState) {
|
||||
this._cancelAllAnimations();
|
||||
resetCSSProperties(this.style);
|
||||
return;
|
||||
}
|
||||
this._cssState.apply();
|
||||
});
|
||||
}
|
||||
|
||||
private pseudoClassAliases = {
|
||||
@ -847,6 +858,8 @@ ViewBase.prototype._defaultPaddingRight = 0;
|
||||
ViewBase.prototype._defaultPaddingBottom = 0;
|
||||
ViewBase.prototype._defaultPaddingLeft = 0;
|
||||
|
||||
ViewBase.prototype._batchUpdateScope = 0;
|
||||
|
||||
export const bindingContextProperty = new InheritedProperty<ViewBase, any>({ name: "bindingContext" });
|
||||
bindingContextProperty.register(ViewBase);
|
||||
|
||||
@ -864,8 +877,6 @@ export const classNameProperty = new Property<ViewBase, string>({
|
||||
classNameProperty.register(ViewBase);
|
||||
|
||||
function resetStyles(view: ViewBase): void {
|
||||
view._cancelAllAnimations();
|
||||
resetCSSProperties(view.style);
|
||||
view._applyStyleFromScope();
|
||||
view.eachChild((child) => {
|
||||
resetStyles(child);
|
||||
|
@ -231,8 +231,8 @@ export class View extends ViewCommon {
|
||||
}
|
||||
|
||||
public updateNativeTransform() {
|
||||
let translateX = Length.toDevicePixels(this.translateX || 0, 0);
|
||||
let translateY = Length.toDevicePixels(this.translateY || 0, 0);
|
||||
let translateX = layout.toDeviceIndependentPixels(Length.toDevicePixels(this.translateX || 0, 0));
|
||||
let translateY = layout.toDeviceIndependentPixels(Length.toDevicePixels(this.translateY || 0, 0));
|
||||
let scaleX = this.scaleX || 1;
|
||||
let scaleY = this.scaleY || 1;
|
||||
let rotate = this.rotate || 0;
|
||||
@ -241,8 +241,15 @@ export class View extends ViewCommon {
|
||||
newTransform = CGAffineTransformRotate(newTransform, rotate * Math.PI / 180);
|
||||
newTransform = CGAffineTransformScale(newTransform, scaleX === 0 ? 0.001 : scaleX, scaleY === 0 ? 0.001 : scaleY);
|
||||
if (!CGAffineTransformEqualToTransform(this.nativeView.transform, newTransform)) {
|
||||
let updateSuspended = this._isPresentationLayerUpdateSuspeneded();
|
||||
if (!updateSuspended) {
|
||||
CATransaction.begin();
|
||||
}
|
||||
this.nativeView.transform = newTransform;
|
||||
this._hasTransfrom = this.nativeView && !CGAffineTransformEqualToTransform(this.nativeView.transform, CGAffineTransformIdentity);
|
||||
if (!updateSuspended) {
|
||||
CATransaction.commit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -266,7 +273,7 @@ export class View extends ViewCommon {
|
||||
}
|
||||
|
||||
public _isPresentationLayerUpdateSuspeneded() {
|
||||
return this._suspendCATransaction;
|
||||
return this._suspendCATransaction || this._batchUpdateScope;
|
||||
}
|
||||
|
||||
[isEnabledProperty.getDefault](): boolean {
|
||||
|
@ -102,11 +102,12 @@ export class CssState {
|
||||
matchingSelectors.push(this.view.inlineStyleSelector);
|
||||
}
|
||||
|
||||
matchingSelectors.forEach(s => this.applyDescriptors(this.view, s.ruleset));
|
||||
matchingSelectors.forEach(s => this.applyDescriptors(s.ruleset));
|
||||
matchingSelectors.forEach(s => this.playKeyframeAnimations(s.ruleset));
|
||||
}
|
||||
|
||||
private applyDescriptors(view: ViewBase, ruleset: RuleSet): void {
|
||||
let style = view.style;
|
||||
private applyDescriptors(ruleset: RuleSet): void {
|
||||
let style = this.view.style;
|
||||
ruleset.declarations.forEach(d => {
|
||||
try {
|
||||
// Use the "css:" prefixed name, so that CSS value source is set.
|
||||
@ -114,23 +115,25 @@ export class CssState {
|
||||
if (cssPropName in style) {
|
||||
style[cssPropName] = d.value;
|
||||
} else {
|
||||
view[d.property] = d.value;
|
||||
this.view[d.property] = d.value;
|
||||
}
|
||||
} catch (e) {
|
||||
traceWrite(`Failed to apply property [${d.property}] with value [${d.value}] to ${view}. ${e}`, traceCategories.Error, traceMessageType.error);
|
||||
traceWrite(`Failed to apply property [${d.property}] with value [${d.value}] to ${this.view}. ${e}`, traceCategories.Error, traceMessageType.error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private playKeyframeAnimations(ruleset: RuleSet): void {
|
||||
let ruleAnimations: kam.KeyframeAnimationInfo[] = ruleset[animationsSymbol];
|
||||
if (ruleAnimations) {
|
||||
ensureKeyframeAnimationModule();
|
||||
for (let animationInfo of ruleAnimations) {
|
||||
let animation = keyframeAnimationModule.KeyframeAnimation.keyframeAnimationFromInfo(animationInfo);
|
||||
if (animation) {
|
||||
view._registerAnimation(animation);
|
||||
animation.play(<View>view)
|
||||
.then(() => { view._unregisterAnimation(animation); })
|
||||
.catch((e) => { view._unregisterAnimation(animation); });
|
||||
this.view._registerAnimation(animation);
|
||||
animation.play(<View>this.view)
|
||||
.then(() => { this.view._unregisterAnimation(animation); })
|
||||
.catch((e) => { this.view._unregisterAnimation(animation); });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ export class Transition {
|
||||
//@private
|
||||
export function _clearBackwardTransitions(fragment: any): void;
|
||||
export function _clearForwardTransitions(fragment: any): void;
|
||||
export function _setAndroidFragmentTransitions(cachePagesOnNavigate: boolean, navigationTransition: NavigationTransition, currentFragment: any, newFragment: any, fragmentTransaction: android.app.FragmentTransaction): void;
|
||||
export function _setAndroidFragmentTransitions(cachePagesOnNavigate: boolean, navigationTransition: NavigationTransition, currentFragment: any, newFragment: any, fragmentTransaction: any): void;
|
||||
export function _onFragmentCreateAnimator(fragment: any, nextAnim: number): any;
|
||||
export function _onFragmentShown(fragment: any, isBack: boolean): void;
|
||||
export function _onFragmentHidden(fragment: any, isBack: boolean, destroyed: boolean): void;
|
||||
|
Reference in New Issue
Block a user