Xamarin Forms iOS中获取按钮坐标:Y坐标始终为0的解决方法
你当前使用Frame.Left和Frame.Top获取的是控件相对于直接父容器的坐标,若父容器布局未完全完成,或你实际需要的是屏幕绝对坐标,就会出现Y坐标始终为0的问题,以下是几种可行的解决方案:
方案1:获取屏幕绝对坐标(推荐)
直接将控件自身的原点转换为屏幕坐标,避免父容器布局带来的相对性问题:
private (int x, int y) GetCoordinatesNative() { var screenPoint = Control.ConvertPointToScreen(new System.Drawing.Point(0, 0)); return (screenPoint.X, screenPoint.Y); }
Control对应原生平台的按钮实例(Android为Android.Widget.Button,iOS为UIKit.UIButton),ConvertPointToScreen方法会将控件左上角的位置转换为屏幕上的绝对坐标,得到的X、Y即为按钮在屏幕上的真实位置。
方案2:确保布局完成后再获取坐标
若你需要的是相对父容器的坐标,需等待控件布局完全完成后再获取值,可通过监听LayoutChanged事件实现:
protected override void OnElementChanged(ElementChangedEventArgs<Button> e) { base.OnElementChanged(e); if (e.OldElement != null) { e.OldElement.LayoutChanged -= OnLayoutChanged; } if (e.NewElement is ContextMenuButton contextButton) { contextButton.LayoutChanged += OnLayoutChanged; contextButton.GetCoordinates = GetCoordinatesNative; } } private void OnLayoutChanged(object sender, EventArgs e) { // 布局完成后,Frame值会更新为正确的相对坐标 } private (int x, int y) GetCoordinatesNative() { return ((int)Frame.Left, (int)Frame.Top); }
方案3:针对不同平台强制更新布局
如果在复杂布局场景下,即使等待LayoutChanged仍有问题,可针对平台强制触发布局更新后再获取坐标:
Android平台
private (int x, int y) GetCoordinatesNative() { Control.RequestLayout(); Control.Measure(Android.Views.View.MeasureSpec.Unspecified, Android.Views.View.MeasureSpec.Unspecified); var location = new int[2]; Control.GetLocationOnScreen(location); return (location[0], location[1]); }
iOS平台
private (int x, int y) GetCoordinatesNative() { Control.LayoutIfNeeded(); var screenPoint = Control.Superview.ConvertPointToScreen(Control.Frame.Location); return ((int)screenPoint.X, (int)screenPoint.Y); }
内容的提问来源于stack exchange,提问作者abani samal
相关产品推荐
相关产品推荐

