在UIPickerView中添加按钮 - Swift 1.2

6
我想在 UIPickerView 上方添加两个 UIButtons。请参考下面这张图片中的 CancelDone 按钮:

enter image description here

我该如何实现?

3个回答

27

我已经解决了这个问题,Swift语言的答案如下:

var pickerView = UIPickerView(frame: CGRectMake(0, 200, view.frame.width, 300))
pickerView.backgroundColor = .whiteColor()
pickerView.showsSelectionIndicator = true

var toolBar = UIToolbar()
toolBar.barStyle = UIBarStyle.Default
toolBar.translucent = true
toolBar.tintColor = UIColor(red: 76/255, green: 217/255, blue: 100/255, alpha: 1)
toolBar.sizeToFit()


let doneButton = UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.Bordered, target: self, action: "donePicker")
let spaceButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.FlexibleSpace, target: nil, action: nil)
let cancelButton = UIBarButtonItem(title: "Cancel", style: UIBarButtonItemStyle.Bordered, target: self, action: "canclePicker")

toolBar.setItems([cancelButton, spaceButton, doneButton], animated: false)
toolBar.userInteractionEnabled = true

textField.inputView = pickerView
textField.inputAccessoryView = toolBar

你在哪里声明了 "textLabel"?这是由你的UIPickerView选择填充的标签吗? - davidrayowens
1
TextLabel 是一个 UILabel outlet,因此当您尝试“编辑”标签时,pickerView 将出现。 - Dejan Skledar
请问您是如何将所选名称写入文本字段的?@DejanSkledar - CAN
pickerView有一个名为selectedRowInComponent的方法,可以获取所选行的索引,然后你只需要这样做:textField.text = yourData[indexOrSelectedRow]。 - Dejan Skledar
@DejanSkledar,你是如何实现那些自定义操作的UIBarButtonItems(donePicker和cancelPicker)的呢?语法是什么样子的? - A. Vin
显示剩余3条评论

2

看我的。我有收藏视图和 UIPicker 来选择照片文件夹。

输入图像描述

//MARK:- SHOW PHOTO FOLDER BUTTON METHOD
@IBAction func photoFolderListButtonClicked(sender: UIButton) {
    self.navigationItem.setHidesBackButton(true, animated: true)

    //Making PickerView of Competitors
    let DEVICE_SCREEN_WIDTH =    UIScreen.mainScreen().bounds.size.width
    photoFolderListPicker.frame = CGRectMake(0.0, 44.0, DEVICE_SCREEN_WIDTH, 260)
    photoFolderListPicker.dataSource = self
    photoFolderListPicker.delegate = self
    photoFolderListPicker.showsSelectionIndicator = true;
    photoFolderListPicker.backgroundColor = UIColor.whiteColor()

    let pickerDateToolbar = UIToolbar(frame: CGRectMake(0, 0, DEVICE_SCREEN_WIDTH, 44))
    pickerDateToolbar.barStyle = UIBarStyle.Black
    pickerDateToolbar.barTintColor = UIColor.blackColor()
    pickerDateToolbar.translucent = true

    //Cancel button on photoFolderListPicker
    let barItems = NSMutableArray()
    let labelCancel = UILabel()
    labelCancel.text = " Cancel"

    let titleCancel = UIBarButtonItem(title: labelCancel.text, style: UIBarButtonItemStyle.Plain, target: self, action: Selector("cancelPickerSelectionButtonClicked:"))
    titleCancel.tintColor = UIColor.whiteColor()
    barItems.addObject(titleCancel)

    var flexSpace: UIBarButtonItem
    flexSpace = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.FlexibleSpace, target: self, action: nil)
    barItems.addObject(flexSpace)

    //Done Button on photoFolderListPicker
    let doneBtn = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Done, target: self, action: Selector("photoFolderSelectionDone:"))
    barItems.addObject(doneBtn)
    doneBtn.tintColor = UIColor.whiteColor()

    pickerDateToolbar.setItems(barItems as [AnyObject] as? [UIBarButtonItem], animated: true)
    actionView.addSubview(pickerDateToolbar)
    actionView.addSubview(photoFolderListPicker)

    if (window != nil) {
        window!.addSubview(actionView)
    }
    else {
        self.view.addSubview(actionView)
    }
    UIView.animateWithDuration(0.2, animations: {
        self.actionView.frame = CGRectMake(0, UIScreen.mainScreen().bounds.size.height - 250.0, UIScreen.mainScreen().bounds.size.width, 250)
    })
}
//MARK:- PICKERVIEW DELEGATE METHODS
func pickerView(_pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
    return model.documentFolders.count
}
func numberOfComponentsInPickerView(_pickerView: UIPickerView) -> Int {
    return 1
}
func pickerView(_pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String! {
    return model.documentFolders[row].value
}
//MARK:- PICKERVIEW BUTTON METHODS
func cancelPickerSelectionButtonClicked(sender: UIBarButtonItem) {
    self.navigationItem.setHidesBackButton(false, animated: true)

    UIView.animateWithDuration(0.2, animations: {
        self.actionView.frame = CGRectMake(0, UIScreen.mainScreen().bounds.size.height, UIScreen.mainScreen().bounds.size.width, 210.0)
        }, completion: { _ in
            for obj: AnyObject in self.actionView.subviews {
                if let view = obj as? UIView
                {
                    view.removeFromSuperview()
                }
            }
    })
    photoFolderListButton.setTitle(" "+"Select Folder", forState: UIControlState.Normal)
}
func photoFolderSelectionDone(sender: UIBarButtonItem) {
    uploadedPhotoFolderName?.isEmpty
    loadedFromPageSection = "fromPhotoFolderSelectionDone"
    self.disableScoutDetailUserInterfaceElementsDutingApiCall()

    //setting selectedPhotoFolderItem and selectedPhotoFolderItemId
    let myRow = photoFolderListPicker.selectedRowInComponent(0)
    selectedPhotoFolderItem =  model.documentFolders[myRow].value!
    selectedPhotoFolderItemId = Int(model.documentFolders[myRow].key!)

    UIView.animateWithDuration(0.2, animations: {
        self.actionView.frame = CGRectMake(0, UIScreen.mainScreen().bounds.size.height, UIScreen.mainScreen().bounds.size.width, 260.0)
        }, completion: { _ in
            for obj: AnyObject in self.actionView.subviews {
                if let view = obj as? UIView
                {
                    view.removeFromSuperview()
                }
            }
    })
    photoFolderListButton.setTitle(" "+(selectedPhotoFolderItem as? String)!, forState: UIControlState.Normal)
    self.view.makeToastActivityWithMessage(message: "Fetching")

    //Delegate is added to class after popViewControllerAnimated(true) called
    model.delegate = self

    //API CALL - Fetching Photos
    AppController().fetchPropertyPhotosGallery(hbId, propertyId: scoutPropertyId, fileTypeId: selectedPhotoFolderItemId)

}

1

以下是我在ObjC中添加带有按钮的选择器弹出框到文本字段的方法。翻译成Swift应该很简单。基本上,您需要创建选择器并将其分配给文本输入视图inputView。然后,您需要创建一个工具栏,并将其分配给文本输入附加视图inputAccessoryView,当它弹出时,它位于inputView的顶部。

self.manufacturerPicker = [[UIPickerView alloc] initWithFrame:CGRectZero];
self.manufacturerPicker.delegate = self;
self.manufacturerPicker.dataSource = self;
[self.manufacturerPicker setShowsSelectionIndicator:YES];
self.filterByManufacturerTextField.inputView = self.manufacturerPicker;

UIToolbar *manufacturerPickerToolbar=[[UIToolbar alloc] init];
manufacturerPickerToolbar.barStyle = UIBarStyleBlack;
manufacturerPickerToolbar.translucent = YES;
manufacturerPickerToolbar.tintColor = nil;
[manufacturerPickerToolbar sizeToFit];

UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithTitle:@"Done"
                                                                style:UIBarButtonItemStyleBordered target:self
                                                              action:@selector(manufacturerPickerDoneClicked:)];
