diff options
Diffstat (limited to 'Xamarin.Forms.Platform.iOS/Renderers/PickerRenderer.cs')
-rw-r--r-- | Xamarin.Forms.Platform.iOS/Renderers/PickerRenderer.cs | 180 |
1 files changed, 180 insertions, 0 deletions
diff --git a/Xamarin.Forms.Platform.iOS/Renderers/PickerRenderer.cs b/Xamarin.Forms.Platform.iOS/Renderers/PickerRenderer.cs new file mode 100644 index 00000000..e47d2fa4 --- /dev/null +++ b/Xamarin.Forms.Platform.iOS/Renderers/PickerRenderer.cs @@ -0,0 +1,180 @@ +using System; +using System.ComponentModel; +using System.Drawing; +#if __UNIFIED__ +using UIKit; +#else +using MonoTouch.UIKit; +#endif +#if __UNIFIED__ +using RectangleF = CoreGraphics.CGRect; +using SizeF = CoreGraphics.CGSize; +using PointF = CoreGraphics.CGPoint; + +#else +using nfloat=System.Single; +using nint=System.Int32; +using nuint=System.UInt32; +#endif + +namespace Xamarin.Forms.Platform.iOS +{ + public class PickerRenderer : ViewRenderer<Picker, UITextField> + { + UIPickerView _picker; + + protected override void OnElementChanged(ElementChangedEventArgs<Picker> e) + { + if (e.OldElement != null) + ((ObservableList<string>)e.OldElement.Items).CollectionChanged -= RowsCollectionChanged; + + if (e.NewElement != null) + { + if (Control == null) + { + var entry = new NoCaretField { BorderStyle = UITextBorderStyle.RoundedRect }; + + entry.Started += OnStarted; + entry.Ended += OnEnded; + + _picker = new UIPickerView(); + + var width = UIScreen.MainScreen.Bounds.Width; + var toolbar = new UIToolbar(new RectangleF(0, 0, width, 44)) { BarStyle = UIBarStyle.Default, Translucent = true }; + var spacer = new UIBarButtonItem(UIBarButtonSystemItem.FlexibleSpace); + var doneButton = new UIBarButtonItem(UIBarButtonSystemItem.Done, (o, a) => + { + var s = (PickerSource)_picker.Model; + if (s.SelectedIndex == -1 && Element.Items != null && Element.Items.Count > 0) + UpdatePickerSelectedIndex(0); + UpdatePickerFromModel(s); + entry.ResignFirstResponder(); + }); + + toolbar.SetItems(new[] { spacer, doneButton }, false); + + entry.InputView = _picker; + entry.InputAccessoryView = toolbar; + + SetNativeControl(entry); + } + + _picker.Model = new PickerSource(this); + + UpdatePicker(); + + ((ObservableList<string>)e.NewElement.Items).CollectionChanged += RowsCollectionChanged; + } + + base.OnElementChanged(e); + } + + protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e) + { + base.OnElementPropertyChanged(sender, e); + if (e.PropertyName == Picker.TitleProperty.PropertyName) + UpdatePicker(); + if (e.PropertyName == Picker.SelectedIndexProperty.PropertyName) + UpdatePicker(); + } + + void OnEnded(object sender, EventArgs eventArgs) + { + ((IElementController)Element).SetValueFromRenderer(VisualElement.IsFocusedPropertyKey, false); + } + + void OnStarted(object sender, EventArgs eventArgs) + { + ((IElementController)Element).SetValueFromRenderer(VisualElement.IsFocusedPropertyKey, true); + } + + void RowsCollectionChanged(object sender, EventArgs e) + { + UpdatePicker(); + } + + void UpdatePicker() + { + var selectedIndex = Element.SelectedIndex; + var items = Element.Items; + Control.Placeholder = Element.Title; + var oldText = Control.Text; + Control.Text = selectedIndex == -1 || items == null ? "" : items[selectedIndex]; + UpdatePickerNativeSize(oldText); + _picker.ReloadAllComponents(); + if (items == null || items.Count == 0) + return; + + UpdatePickerSelectedIndex(selectedIndex); + } + + void UpdatePickerFromModel(PickerSource s) + { + if (Element != null) + { + var oldText = Control.Text; + ((IElementController)Element).SetValueFromRenderer(Picker.SelectedIndexProperty, s.SelectedIndex); + Control.Text = s.SelectedItem; + UpdatePickerNativeSize(oldText); + } + } + + void UpdatePickerNativeSize(string oldText) + { + if (oldText != Control.Text) + ((IVisualElementController)Element).NativeSizeChanged(); + } + + void UpdatePickerSelectedIndex(int formsIndex) + { + var source = (PickerSource)_picker.Model; + source.SelectedIndex = formsIndex; + source.SelectedItem = formsIndex >= 0 ? Element.Items[formsIndex] : null; + _picker.Select(Math.Max(formsIndex, 0), 0, true); + } + + class PickerSource : UIPickerViewModel + { + readonly PickerRenderer _renderer; + + public PickerSource(PickerRenderer model) + { + _renderer = model; + } + + public int SelectedIndex { get; internal set; } + + public string SelectedItem { get; internal set; } + + public override nint GetComponentCount(UIPickerView picker) + { + return 1; + } + + public override nint GetRowsInComponent(UIPickerView pickerView, nint component) + { + return _renderer.Element.Items != null ? _renderer.Element.Items.Count : 0; + } + + public override string GetTitle(UIPickerView picker, nint row, nint component) + { + return _renderer.Element.Items[(int)row]; + } + + public override void Selected(UIPickerView picker, nint row, nint component) + { + if (_renderer.Element.Items.Count == 0) + { + SelectedItem = null; + SelectedIndex = -1; + } + else + { + SelectedItem = _renderer.Element.Items[(int)row]; + SelectedIndex = (int)row; + } + _renderer.UpdatePickerFromModel(this); + } + } + } +}
\ No newline at end of file |