【问题标题】:Picker renderer height/placement adjustment?选择器渲染器高度/位置调整?
【发布时间】:2018-01-26 18:02:58
【问题描述】:

我是 Xamrin.Forms 编程的新手。我想自定义“选择器”视图控件。上图中有:

-带有文本“选择”的按钮(单击时调用 picker.Focus()),
-选择按钮后面有黑色背景和文本颜色的选择器,
-空列表视图,
- 选择器选项轮窗格,弹出拾取器'聚焦'

时弹出

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

Picker 渲染器实现代码,就像现在一样(由@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;
        }
    }

}

【问题讨论】:

    标签: c# ios xamarin.forms uipickerview


    【解决方案1】:

    a) 将滚轮窗格移动到空白的 ListView 中

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

    b) 加长轮盘的高度(以覆盖更多的 屏幕)?

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

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

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

    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。相应调整)。

    【讨论】:

    • @jtth 因为我们覆盖了选择器,所以应该重置事件。我只是给出一个UI示例,实际上我们应该做很多事情来达到我们的效果。我给你打样,你可以参考this
    • 感谢您的样品。 SelectedIndex 现在正在正确更改。但是我仍然不知道如何在选择器轮窗格顶部覆盖“完成”按钮(默认情况下)。使用您的 Picker 渲染器,我们将 Done 按钮移动到选择器轮上方,而不是将 Done 按钮叠加在轮窗格上。如果这是选择器默认显示的方式,这一定是可能的?
    • @jtth 我知道这可能不是一个完美的解决方案,但是 inputView 是由 Apple 定义的,我们无法更改其功能。我们总是使用它的默认高度。我也知道官方渲染器使用工具栏,除了我们总是使用它。但是达不到你的效果,我把它改成view,你可以修改它的高度和背景颜色。它也可以很好地工作。
    • accessoryView.BackgroundColor = UIColor.FromRGB(207, 212, 218);
    猜你喜欢
    • 1970-01-01
    • 2012-01-08
    • 2018-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-30
    • 1970-01-01
    相关资源
    最近更新 更多