UIBarButtonItem *spacerButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
UIBarButtonItem *cancelButton = [[UIBarButtonItem alloc] initWithTitle:@"Cancel"
                                                                style:UIBarButtonItemStyleBordered target:self
                                                               action:@selector(manufacturerPickerCancelClicked:)];

[manufacturerPickerToolbar setItems:@[cancelButton,spacerButton,doneButton]];
self.filterByManufacturerTextField.inputAccessoryView = manufacturerPickerToolbar;

针对没有 UITextField 作为起点的更新:

如果你想从单元格中启动一个选择器,就像文本字段选择器一样,我认为你必须让你的 UITableViewCell 实现成为第一响应者的过程。

为此,我认为这个过程是在你的单元格中实现 UIResponder 协议。

1) 重写 canBecomeFirstResponder 方法并返回 YES。

2) 重写 inputView 属性的 getter 方法。在此代码中返回你的 UIPickerView。

§3) 重写 inputAccessoryView 属性的 getter 方法。在此代码中返回你的 UIToolbar。

现在,在你的单元格中,当你选择该单元格时,通过调用 [self becomeFirstResponder]; 使该单元格成为第一响应者。

我认为这应该会正确地显示选择器和工具栏。可能还有更多细节需要注意。

在取消或完成后,使用 [self resignFirstResponder]; 将其关闭。

我之前没有做过这个,但我想这是一般步骤。

选项 2(作弊):

有时作弊更容易。在单元格后面添加一个隐藏的UITextField或添加一个宽度为0的UITextField。根据原始建议设置其inputView和inputAccessoryView。
然后当您选择单元格时,只需使用[self.<your text field property> becomeFirstResponder];使UITextField成为第一个响应者。
这样就可以通过后门获得相同的结果。

我尝试了这个,但在Swift 1.2上似乎不起作用:/ 它什么也没显示出来。 - Dejan Skledar
你是从哪里启动选择器的?UITextView还是其他什么地方?此外,如果你只使用模拟器,那么会有一个bug,如果在模拟器中设置了硬件键盘,弹出式选择器将无法正常显示。在模拟器菜单中取消勾选Hardware -> Keyboard -> Connect Hardware Keyboard,然后再试一下你的代码。否则,你能否发布你的设置代码? - Rory McKinnel
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Dejan Skledar
这是否意味着您的初始问题添加按钮已解决?如果是,请接受此答案,我将转向新问题;否则,您将在两个运行的问题中遇到相同的问题。 - Rory McKinnel
很遗憾,我仍然无法将UIPickerView与UIToolBar一起呈现。在另一个问题中,我尝试使用addSubView方法,而在这个问题中,我正在尝试使用inputAccessoryView方法... - Dejan Skledar
更新答案,提供了处理非UITextField作为选择器启动的建议。有两种方法:适当的机制和一个我认为可以让您快速运行的欺骗机制。 - Rory McKinnel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接