Iphone UIBUTTON和picker视图

Iphone UIBUTTON和picker视图,iphone,uibutton,uipickerview,Iphone,Uibutton,Uipickerview,我想在用户单击按钮时显示选择器 我对UIButton进行了子类化,并更改了其inputview,使其可写 我跟踪了这个链接 我点击按钮,什么也没发生。如果我将inputview从按钮更改为UITextField,效果会很好。有什么想法吗? 谢谢 Saro属性inputView只是UITextField和UITextView的一部分,而不是UIButton @property (readwrite, retain) UIView *inputView; 尽管您可以使用ui按钮实现同样的效果

我想在用户单击按钮时显示选择器 我对UIButton进行了子类化,并更改了其inputview,使其可写

我跟踪了这个链接

我点击按钮,什么也没发生。如果我将inputview从按钮更改为UITextField,效果会很好。有什么想法吗? 谢谢
Saro

属性
inputView
只是
UITextField
UITextView
的一部分,而不是
UIButton

   @property (readwrite, retain) UIView *inputView;
尽管您可以使用
ui按钮
实现同样的效果

   @property (readwrite, retain) UIView *inputView;
创建一个
UIButton
对象,然后设置一个操作方法,并在UIButton的操作方法中的按钮父视图中添加选择器视图

应该是这样的

-(void) buttonClicked:(id) sender
{
    [self.view addSubview:myPickerView];
}
1) 创建UIButton的子类

h

2) 在视图控制器中设置
inputView
(如果需要也设置
inputAccessoryView
)(到选择器或任何其他自定义视图)

3) 为视图控制器中的按钮创建iAction

- (IBAction)becom:(id)sender {
    [sender becomeFirstResponder];
}
如果要卸下键盘,请按以下按钮:

[button resignFirstResponder];
或在视图控制器中:

[self.view endEditing:YES];

我在Swift 3中就是这样做的(覆盖属性的规则与Objective-C不同)

我想要一个显示日期的按钮,并在点击按钮时从屏幕底部显示日期选择器,以允许用户编辑显示的日期。使用定位在目标按钮上的popover相对容易,但我的应用程序仅限于iPhone(而非iPad),因此UITextField inputView模式似乎更好(在AppStore应用程序上使用,有违反人机界面准则的风险。

按钮子类:

class EditableButton: UIButton {

    // This holds the assigned input view (superclass property is readonly)
    private var customInputView: UIView?

    // We override the superclass property as computed, and actually 
    // store into customInputView: 
    override var inputView: UIView? {
        get {
            return customInputView
        }
        set (newValue) {
            customInputView = newValue
        }
    }

    // Must be able to become first responder in order to 
    // get input view to be displayed:
    override var canBecomeFirstResponder: Bool {
        return true
    }

    // Setup becoming first responder on tap:
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)

        self.addTarget(self, action: #selector(EditableButton.tap(_:)), for: .touchDown)
        // (Not sure if this creates a retain cycle; must investigate)
    }

    @IBAction func tap(_ sender: UIButton) {
        self.becomeFirstResponder()
    }
} 
视图控制器代码:

class ViewController: UIViewController {

    // Set the appropriate subclass in the storyboard too!
    @IBOutlet weak var todayButton: EditableButton!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.

        let datePicker = UIDatePicker()
        datePicker.datePickerMode = .date
        todayButton.inputView = datePicker

        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "yyyy-MM-dd"
        todayButton.setTitle(dateFormatter.string(from: Date()), for: .normal)

        // Also hook an a target/action to the date picker's 
        // valueChanged event, to get notified of the user's input
        datePicker.addTarget(self, action: #selector(ViewController.changeDate(_:)), for: .valueChanged)
    }

    @IBAction func changeDate(_ sender: UIDatePicker) {
        // (update button title with formatted date)
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "yyyy-MM-dd"
        todayButton.setTitle(dateFormatter.string(from: sender.date), for: .normal)  

        // Dismiss picker:
        todayButton.resignFirstResponder()
    }
}
注意: 为简单起见,此代码将在指定日期后立即关闭日期选择器-即,每当您滚动任何控制盘时。这可能不是您想要的:通常,用户每次指定一个组件的日期(年、月等)。此实现不允许用户在解除日期选择器之前完成所有日期组件的指定

理想情况下,您可以添加一个
UIToolbar
作为输入附件视图,并使用一个“完成”按钮关闭输入视图(即,使按钮退出第一响应者)。这需要进一步修改UIButton子类(以适应inputAccessoryView),但应该是可行的


编辑:我可以确认输入附件视图也可以以与输入视图完全相同的方式附加到自定义UIButton子类:

private var customInputAccessoryView: UIView?

override var inputAccessoryView: UIView? {
    get {
        return customInputAccessoryView
    }
    set (newValue) {
        customInputAccessoryView = newValue
    }
}
现在,我这样设置它:

let datePicker = UIDatePicker()
datePicker.datePickerMode = .date
todayButton.inputView = datePicker

let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd"
todayButton.setTitle(dateFormatter.string(from: Date()), for: .normal)

datePicker.addTarget(self, action: #selector(ViewController.changeDate(_:)), for: .valueChanged)

let dateToolbar = UIToolbar(frame: CGRect.zero)
dateToolbar.barStyle = .default

let dateDoneButton = UIBarButtonItem(
        barButtonSystemItem: .done,
        target: self,
        action: #selector(ViewController.dateDone(_:)))
let dateSpacer = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)

dateToolbar.items = [dateSpacer, dateDoneButton]
dateToolbar.sizeToFit()
todayButton.inputAccessoryView = dateToolbar
并采取两种不同的行动:

@IBAction func changeDate(_ sender: UIDatePicker) {
    // Update button title in real time:
    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = "yyyy-MM-dd"
    todayButton.setTitle(dateFormatter.string(from: sender.date), for: .normal)
}

@IBAction func dateDone(_ sender: UIBarButtonItem) {
    // ...but dismiss picker only on 'Done': 
    todayButton.resignFirstResponder()
}
此外,当视图控制器弹出导航时,会调用自定义按钮子类的
deinit()
方法,因此
UIButton
不再(?)保留其目标,或者Swift运行时比我想象的更智能



更新:我创建了一个(Github存储库)。修改它以使用自定义的
UIPickerView
(而不是
UIDatePicker
)应该非常简单。显而易见的(至少对我来说)是如何让它以键盘作为输入视图。

你是说当用户点击按钮时,我不能显示选择器?我试图模仿c#中的组合功能。用户在文本框中输入,然后如果她想查找列表,则按下下拉按钮。这很好。但是我如何显示它呢?我在动作中有myPicker.hidden=否,但我没有看到它。thanks@SaroKhatchatourian:你是否添加了picker作为子视图,并为pickerview设置了框架?是的,我添加了。我做的一件事是将“隐藏”设置为“是”,然后它显示出来。谢谢你的帮助@Saro Khatchatourian:如果答案对您有帮助,请接受。如果父类只有一个getter,则无法设置子类的inputView。您可以将其分配给您自己的变量,但这并没有什么区别。
@IBAction func changeDate(_ sender: UIDatePicker) {
    // Update button title in real time:
    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = "yyyy-MM-dd"
    todayButton.setTitle(dateFormatter.string(from: sender.date), for: .normal)
}

@IBAction func dateDone(_ sender: UIBarButtonItem) {
    // ...but dismiss picker only on 'Done': 
    todayButton.resignFirstResponder()
}