Reputation: 886
I'm new to Xamrin.Forms programming. I would like to customize the 'Picker' View control. In the picture above there is:
-Button with the text 'Select' (when clicked calls picker.Focus()),
-Picker with both black background and text colors behind the select button,
-Empty ListView,
-The picker options wheel pane, pops up when a picker is 'Focused'
How to either, a) move the wheel pane into the blank ListView, or, b) lengthen the height of the wheel pane (to cover more of the screen)? Examples via PS:
Picker renderer implementation code, as it is now (provided by @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;
}
}
}
Upvotes: 1
Views: 985
Reputation: 6643
a) move the wheel pane into the blank ListView
It is by design that UITextField's inputView will fly into view from bottom. If you do want to put it in your ListView. You can try to create a new control instead of Picker.
b) lengthen the height of the wheel pane (to cover more of the screen)?
Yes we can do that by setting the inputView's frame like:
UIPickerView pickerView = textField.InputView as UIPickerView;
textField.InputView.Frame = new CGRect(0, 0, 320, 320);
But when we do this, it will overlap the inputAccessoryView(with a "Done" button for selecting items). So we need to customize this view too:
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;
Adjust the last parameter of CGRect()
to satisfy your requirement of lengthen the height of the wheel pane(In my test, the default height of InputView is about 220, of InputAccessoryView is about 44. Adjust them in corresponding).
Upvotes: 2