如何将带有完成按钮的工具栏添加到 UIPickerView?

Posted

技术标签:

【中文标题】如何将带有完成按钮的工具栏添加到 UIPickerView?【英文标题】:How to add ToolBar with done button to UIPickerView? 【发布时间】:2017-11-24 09:35:09 【问题描述】:

我想在 Xamarin.ios 项目中有一个 UIPickerView。我需要的 UIPicker 必须是这样的(默认隐藏并带有工具栏和完成按钮):

这是 Xamarin.forms 的一个示例!

我已经看到了关于堆栈溢出的所有问题,但它们不是我的情况,或者它们不是为此目的的完整解释。

为了证明我已经尝试过创建完成工具栏,这是我的代码:

public class TestPickerViewController : UIViewController
    
        PickerModel picker_model;
        UIPickerView picker;

        public TestPickerViewController()

        
            Title = Texts.Home;
            View.BackgroundColor = UIColor.White;
            this.EdgesForExtendedLayout = UIRectEdge.None;

        

        public override void DidReceiveMemoryWarning()
        
            // Releases the view if it doesn't have a superview.
            base.DidReceiveMemoryWarning();

            // Release any cached data, images, etc that aren't in use.
        

        public override void ViewDidLoad()
        
            base.ViewDidLoad();

            List<Object> state_list = new List<Object>();
            state_list.Add("1");
            state_list.Add("2");
            state_list.Add("3");
            state_list.Add("4");
            picker_model = new PickerModel(state_list);

            picker = new UIPickerView();
            picker.Model = picker_model;
            picker.ShowSelectionIndicator = true;



            UIToolbar toolbar = new UIToolbar();
            toolbar.BarStyle = UIBarStyle.Black;
            toolbar.Translucent = true;
            toolbar.SizeToFit();

            UIBarButtonItem doneButton = new UIBarButtonItem("Done", UIBarButtonItemStyle.Done, (s, e) =>
            
                foreach (UIView view in this.View.Subviews)
                
                    if (view.IsFirstResponder)
                    
                        UITextField textview = (UITextField)view;
                        textview.Text = picker_model.values[(int)picker.SelectedRowInComponent(0)].ToString();
                        textview.ResignFirstResponder();
                    
                

            );
            toolbar.SetItems(new UIBarButtonItem[]  doneButton , true);


            View.AddSubviews(picker);

            //How to add toolbar, action for opening toolbar and hide by default the list 
        

        public override void ViewDidLayoutSubviews()
        
            base.ViewDidLayoutSubviews();
            View.SubviewsDoNotTranslateAutoresizingMaskIntoConstraints();

            View.AddConstraints(

                picker.AtTopOf(View, 90),
                picker.AtLeftOf(View, 50),
                picker.WithSameWidth(View).Minus(100)
            );
        


        private void SetPicker(object sender, EventArgs e)
        
            UITextField field = (UITextField)sender;
            picker.Select(picker_model.values.IndexOf(field.Text), 0, true);
        
    

    public class PickerModel : UIPickerViewModel
    
        public IList<Object> values;

        public event EventHandler<PickerChangedEventArgs> PickerChanged;

        public PickerModel(IList<Object> values)
        
            this.values = values;
        

        public override nint GetComponentCount(UIPickerView picker)
        
            return 1;
        

        public override nint GetRowsInComponent(UIPickerView picker, nint component)
        
            return values.Count;
        

        public override string GetTitle(UIPickerView picker, nint row, nint component)
        
            return values[(int)row].ToString();
        

        public override nfloat GetRowHeight(UIPickerView picker, nint component)
        
            return 40f;
        

        public override void Selected(UIPickerView picker, nint row, nint component)
        
            if (this.PickerChanged != null)
            
                this.PickerChanged(this, new PickerChangedEventArgs  SelectedValue = values[(int)row] );
            
        
    

    public class PickerChangedEventArgs : EventArgs
    
        public object SelectedValue  get; set; 
    

我知道我必须将工具栏添加到已完成按钮的某处。而且我还需要隐藏默认选择器并在我们单击选择部分等时显示列表的操作...

【问题讨论】:

【参考方案1】:

只需将UIToolbar 分配给UITextFieldInputAccessoryView 属性即可。下面是一个代码 sn-p 示例:

UIToolbar toolBar = new UIToolbar(new CGRect(0, 0, 320, 44));
UIBarButtonItem flexibleSpaceLeft = new UIBarButtonItem(UIBarButtonSystemItem.FlexibleSpace,null,null);
UIBarButtonItem doneButton = new UIBarButtonItem("OK",UIBarButtonItemStyle.Done,this, new ObjCRuntime.Selector("DoneAction"));
UIBarButtonItem[] list = new UIBarButtonItem[]  flexibleSpaceLeft, doneButton ;
toolBar.SetItems(list, false);

UIPickerView pickerView = new UIPickerView(new CGRect(0, 44, 320, 216));
pickerView.DataSource = new MyUIPickerViewDataSource();
pickerView.Delegate = new MyUIPickerViewDelegate();
pickerView.ShowSelectionIndicator = true;

//Assign the toolBar to InputAccessoryView 
textField.InputAccessoryView = toolBar;

textField.InputView = pickerView;

并像这样实现Action:

    [Export("DoneAction")]
    private void DoneAction()
    
        Console.WriteLine("Your Action!");
    

它是这样工作的:

【讨论】:

您知道如何在单击“确定”按钮后隐藏 Picker 吗? 辞职UITextField第一响应者:textField.ResignFirstResponder(); 完美!再次感谢:) KevinLi 最后一个问题!我保证;)我已经向 TextField 添加了一个 RightView,但是当我单击它(这是一个底部箭头图标)时,它什么也不做,你有什么想法将我的 TextField 的相同操作定义/复制到 RightView 吗? 只需在 RightView 的点击动作中添加textField.BecomeFirstResponder(); 行即可。

以上是关于如何将带有完成按钮的工具栏添加到 UIPickerView?的主要内容,如果未能解决你的问题,请参考以下文章

使用工具栏按钮更改 UIPickerView 值

组件与工具栏和pickerview冲突[关闭]

UIPickerView 工具栏按钮不起作用

自动向下滚动到下一个 UITextField

如何向 UINavigationBar 添加按钮

仅在单击完成按钮时将 UIPickerView 选择添加到 TextField