【问题标题】:UIDatePicker with toolbar but without text field带有工具栏但没有文本字段的 UIDatePicker
【发布时间】:2021-09-14 04:18:39
【问题描述】:

在我的应用程序中,我有一个按钮,单击该按钮应显示带有工具栏的时间选择器。我看到的大多数示例都将工具栏添加为文本字段上的 inputAccessoryView,但在我的情况下,我没有文本字段。

因此,我创建了一个自定义视图,其中包含日期时间选择器和工具栏,我将该视图作为子视图添加到我的控制器视图中,但我在应用程序上看不到自定义视图。

以下是点击按钮的控制器代码:

func buttonClicked(date: Date) {
    let timePicker = EditTimeHelper.createTimePickerAndToolbar(displayDate: date)
    self.view.addSubview(timePicker)
}

单独的 EditTimeHelper 类中的自定义视图代码:

  static func createTimePickerAndToolbar(displayDate: Date) -> UIView {
        let pickerView = UIView(frame: CGRect(x: 0, y: UIScreen.main.bounds.height - 300, width: UIScreen.main.bounds.width, height: 300))
        let timePicker = createTimePicker(displayDate: displayDate)
        pickerView.addSubview(timePicker)
        let toolbar = createUIToolBar()
        pickerView.addSubview(toolbar)
        return pickerView
    }
    
    static func createTimePicker(displayDate: Date) -> UIDatePicker {
        let timePicker:UIDatePicker = UIDatePicker()
        timePicker.datePickerMode = UIDatePicker.Mode.time
        timePicker.date = displayDate
        timePicker.minuteInterval = 15
        if #available(iOS 13.4, *) {
            timePicker.preferredDatePickerStyle = .wheels
        } else {
            // Fallback on earlier versions where time picker is wheels style by default.
        }
        timePicker.addTarget(self, action: #selector(timeChanged(_:)), for: UIControl.Event.valueChanged)
        timePicker.backgroundColor = .white
        timePicker.frame = CGRect(x: 0, y: UIScreen.main.bounds.height - 200, width: UIScreen.main.bounds.width, height: 200)
        return timePicker
    }
    
    private static func createUIToolBar() -> UIToolbar {
        let pickerToolbar = UIToolbar()
        pickerToolbar.autoresizingMask = .flexibleHeight
        
        //customize the toolbar
        pickerToolbar.barStyle = .default
        pickerToolbar.barTintColor = UIColor.black
        pickerToolbar.backgroundColor = UIColor.white
        pickerToolbar.isTranslucent = false
        
        pickerToolbar.frame = CGRect(x: 0, y: UIScreen.main.bounds.height - 300, width: UIScreen.main.bounds.width, height: 100)
        // add buttons
        let cancelButton = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(cancelBtnClicked(_:)))
        cancelButton.tintColor = UIColor.white
        let flexSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
        let doneButton = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(doneBtnClicked(_:)))
        doneButton.tintColor = UIColor.white
        
        //add the items to the toolbar
        pickerToolbar.items = [cancelButton, flexSpace, doneButton]
        return pickerToolbar
    }
    
    @objc func timeChanged(_ sender: UIDatePicker) {
       
    }
    
    @objc func cancelBtnClicked(_ button: UIBarButtonItem?) {
        
    }
    
    @objc func doneBtnClicked(_ button: UIBarButtonItem?) {
        
    }

知道我做错了什么并且没有看到自定义视图吗?

如果我调用EditTimeHelper.createTimePicker(displatDate: date),我会看到时间选择器,但我想在它上面添加工具栏。

当我调试此代码时,我确实将时间选择器和工具栏视为自定义视图的子视图,但我只是在应用程序上看不到它们。

【问题讨论】:

  • 您创建选择器的方法被声明为静态的。没有实例 self 可分配给您的日期选择器。

标签: ios swift uidatepicker


【解决方案1】:

您看不到选择器和工具栏的原因是您将时间选择器和工具栏定位不正确。注意这两行:

