如何覆盖Xamarin.IOS UIButton的LayoutSublayersOfLayer行为

本文关键字:UIButton IOS LayoutSublayersOfLayer 行为 Xamarin 何覆盖 覆盖 | 更新日期: 2023-09-27 17:59:46

我正在将一个swift库移植到Xamarin.IOS,该库使用UIButton制作一些材料设计动画。

swift对应项是UIButton的一个子类,覆盖layoutSublayersOfLayer。

Swift:

public override func layoutSublayersOfLayer(layer: CALayer) {
    super.layoutSublayersOfLayer(layer)
    if self.layer == layer {
        layoutShape()
        layoutVisualLayer()
    }
}

在Xamarin方面,我注意到这个方法是通过CALayerDelegate调用的,它通过de property Delegate与CALayer相关联。我试图将CALayerDelegate子类化并替换deDelegate属性,但当我这样做时,按钮没有正确呈现,并停止响应事件。

有没有办法覆盖Xamarin.Ios上的layoutSublayersOfLayer?有没有其他方法可以在绘制特定图层之前覆盖以准备材料

public class MaterialButtonLayerDelegate : CALayerDelegate
{
    private readonly MaterialButton _button;
    public MaterialButtonLayerDelegate(MaterialButton button):base()
    {
        _button = button;
    }
    public override void LayoutSublayersOfLayer(CALayer layer)
    {
        if (_button.Layer == layer)
        {
            _button.LayoutShape();
            _button.LayoutVisualLayer();
        }
    }
}
[Register("MaterialButton")]
public class MaterialButton : UIButton
{
    public CAShapeLayer VisualLayer { get; private set; } = new CAShapeLayer();
    public MaterialButton(CGRect frame):base(frame)  
    {
        PrepareView();
    }
    protected void PrepareView()
    {
        Layer.Delegate = new MaterialButtonLayerDelegate(this);
        ContentScaleFactor = MaterialDevice.Scale();
        PrepareVisualLayer();
    }
    protected virtual void PrepareVisualLayer()
    {
        VisualLayer.ZPosition = 0;
        VisualLayer.MasksToBounds = true;
        Layer.AddSublayer(VisualLayer);
    }
    protected virtual void LayoutShape()
    {
        //...
    }
    protected virtual void LayoutVisualLayer()
    {
        //...
    }
}

谢谢!

如何覆盖Xamarin.IOS UIButton的LayoutSublayersOfLayer行为

唯一可能的方法是扩展CALayerDelegate类并将其设置为CAShapeLayer委托。确保尽可能调用委托的基础成员,因为它在后台执行所需的绑定。

public override void LayoutSublayersOfLayer(CALayer layer)
{
    base.LayoutSublayersOfLayer(layer);
    if (_button.Layer == layer)
    {
        _button.LayoutShape();
        _button.LayoutVisualLayer();
    }
}