选择器渲染器 height/placement 调整?

Picker renderer height/placement adjustment?

我是 Xamrin.Forms 编程新手。我想自定义 'Picker' 视图控件。上图中有:

-带有文本 'Select' 的按钮(单击时调用 picker.Focus()),
- select 按钮后面有黑色背景和文本颜色的选择器,
-空列表视图,
-The picker options wheel pane, pops up when a picker is 'Focused'

如何 a) 将滚轮窗格移动到空白 ListView 中,或者 b) 加长滚轮窗格的高度(以覆盖更多屏幕)?通过 PS 的示例:

Picker renderer 实现代码,如下(@Land 提供):

[assembly: ExportRenderer(typeof(MyPicker), typeof(MyPickerRenderer))]
namespace AppName.iOS
{
    public class MyPickerRenderer : PickerRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<Picker> e)
        {
            base.OnElementChanged(e);

            UITextField textField = Control;
            UIPickerView pickerView = textField.InputView as UIPickerView;
            Picker myPicker = Element;
            List<string> itemList;
            itemList = myPicker.Items.ToList();
            pickerView.Delegate = new MyPickerViewDelegate(itemList);
        }
    }

    public class MyPickerViewDelegate : UIPickerViewDelegate
    {
        List<string> itemList;

        public MyPickerViewDelegate(List<string> list)
        {
            itemList = list;
        }

        //Define the Font size or style
        public override NSAttributedString GetAttributedTitle(UIPickerView pickerView, nint row, nint component)
        {
            var text = new NSAttributedString(
                itemList[(int)row],
                font: UIFont.SystemFontOfSize(12),
                foregroundColor: UIColor.Black,
                strokeWidth: 1
            );

            return text;
        }

        //Define the row height
        public override nfloat GetRowHeight(UIPickerView pickerView, nint component)
        {
            return 20;
        }

        //Customize more flexible (including placement) use following method:

        public override UIView GetView(UIPickerView pickerView, nint row, nint component, UIView view)
        {
            UIView contentView = new UIView(new CGRect(
                0, 0, UIScreen.MainScreen.Bounds.Size.Width, UIScreen.MainScreen.Bounds.Size.Height));

            UILabel label = new UILabel();
            label.Frame = contentView.Bounds;
            contentView.AddSubview(label);

            label.Text = itemList[(int)row];
            //Change the label style
            label.Font = UIFont.SystemFontOfSize(12);
            label.TextColor = UIColor.Black;
            label.TextAlignment = UIKit.UITextAlignment.Center;

            return contentView;
        }
    }

}

a) move the wheel pane into the blank ListView

根据设计,UITextField 的 inputView 将从底部飞入视图。如果你确实想把它放在你的 ListView 中。您可以尝试创建一个新控件而不是 Picker。

b) lengthen the height of the wheel pane (to cover more of the screen)?

是的,我们可以通过设置 inputView 的框架来做到这一点:

UIPickerView pickerView = textField.InputView as UIPickerView;
textField.InputView.Frame = new CGRect(0, 0, 320, 320);

但是当我们这样做时,它会与 inputAccessoryView 重叠(带有用于选择项目的 "Done" 按钮)。所以我们也需要自定义这个视图:

UIView accessoryView = new UIView(new CGRect(100, 100, 320, 144));
UIButton btn = new UIButton(UIButtonType.System);
btn.SetTitle("Done", UIControlState.Normal);
btn.AddTarget((sender, args) =>
{
    textField.Text = itemList[(int)(pickerView.SelectedRowInComponent(0))];
    textField.ResignFirstResponder();
}, UIControlEvent.TouchUpInside);
accessoryView.AddSubview(btn);
//Place the button at super view's top, right position.
btn.TranslatesAutoresizingMaskIntoConstraints = false;
accessoryView.AddConstraint(NSLayoutConstraint.Create(btn, NSLayoutAttribute.Trailing, NSLayoutRelation.Equal, accessoryView, NSLayoutAttribute.Trailing, 1, -10));
accessoryView.AddConstraint(NSLayoutConstraint.Create(btn, NSLayoutAttribute.Top, NSLayoutRelation.Equal, accessoryView, NSLayoutAttribute.Top, 1, 5));

textField.InputAccessoryView = accessoryView;

调整CGRect()的最后一个参数满足你加长轮盘高度的要求(我测试InputView的默认高度是220左右, InputAccessoryView的大约是44个。相应调整。