在 iOS 中使用自定义渲染器的按钮的 Xamarin.Forms 渐变背景

标签 xamarin xamarin.ios xamarin.forms

我正在使用 Xamarin.Forms,我想全局地使按钮看起来更好一些。

我已经使用自定义渲染器在 Android 版本上很好地实现了这一点,但在 iOS 上却遇到了困难。

在 XAML 页面中定义按钮时,我引用“CustomButton”而不是“Button”,然后我的 iOS 应用程序中就有以下 CustomButtonRenderer。

大多数样式更改都可以正常工作(边框半径等),但我似乎无法使其呈现按钮的背景渐变。

这是到目前为止我的代码,但背景仅显示为白色。如何使其显示渐变且文本位于顶部?

class CustomButtonRenderer : ButtonRenderer
{
    protected override void OnElementChanged(ElementChangedEventArgs<Button> e)
    {
        base.OnElementChanged(e);

        if (Control != null)
        {
            var gradient = new CAGradientLayer();
            gradient.Frame = Control.Layer.Bounds;
            gradient.Colors = new CGColor[]
            {
                UIColor.FromRGB(51, 102, 204).CGColor,
                UIColor.FromRGB(51, 102, 204).CGColor
            };

            Control.Layer.AddSublayer(gradient);
            Control.Layer.CornerRadius = 10;
            Control.Layer.BorderColor = UIColor.FromRGB(51, 102, 204).CGColor;
            Control.Layer.BorderWidth = 1;

            Control.VerticalAlignment = UIControlContentVerticalAlignment.Center;
        }
    }
}

最佳答案

1st) 不要使用 AddSublayer,使用 InsertSublayerBelow 以便 Z 顺序正确并且您的 Title 文本将位于顶部。

2nd) 覆盖 LayoutSubviews 并更新您的 CAGradientLayer 框架以匹配您的 UIButton

第三)享受你的渐变:

enter image description here

完整示例:

[assembly: ExportRenderer(typeof(CustomButton), typeof(CustomButtonRenderer))]
namespace AppCompatRender.iOS
{
    public class CustomButtonRenderer : Xamarin.Forms.Platform.iOS.ButtonRenderer
    {
        public override void LayoutSubviews()
        {
            foreach (var layer in Control?.Layer.Sublayers.Where(layer => layer is CAGradientLayer))
                layer.Frame = Control.Bounds;
            base.LayoutSubviews();
        }

        protected override void OnElementChanged(ElementChangedEventArgs<Button> e)
        {
            base.OnElementChanged(e);

            if (e.OldElement == null)
            {
                var gradient = new CAGradientLayer();
                gradient.CornerRadius = Control.Layer.CornerRadius = 10;
                gradient.Colors = new CGColor[]
                {
                    UIColor.FromRGB(51, 102, 104).CGColor,
                    UIColor.FromRGB(51, 202, 204).CGColor
                };
                var layer = Control?.Layer.Sublayers.LastOrDefault();
                Control?.Layer.InsertSublayerBelow(gradient, layer);
            }
        }

    }
}

更新:

如果您使用 iOS 10+ 较新版本的 Xamarin.Forms,则调用 LayoutSubViews 期间的 Control.Bounds 全部为零。您需要在设置控件的 Frame 属性期间设置渐变层 Frame 大小,即:

public class CustomButtonRenderer : Xamarin.Forms.Platform.iOS.ButtonRenderer
{
    public override CGRect Frame
    {
        get
        {
            return base.Frame;
        }
        set
        {
            if (value.Width > 0 && value.Height > 0)
            {
                foreach (var layer in Control?.Layer.Sublayers.Where(layer => layer is CAGradientLayer))
                    layer.Frame = new CGRect(0, 0, value.Width, value.Height);
            }
            base.Frame = value;
        }
    }

    protected override void OnElementChanged(ElementChangedEventArgs<Button> e)
    {
        base.OnElementChanged(e);

        if (e.OldElement == null)
        {
            var gradient = new CAGradientLayer();
            gradient.CornerRadius = Control.Layer.CornerRadius = 20;
            gradient.Colors = new CGColor[]
            {
                UIColor.FromRGB(51, 102, 104).CGColor,
                UIColor.FromRGB(51, 202, 204).CGColor
            };
            var layer = Control?.Layer.Sublayers.LastOrDefault();
            Control?.Layer.InsertSublayerBelow(gradient, layer);
        }
    }
}

关于在 iOS 中使用自定义渲染器的按钮的 Xamarin.Forms 渐变背景,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37170276/

相关文章:

c# - Xamarin 表单更新 listView itemSsource

c# - MonoTouch MKLocalSearch示例

ios - UIImagePickerController 没有出现在 xamarin iOS 中

android - 将 Xamarin 表单更新到 5.0.0.2401 后,Xamarin 表单 android 抛出空异常

c# - HttpClient 不适用于 android

android - 无法在 Android 中找到 PCLstorage 路径

c# - 如何在 Xamarin Forms PCL 中使用 native Android ImageView?

c# - 旋转时关闭键盘

xaml - 使用 MVVM 刷新 TabbedPage 中的数据

visual-studio - 无法在调试 Xamarin Android 和 iOS 的设备上部署