使用 UIButton 实现 UIDatePicker 和 UIPickerView

Posted

技术标签:

【中文标题】使用 UIButton 实现 UIDatePicker 和 UIPickerView【英文标题】:Implementing UIDatePicker and UIPickerView with a UIButton 【发布时间】:2016-04-11 17:18:00 【问题描述】:

我正在一个 ios 应用程序中实现一个用户表单,它同时使用 UIPickerViewUIDatePicker 作为用户的输入设备。我已经将其中的每一个实现为场景中主 UIViewController 外部的视图,并通过添加和删除约束让它们显示和隐藏使用 autolayout

这是我的问题:我正在维护单独的约束和隐藏/显示方法,以便为这些视图中的每一个设置进出动画。这是很多重复代码,我觉得必须有一种更简洁的方法来做到这一点,因为它似乎是 iOS 应用程序中非常常见的设计模式。我对此很陌生,所以我觉得我错过了一些东西。

有没有比这更好的设计模式来为 UIButtons 使用多个输入设备??

这是我用来维护它的代码示例...

var datePickerViewBottomConstraint: NSLayoutConstraint!
var datePickerViewTopConstraint: NSLayoutConstraint!
var storagePickerViewBottomConstraint: NSLayoutConstraint!
var storagePickerViewTopConstraint: NSLayoutConstraint!

@IBAction func storageButtonClicked(sender: UITextField) 

    storagePickerView.translatesAutoresizingMaskIntoConstraints = false
    storagePickerViewBottomConstraint = storagePickerView.bottomAnchor.constraintEqualToAnchor(view.bottomAnchor)

    UIView.animateWithDuration(0.4, animations: 
        self.storagePickerViewTopConstraint.active = false
        self.storagePickerViewBottomConstraint.active = true
    self.view.layoutIfNeeded()
    )


@IBAction func datePumpedClicked(sender: UIButton) 

    datePickerView.translatesAutoresizingMaskIntoConstraints = false
    datePickerViewBottomConstraint = datePickerView.bottomAnchor.constraintEqualToAnchor(view.bottomAnchor)

    UIView.animateWithDuration(0.4, animations: 
        self.datePickerViewTopConstraint.active = false
        self.datePickerViewBottomConstraint.active = true
        self.view.layoutIfNeeded()
    )


@IBAction func datePickerDismiss(sender: AnyObject) 
    datePumpedLabel.setTitle(Global.dateFormatter.stringFromDate(datePicker.date), forState: UIControlState.Normal)

    datePickerView.translatesAutoresizingMaskIntoConstraints = false
    datePickerViewTopConstraint = datePickerView.topAnchor.constraintEqualToAnchor(view.bottomAnchor)

    UIView.animateWithDuration(0.4, animations: 
        self.datePickerViewBottomConstraint.active = false
        self.datePickerViewTopConstraint.active = true
        self.view.layoutIfNeeded()
    )  


@IBAction func storagePickerDismiss(sender: AnyObject) 

    storagePickerView.translatesAutoresizingMaskIntoConstraints = false
    storagePickerViewTopConstraint = storagePickerView.topAnchor.constraintEqualToAnchor(view.bottomAnchor)

    UIView.animateWithDuration(0.4, animations: 
        self.storagePickerViewBottomConstraint.active = false
        self.storagePickerViewTopConstraint.active = true
        self.view.layoutIfNeeded()
    )       

这是我的故事板的屏幕截图... Storyboard

【问题讨论】:

【参考方案1】:

你们,我想出了一个更好的方法!

我最初缺少的是,当您从超级视图中删除视图时,所有约束都将被删除。这让事情变得容易多了。

我为当前正在显示的视图保留了 1 个约束类变量,因此视图可以在不适当的位置进行动画处理。

我还添加了一个“设置”功能来获得viewdidload() 上的视图。如果没有这个,视图将始终在第一次出现时从顶部开始动画(无法解决这个问题)。

这是我使用的:

var secondaryMenuBottomConstraint: NSLayoutConstraint!

func setupSecondaryMenu(secondaryMenu: UIView)

    secondaryMenu.translatesAutoresizingMaskIntoConstraints = false

    let topConstraint = secondaryMenu.topAnchor.constraintEqualToAnchor(view.bottomAnchor)
    let leftConstraint = secondaryMenu.leftAnchor.constraintEqualToAnchor(view.leftAnchor)
    let rightConstraint = secondaryMenu.rightAnchor.constraintEqualToAnchor(view.rightAnchor)

    view.addSubview(secondaryMenu)
    NSLayoutConstraint.activateConstraints([topConstraint, leftConstraint, rightConstraint])
    self.view.layoutIfNeeded()
    secondaryMenu.removeFromSuperview()



func showSecondaryMenu(secondaryMenu: UIView)
    //Close any open keyboards
    amountTextField.resignFirstResponder()
    notesTextField.resignFirstResponder()

    //Add the view and then add constraints to show the submenu below the current view
    secondaryMenu.translatesAutoresizingMaskIntoConstraints = false
    let topConstraint = secondaryMenu.topAnchor.constraintEqualToAnchor(view.bottomAnchor)
    let leftConstraint = secondaryMenu.leftAnchor.constraintEqualToAnchor(view.leftAnchor)
    let rightConstraint = secondaryMenu.rightAnchor.constraintEqualToAnchor(view.rightAnchor)

    view.addSubview(secondaryMenu)
    NSLayoutConstraint.activateConstraints([topConstraint, leftConstraint, rightConstraint])

    secondaryMenuBottomConstraint = secondaryMenu.bottomAnchor.constraintEqualToAnchor(view.bottomAnchor)

    //animate the view up into place
    UIView.animateWithDuration(0.4, animations: 
        topConstraint.active = false
        self.secondaryMenuBottomConstraint.active = true
        self.view.layoutIfNeeded()
    )


func dismissSecondaryMenu(secondaryMenu: UIView)
    if secondaryMenu.superview != nil 
        secondaryMenu.translatesAutoresizingMaskIntoConstraints = false
        let secondaryMenuTopConstraint = secondaryMenu.topAnchor.constraintEqualToAnchor(view.bottomAnchor)
        self.secondaryMenuBottomConstraint.active = false

        UIView.animateWithDuration(0.4, animations: 
            secondaryMenuTopConstraint.active = true

            self.view.layoutIfNeeded()
        , completion: (finished:Bool) in
                secondaryMenu.removeFromSuperview()
        )
    

【讨论】:

以上是关于使用 UIButton 实现 UIDatePicker 和 UIPickerView的主要内容,如果未能解决你的问题,请参考以下文章

如何实现UIButton的小型Dropdown,例如在Swift 4和iOS 11中选择货币?

UIButton上图下文、左文右图实现(附分类方法)

图像上的触摸事件,通过使用 UIButton 实现,但与 UIImageView 相比显示延迟

如何同时实现两个UIButton?

如何捕获 UIButton 事件:在自定义 UITableViewCell 实现中添加了 UIButton

在使用自定义 UITableViewCell 时检测 UIButton