我不能使用回调作为完成处理程序在类之间传递数据。

问题描述 投票:0回答:1

我想把自定义类中textField的文本传递给ViewController,并在DatePicker的BarButtonItem被点击时将其填充到数组中。我使用了一个回调作为完成处理程序,但它捕获了EXC-BAD-ACCESS。是什么原因导致了这个错误,我如何才能将文本传递给我的ViewController?

  • 自定义textField类
class HourDatePicker: UITextField {

    var datePicker =  UIDatePicker()

    override init(frame: CGRect) {
        super.init(frame: frame)
        commominit()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        commominit()
    }

    func commominit(){
        text = ""
        datePicker.datePickerMode = .dateAndTime
        datePicker.minuteInterval = 30
        datePicker.locale = Locale(identifier: "ja")
        datePicker.addTarget(self, action: #selector(setText), for: .valueChanged)
        setText()
        inputView = datePicker
        inputAccessoryView = customPicker()
     }

    @objc func setText(){
        let f = DateFormatter()
        f.dateStyle = .full
        f.timeStyle = .short
        f.locale = Locale(identifier: "ja")
        textColor = .black
        text = "\(f.string(from: datePicker.date))"

    }
    private func customPicker() -> UIToolbar {
        let toolbar = UIToolbar()
        toolbar.frame = CGRect(x: 0, y: 0, width: self.frame.size.width, height: 40)
        let space = UIBarButtonItem(barButtonSystemItem: .fixedSpace, target: self, action: nil)
        space.width = 100
        let flexSpaceItem = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: self, action: nil)
        let todayButtonItem = UIBarButtonItem(title: "today", style: .done, target: self, action: #selector(setToday))
        let selectButtonItem = UIBarButtonItem(title: "select", style: .done, target: self, action: #selector(tellCalenderText))

        let toolbarItem = [space, flexSpaceItem, todayButtonItem, selectButtonItem]
         toolbar.setItems(toolbarItem, animated: true)
        }
        return toolbar
    }

    @objc func tellCalenderText(completion: ((_ titleText: String) -> Void)){
        //I want to pass text here.
        if text != "" {
        guard let titleText = text else {return}
        completion(titleText)
        } else {
            return
        }

    }
  • 视图控制器
class Calender1ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    private let selectDate = HourDatePicker()
    private var keepDate: [String] = []

    @IBOutlet weak var timeTextView: UITextView!
    @IBOutlet weak var dateText: HourDatePicker!
    @IBOutlet weak var calenderTableView: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()
        self.calenderTableView.delegate = self
        self.calenderTableView.dataSource = self

        selectDate.tellCalenderText {[weak self] (titleText) in
            self?.bringDate(title: titleText)
        }


    }

    func bringDate(title: String){

        print("title: \(title)")
        self.keepDate.append(title)
        timeTextView.text.append(contentsOf: "\(title)\n")

    }

谢谢你。

这是错误日志。错误日志

ios swift callback swift5
1个回答
0
投票

首先,我认为你的做法有点混乱,因为你有。

private let selectDate = HourDatePicker()

和... 有。

@IBOutlet weak var dateText: HourDatePicker!

然后利用 selectDate 里面 viewDidLoad()...

试试这个。我只做了一些修改,并试图包含足够的评论来使其清晰。我想你会发现这是个更直接的方式来获得你的自定义的东西。HourDatePicker 类将信息传回视图控制器。

class HourDatePicker: UITextField {

    var datePicker =  UIDatePicker()

    override init(frame: CGRect) {
        super.init(frame: frame)
        commominit()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        commominit()
    }

    func commominit(){
        text = ""
        datePicker.datePickerMode = .dateAndTime
        datePicker.minuteInterval = 30
        datePicker.locale = Locale(identifier: "ja")
        datePicker.addTarget(self, action: #selector(setText), for: .valueChanged)
        setText()
        inputView = datePicker
        inputAccessoryView = customPicker()
    }

    @objc func setToday(){
        datePicker.date = Date()
    }

    @objc func setText(){
        let f = DateFormatter()
        f.dateStyle = .full
        f.timeStyle = .short
        f.locale = Locale(identifier: "ja")
        textColor = .black
        text = "\(f.string(from: datePicker.date))"

    }
    private func customPicker() -> UIToolbar {
        let toolbar = UIToolbar()
        toolbar.frame = CGRect(x: 0, y: 0, width: self.frame.size.width, height: 40)
        let space = UIBarButtonItem(barButtonSystemItem: .fixedSpace, target: self, action: nil)
        space.width = 100
        let flexSpaceItem = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: self, action: nil)
        let todayButtonItem = UIBarButtonItem(title: "today", style: .done, target: self, action: #selector(setToday))
        let selectButtonItem = UIBarButtonItem(title: "select", style: .done, target: self, action: #selector(tellCalenderText))

        let toolbarItem = [space, flexSpaceItem, todayButtonItem, selectButtonItem]
        toolbar.setItems(toolbarItem, animated: true)
        return toolbar
    }

    // "callback" closure
    var tellController: ((String) ->())?

    // triggered by "select" bar button tap
    @objc func tellCalenderText() -> Void {
        // get text from self
        guard let t = text else {
            return
        }
        // execute the callback closure
        tellController?(t)
    }

//  @objc func tellCalenderText(completion: ((_ titleText: String) -> Void)){
//      //I want to pass text here.
//      if text != "" {
//          guard let titleText = text else {return}
//          completion(titleText)
//      } else {
//          return
//      }
//
//  }
}

//ViewController
class Calender1ViewController: UIViewController {

    // not needed
    //private let selectDate = HourDatePicker()

    private var keepDate: [String] = []

    // UITextView connected via Storyboard
    @IBOutlet weak var timeTextView: UITextView!

    // UITextField set to HourDatePicker, connected via Storyboard
    @IBOutlet weak var dateText: HourDatePicker!

    @IBOutlet weak var calenderTableView: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()

        // set the callback closure for the HourDatePicker
        dateText.tellController = { [weak self] (titleText) in
            self?.bringDate(title: titleText)
        }

        // not needed
        //selectDate.tellCalenderText {[weak self] (titleText) in
        //  self?.bringDate(title: titleText)
        //}

    }

    func bringDate(title: String){

        print("title: \(title)")
        self.keepDate.append(title)
        timeTextView.text.append(contentsOf: "\(title)\n")

    }
}
© www.soinside.com 2019 - 2024. All rights reserved.