如何通过按钮停止滚动中的UIPickerView(Xamarin.iOS)
解决Xamarin.iOS中UIPickerView停止滚动并获取值的问题
嘿,针对你在Xamarin.iOS项目里遇到的这个UIPickerView问题,我给你整理了一套可靠的解决方案,亲测能搞定!
UIPickerView本身没有直接的“停止滚动”API,但我们可以通过强制选中当前滚动到的行来实现停止滚动的效果,同时还能精准获取对应的值。下面是具体的实现步骤和代码示例:
1. 核心思路
当Picker正在滚动时,我们先通过视觉位置计算出当前滚动到的中间行,然后调用SelectRow方法强制选中该行——这会让Picker立即停止滚动,之后直接从数据源中取出该行对应的值即可。
2. 完整代码实现
假设你已经有了这些基础元素:
- UIPickerView实例:
numberPicker - 数据源列表:
numberList(包含1到10000的数字) - 触发停止的按钮:
stopButton
第一步:添加滚动状态标记
先在你的ViewController里定义一个类成员变量,用来标记Picker是否正在滚动:
private bool _isPickerScrolling = false;
第二步:监听Picker的滚动状态
给numberPicker设置自定义Delegate,监听滚动的开始和结束事件:
// 在ViewDidLoad或Picker初始化时设置 numberPicker.Delegate = new CustomPickerDelegate(this); // 自定义Delegate类 private class CustomPickerDelegate : UIPickerViewDelegate { private readonly YourViewController _parentVC; public CustomPickerDelegate(YourViewController parentVC) { _parentVC = parentVC; } // 开始滚动时标记状态 public override void DidStartScrolling(UIPickerView pickerView) { _parentVC._isPickerScrolling = true; } // 滚动结束时重置状态 public override void DidEndScrolling(UIPickerView pickerView) { _parentVC._isPickerScrolling = false; } }
第三步:实现按钮点击事件
在按钮的TouchUpInside事件里,编写停止滚动和获取值的逻辑:
stopButton.TouchUpInside += (sender, e) => { if (_isPickerScrolling) { // 计算当前Picker视觉中心对应的行索引 var centerInView = numberPicker.ConvertPointFromView(View.Center, View); var firstRowRect = numberPicker.RectForRow(0); var rowHeight = firstRowRect.Height; var rowIndex = (int)((centerInView.Y - firstRowRect.Top) / rowHeight); // 确保索引在数据源的合法范围内 rowIndex = Math.Clamp(rowIndex, 0, numberList.Count - 1); // 强制选中该行,停止滚动(第三个参数设为false是立即停止,true是平滑停止) numberPicker.SelectRow(rowIndex, 0, false); } // 获取最终选中的值 var selectedRowIndex = numberPicker.SelectedRowInComponent(0); var selectedValue = numberList[selectedRowIndex]; // 这里可以把值展示出来,比如赋值给Label或者打印 Console.WriteLine($"Picker停止后的值:{selectedValue}"); };
3. 关键细节说明
- 滚动状态判断:通过
DidStartScrolling和DidEndScrolling标记滚动状态,避免在Picker静止时执行无效操作。 - 行索引计算:利用Picker的行高度和视觉中心点位置,精准计算出用户看到的中间行,确保停止的位置符合预期。
- SelectRow的作用:调用这个方法不仅能选中指定行,还会打断Picker的滚动状态,无论是立即停止还是平滑停止都能满足需求。
如果你的Picker是多列的,只需要把代码里的0(代表第一列)换成对应的列索引即可,逻辑是完全通用的。
内容的提问来源于stack exchange,提问作者gowtham T
相关产品推荐
相关产品推荐