timePicker.frame = CGRect(x: 0, y: UIScreen.main.bounds.height - 200, width: UIScreen.main.bounds.width, height: 200)
// and
pickerToolbar.frame = CGRect(x: 0, y: UIScreen.main.bounds.height - 300, width: UIScreen.main.bounds.width, height: 100)

由于这些是pickerView 的子视图,坐标相对于pickerView 的左上角,而不是屏幕的左上角。你应该这样做

timePicker.frame = CGRect(x: 0, y: 100, width: UIScreen.main.bounds.width, height: 200)
// and
pickerToolbar.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 100)

现在您应该会看到工具栏和时间选择器。

但是,您的代码还有其他问题。首先,timeChangedcancelBtnClickeddoneBtnClicked 不会被调用。您已将self 添加为栏按钮项和选择器的目标,但由于您处于静态方法中,self 指的是类本身。当用户按下完成按钮时,它会尝试调用 class 上名为 doneBtnClicked 的方法,而不是特定实例。但是类没有这样的方法!您声明的doneBtnClicked 是一个实例方法,仅在实例上可用。

第二,你给这些视图固定的位置。这意味着当用户旋转屏幕时布局看起来会很奇怪。 只需使用 AutoLayout!

您也可以将timeChangedcancelBtnClickeddoneBtnClicked 都设为static,但更好的方法是创建一个自定义UIView 子类。这是一个示例,作为起点:

class TimePickerToolBarView: UIView {
    override init(frame: CGRect) {
        super.init(frame: frame)
        commonInit()
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        commonInit()
    }
    
    private func commonInit() {
        let timePicker = createTimePicker()
        addSubview(timePicker)
        let toolBar = createUIToolBar()
        addSubview(toolBar)
        timePicker.translatesAutoresizingMaskIntoConstraints = false
        toolBar.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            toolBar.heightAnchor.constraint(equalToConstant: 44),
            toolBar.topAnchor.constraint(equalTo: topAnchor),
            toolBar.leftAnchor.constraint(equalTo: leftAnchor),
            toolBar.rightAnchor.constraint(equalTo: rightAnchor),
            timePicker.leftAnchor.constraint(equalTo: leftAnchor),
            timePicker.rightAnchor.constraint(equalTo: rightAnchor),
            timePicker.bottomAnchor.constraint(equalTo: bottomAnchor),
            timePicker.topAnchor.constraint(equalTo: toolBar.bottomAnchor),
        ])
    }
    
    private func createTimePicker() -> UIDatePicker {
        let timePicker:UIDatePicker = UIDatePicker(frame: .zero)
        timePicker.datePickerMode = UIDatePicker.Mode.time
        timePicker.minuteInterval = 15
        if #available(iOS 13.4, *) {
            timePicker.preferredDatePickerStyle = .wheels
        } else {
            // Fallback on earlier versions where time picker is wheels style by default.
        }
        timePicker.addTarget(self, action: #selector(timeChanged(_:)), for: UIControl.Event.valueChanged)
        timePicker.backgroundColor = .white
        return timePicker
    }
    
    private func createUIToolBar() -> UIToolbar {
        let pickerToolbar = UIToolbar(frame: .zero)
        
        //customize the toolbar
        pickerToolbar.barStyle = .default
        pickerToolbar.barTintColor = UIColor.black
        pickerToolbar.backgroundColor = UIColor.white
        pickerToolbar.isTranslucent = false
        // add buttons
        let cancelButton = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(cancelBtnClicked(_:)))
        cancelButton.tintColor = UIColor.white
        let flexSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
        let doneButton = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(doneBtnClicked(_:)))
        doneButton.tintColor = UIColor.white
        
        //add the items to the toolbar
        pickerToolbar.items = [cancelButton, flexSpace, doneButton]
        return pickerToolbar
    }
    
    @objc func timeChanged(_ sender: UIDatePicker) {
       
    }
    
    @objc func cancelBtnClicked(_ button: UIBarButtonItem?) {
        
    }
    
    @objc func doneBtnClicked(_ button: UIBarButtonItem?) {
        
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-12-23
    • 1970-01-01
    • 1970-01-01
    • 2015-10-09
    • 2015-10-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多