IOS 中的 Xamarin 表单选择器不会换行

Posted

技术标签:

【中文标题】IOS 中的 Xamarin 表单选择器不会换行【英文标题】:Xamarin Forms Picker in IOS will not wrap 【发布时间】:2020-07-13 16:38:51 【问题描述】:

我正在尝试在 Xamarin 表单中制作自定义渲染器,以便选择器中的文本将为 ios 换行。安卓运行良好。从周围阅读看来,我需要使用 UIPickerViewDelegate 来执行此操作。但是,当我这样做时.. 拾取器的损坏程度比以前更严重,并且基本上无法使用。如果我使用委托,那么选择器渲染得很好,但是当你选择一些东西时。任何事物。它始终是第一个被选中的项目。选择第 10 项,UI 显示第 1 项。您选择哪个项目并不重要。不知何故,选择器总是认为它是第一个。我没有故意做任何事情来影响所选项目。感觉就像我应该做的其他事情这些其他解决方案没有告诉我。

这是我的渲染器:

public class CustomPickerRenderer : PickerRenderer 

protected override void OnElementChanged(ElementChangedEventArgs<Picker> e) 
  base.OnElementChanged(e);
  if (Control != null) 
    ((UIPickerView)Control.InputView).Delegate = new CustomPickerViewDelegate();
  


protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e) 
  base.OnElementPropertyChanged(sender, e);
  if (e.PropertyName.Equals("itemssource", StringComparison.InvariantCultureIgnoreCase)) 
    ((Control.InputView as UIPickerView).Delegate as CustomPickerViewDelegate).ItemSource = Element.ItemsSource;
  

这是我的 UIPickerViewDelegate

public class CustomPickerViewDelegate: UIPickerViewDelegate 

public IList ItemSource  get; set; 

public override UIView GetView(UIPickerView pickerView, nint row, nint component, UIView view) 
  UILabel label = new UILabel();
  label.Text = ItemSource[(int)row].ToString();
  label.Lines = 0;
  label.LineBreakMode = UILineBreakMode.WordWrap;

  return label;


public override nfloat GetRowHeight(UIPickerView pickerView, nint component) 
  return 48;

【问题讨论】:

嗨,你能分享两张图片来解释想要的节目和当前节目吗? 好的。我想要的其实很简单。我希望选择器能够选择第一个以外的项目。这怎么不清楚?使用上面的代码,无论选择什么,每次选择都会导致第一个被选择的项目。 STR 是字面意思。 1. 点击 Picker 2. 随意选择任何东西 3. 注意你的选择不是被选中的。它始终是第一个项目。当我想要的是: 1. 点击 Picker 2. 随机选择任何东西 3. 观察 picker 已经选择了我选择的项目。 我把上面的代码放在一个全新的项目中,这个项目没有从 VS2019 股票 xamarin 表单模板修改,它已经坏了。我必须在委托中遗漏一些东西。 感谢您的解释。我只是想检查一下包裹效果是否是我的想法。 【参考方案1】:

我检查了本地站点的部分代码,还发现单击Done按钮后没有设置选定的值。为了解决这个问题,我们需要自定义一个 UIToolbar 来覆盖系统。

另外,当滚动结束时,无法自动选择该值。我们需要在CustomPickerViewDelegate中添加Selected覆盖方法来设置ControlUITextField)的选择值。

CustomPickerRenderer的完整代码如下:

[assembly: ExportRenderer(typeof(Picker), typeof(CustomPickerRenderer))]
namespace MonkeyApp.iOS

    public class CustomPickerRenderer : PickerRenderer
    
        List<string> itemList;
        protected override void OnElementChanged(ElementChangedEventArgs<Picker> e)
        
            base.OnElementChanged(e);
            if (Control != null)
            

                //Control.BackgroundColor = UIColor.Red;

                UITextField textField = Control;
           
                UIPickerView pickerView = textField.InputView as UIPickerView;

                Picker myPicker = Element;
                itemList = myPicker.Items.ToList();

                pickerView.Delegate = new CustomPickerViewDelegate(itemList, textField);

                UIToolbar toolbar = new UIToolbar(new CoreGraphics.CGRect(0,0,UIScreen.MainScreen.Bounds.Size.Width,44));
                UIBarButtonItem spaceItem = new UIBarButtonItem(UIBarButtonSystemItem.FlexibleSpace);
                UIBarButtonItem doneButtonItem = new UIBarButtonItem(UIBarButtonSystemItem.Done);
                doneButtonItem.Clicked += DoneButtonItem_Clicked;
                var bbs = new UIBarButtonItem[]  spaceItem, doneButtonItem ;
                toolbar.SetItems(bbs, false);
                Control.InputAccessoryView = toolbar;
            
        

        private void DoneButtonItem_Clicked(object sender, EventArgs e)
        
            Control.ResignFirstResponder();
        
    

    internal class CustomPickerViewDelegate : UIPickerViewDelegate
    
        private List<string> itemList;
        private UITextField textField;

        public CustomPickerViewDelegate(List<string> itemList, UITextField textField)
        
            this.itemList = itemList;
            this.textField = textField;
        

        public override UIView GetView(UIPickerView pickerView, nint row, nint component, UIView view)
        
            UILabel label = new UILabel();
            label.Text = itemList[(int)row];
            label.Lines = 0;
            label.LineBreakMode = UILineBreakMode.WordWrap;

            return label;
        

        public override nfloat GetRowHeight(UIPickerView pickerView, nint component)
        
            return 48;
        

        public override void Selected(UIPickerView pickerView, nint row, nint component)
        
            textField.Text = itemList[(int)row];
        
    

效果:

【讨论】:

这似乎有效!谢谢!移动开发新手,我已经为此苦苦挣扎了一段时间!非常感谢!

以上是关于IOS 中的 Xamarin 表单选择器不会换行的主要内容,如果未能解决你的问题,请参考以下文章

Xamarin.iOS 中的文件选择器

使用本机库中的功能的 Xamarin 表单应用程序

绑定 xamarin 表单选择器值的正确方法

xamarin 表单中的 datepicker 和 timepicker 多次触发 Focus 和 Unfocus 事件

xamarin 表单信号器核心客户端处理程序不在 ios 上执行,但在 android 上执行

创建自定义导航栏渲染器以在 xamarin 表单 IOS 项目中添加自定义后退按钮图标