首页 > 解决方案 > 如何将新的日期选择器 iOS 14 居中 - Swift

问题描述

有没有办法让这个日期选择器居中?它在我的 UIAlertController 上设置为 ContentViewController。我希望它在中心

标签: swiftdatepickeruidatepicker

解决方案


对于任何感兴趣的人,我都可以使用 StackViews 将其集中在 UIAlertController 的 ContentViewController

final class DatePickerViewController: UIViewController {
  
  private var completion: ((Date)->Void)? = nil
  
  lazy var datePicker: UIDatePicker = { [weak self] in
    let dp = UIDatePicker()
    dp.addTarget(self, action: #selector(DatePickerViewController.actionForDatePicker), for: .valueChanged)
    return dp
  }()
  
  required init(mode: UIDatePicker.Mode, date: Date = Date(), completion: ((Date)->Void)? = nil) {
    super.init(nibName: nil, bundle: nil)
    datePicker.datePickerMode = mode
    datePicker.date = date
    self.completion = completion
  }
  
  required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
  }
  
  deinit {
    Log.info("De-Init Date Picker VC")
  }
  
  override func loadView() {
    if #available(iOS 13.4, *) {
      let spacerViewLeading = UIView()
      let spacerViewTrailing = UIView()
      
      let sv = UIStackView(arrangedSubviews: [spacerViewLeading, datePicker, spacerViewTrailing])
      sv.axis = .horizontal
      sv.distribution = .fill
      
      datePicker.centerXAnchor.constraint(equalTo: sv.centerXAnchor).isActive = true
      view = sv
      
      if datePicker.datePickerMode == .dateAndTime {
        spacerViewLeading.widthAnchor.constraint(equalTo: spacerViewTrailing
                                                  .widthAnchor, constant: ((datePicker.frame.width - view.frame.width)/2) - 10).isActive = true
      } else if datePicker.datePickerMode == .time || datePicker.datePickerMode == .date {
        sv.distribution = .fillEqually
      }
    } else {
      view = datePicker
    }
  }
  
  @objc func actionForDatePicker() {
    completion?(datePicker.date)
  }
}

Alert 上的 Helper 方法将其添加到 UIVlertView 的 ContentViewController:

  extension UIAlertController {
    func setContentViewController(vc: UIViewController, height: CGFloat? = nil) {
      setValue(vc, forKey: "contentViewController")
        
      if let height = height {
        vc.preferredContentSize.height = height
        preferredContentSize.height = height
      }
    }
  }

在行动:

let alert = UIAlertController(title: "This is an alert", message: "This is the message", preferredStyle: .alert)
let datePickerVc = DatePickerViewController(mode: UIDatePicker.Mode.dateAndTime)
datePickerVc.datePicker.date = (Calendar.current as NSCalendar).date(bySettingHour: 7, minute: 0, second: 0, of: Date(), options: .matchFirst) ?? Date()
alert.setContentViewController(vc: datePickerVc)

推荐阅读