【问题标题】:Xamarin Form - IOS: How to detect the UIView size changedXamarin Form - IOS:如何检测 UIView 大小已更改
【发布时间】:2016-09-13 03:54:14
【问题描述】:

我使用 ContentView 创建了一个 Xamarin 表单,并为 Android 创建了一个渲染器。现在我必须为 IOS 创建一个渲染器。

在 android 渲染器中,我可以覆盖 onSizeChanged 并将这些宽度/高度值传递给自定义 xamarin-form 视图。

protected override void OnSizeChanged(int w, int h, int oldw, int oldh) { 
        base.OnSizeChanged(w,h, oldw, old);

        Element.SizChanged(w,h);

}

IOS中的UIView是否有类似的覆盖方法?我已经尝试覆盖 Frame 属性并在 Element.SizeChanged(w,h) 中调用,但我会得到 TargetInvocationException。

附: SizeChanged 方法是我的自定义虚拟方法而不是 android 方法。

【问题讨论】:

    标签: ios xamarin xamarin.ios xamarin.forms


    【解决方案1】:

    覆盖LayoutSubviews 通常用于跟踪调整大小事件,因为UIView 也负责它的所有子视图。

    我也倾向于覆盖 BoundsFrame,具体取决于我在做什么以及此视图包含的内容...根据父级,可以多次调用视图的 LayoutSubviews...

    假设 UIView 子类如下:

    public class UIViewResizing : UIView
    {
        public UIViewResizing() { }
        public UIViewResizing(CGRect frame) : base(frame) { }
        public UIViewResizing(NSCoder coder) : base(coder) { }
    
        public override CGRect Bounds
        {
            get
            {
                return base.Bounds;
            }
            set
            {
                if (value != base.Bounds)
                {
                    Console.WriteLine($"Bounds changing: {this}");
                }
                base.Bounds = value;
            }
        }
    
        public override CGRect Frame
        {
            get
            {
                return base.Frame;
            }
            set
            {
                if (value != base.Frame)
                {
                    Console.WriteLine($"Frame changing: {this}.");
                }
                base.Frame = value;
            }
        }
    
        public override void LayoutSubviews()
        {
            Console.WriteLine($"LayoutSubViews requested: {this}");
            base.LayoutSubviews();
        }
    }
    

    锻炼它:

    var view = new UIViewResizing(new CGRect(100, 100, 100, 100));
    view.BackgroundColor = UIColor.Red;
    Add(view);
    await Task.Delay(2500);
    view.Frame = new CGRect(100, 100, 200, 200);
    await Task.Delay(2500);
    view.Bounds = new CGRect(20, 20, 100, 200);
    

    结果:

    Frame changing: <uiviewresize_UIViewResizing: 0x79a6cc00; frame = (-50 -50; 100 100); layer = <CALayer: 0x78628230>>.
    LayoutSubViews requested: <uiviewresize_UIViewResizing: 0x79a6cc00; frame = (100 100; 100 100); layer = <CALayer: 0x78628230>>
    Frame changing: <uiviewresize_UIViewResizing: 0x79a6cc00; frame = (100 100; 100 100); layer = <CALayer: 0x78628230>>. 
    LayoutSubViews requested: <uiviewresize_UIViewResizing: 0x79a6cc00; frame = (100 100; 200 200); layer = <CALayer: 0x78628230>>
    Bounds changing: <uiviewresize_UIViewResizing: 0x79a6cc00; frame = (100 100; 200 200); layer = <CALayer: 0x78628230>>
    LayoutSubViews requested: <uiviewresize_UIViewResizing: 0x79a6cc00; frame = (150 100; 100 200); layer = <CALayer: 0x78628230>>
    

    有关更多信息,请参阅此 SO:Is there a UIView resize event?

    【讨论】:

    • 这行得通,但我如何知道动画何时结束。好像调用了好几次
    • @Simon 动画有完成块,可用于在动画结束时执行代码。
    • 你是说AnimateWillStop方法
    • 正如引用的 SO 中提到的,框架和边界实际上都是计算属性,它们的 setter/getter 方法可能并不总是被调用。它仍然可能是最好的,但如果有什么奇怪的行为值得记住。
    猜你喜欢
    • 1970-01-01
    • 2015-08-17
    • 1970-01-01
    • 2017-05-05
    • 2014-12-29
    • 2018-09-17
    • 1970-01-01
    • 2013-09-27
    • 1970-01-01
    相关资源
    最近更新 更多