public async Task HandleTouch(TouchStatus status, TouchInteractionStatus?interactionStatus = null) { if (IsCanceled || effect == null) { return; } if (effect?.IsDisabled ?? true) { return; } var canExecuteAction = effect.CanExecute; if (interactionStatus == TouchInteractionStatus.Started) { effect?.HandleUserInteraction(TouchInteractionStatus.Started); interactionStatus = null; } effect?.HandleTouch(status); if (interactionStatus.HasValue) { effect?.HandleUserInteraction(interactionStatus.Value); } if (effect == null || (!effect.NativeAnimation && !IsButton) || (!canExecuteAction && status == TouchStatus.Started)) { return; } var control = effect.Element; if (control?.GetRenderer() is not UIView renderer) { return; } var color = effect.NativeAnimationColor; var radius = effect.NativeAnimationRadius; var shadowRadius = effect.NativeAnimationShadowRadius; var isStarted = status == TouchStatus.Started; defaultRadius = (float?)(defaultRadius ?? renderer.Layer.CornerRadius); defaultShadowRadius = (float?)(defaultShadowRadius ?? renderer.Layer.ShadowRadius); defaultShadowOpacity ??= renderer.Layer.ShadowOpacity; var tcs = new TaskCompletionSource <UIViewAnimatingPosition>(); UIViewPropertyAnimator.CreateRunningPropertyAnimator(.2, 0, UIViewAnimationOptions.AllowUserInteraction, () => { if (color == Color.Default) { renderer.Layer.Opacity = isStarted ? 0.5f : (float)control.Opacity; } else { renderer.Layer.BackgroundColor = (isStarted ? color : control.BackgroundColor).ToCGColor(); } renderer.Layer.CornerRadius = isStarted ? radius : defaultRadius.GetValueOrDefault(); if (shadowRadius >= 0) { renderer.Layer.ShadowRadius = isStarted ? shadowRadius : defaultShadowRadius.GetValueOrDefault(); renderer.Layer.ShadowOpacity = isStarted ? 0.7f : defaultShadowOpacity.GetValueOrDefault(); } }, endPos => tcs.SetResult(endPos)); await tcs.Task; }