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

Posted

技术标签:

【中文标题】如何覆盖 Xamarin.IOS UIButton 的 LayoutSublayersOfLayer 行为?【英文标题】:How to override LayoutSublayersOfLayer behavior of Xamarin.IOS UIButton? 【发布时间】:2016-08-01 15:03:39 【问题描述】:

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

swift 对应物是 UIButton 的子类,并覆盖 layoutSublayersOfLayer。

斯威夫特:

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

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

有没有办法覆盖 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()
    
        //...
    

谢谢!

【问题讨论】:

【参考方案1】:

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

public override void LayoutSublayersOfLayer(CALayer layer)

    base.LayoutSublayersOfLayer(layer);

    if (_button.Layer == layer)
    
        _button.LayoutShape();
        _button.LayoutVisualLayer();
    

【讨论】:

以上是关于如何覆盖 Xamarin.IOS UIButton 的 LayoutSublayersOfLayer 行为?的主要内容,如果未能解决你的问题,请参考以下文章

UIButton 在相机流中不可见 (Xamarin.iOS)

Xamarin iOS UINavigationBar 奇怪的覆盖

在 Xamarin.iOS 中使用 UITableViewCell 展开 Segue

Xamarin iOS Tap 事件通过最顶部的视图?

Xamarin.ios 基本控件

Xamarin iOS 方法在应用导航到后台、关闭或导航到不同屏幕时覆盖以保存数据