为什么我不能在表格视图中选择一行?

时间:2018-10-10 05:16:31

标签: ios uitableview

我对此感到困惑。我无法在iOS的表格视图中选择任何行。表格视图滚动很好。我已经以编程方式设置了可能影响此问题的所有属性。

这是我的代码:

tableView.dataSource = self
tableView.delegate = self

tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 44

tableView.allowsSelection = true
tableView.isUserInteractionEnabled = true


class MessageTableViewCell: UITableViewCell {

    @IBOutlet weak var labelTitle: UILabel!
    @IBOutlet weak var textViewBody: UITextView!

    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code

        self.isUserInteractionEnabled = true

    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
    }

}

更新:

我能够选择一行-最后一行。然后我不再允许我再次选择任何行。

这是我的整个课堂,不包括导入语句:

class CreateMessagesViewController: UIViewController {

    @IBOutlet weak var tableView: UITableView!
    @IBOutlet weak var viewControls: UIView!
    @IBOutlet weak var toolbarCopyMessage: UIToolbar!
    @IBOutlet weak var barButtonCopyMessage: UIBarButtonItem!
    @IBOutlet weak var labelTitle: UILabel!
    @IBOutlet weak var textFieldTitle: UITextField!
    @IBOutlet weak var labelBody: UILabel!
    @IBOutlet weak var textViewBody: UITextView!
    @IBOutlet weak var toolbarCreateMessage: UIToolbar!
    @IBOutlet weak var barButtonCreateMessage: UIBarButtonItem!
    @IBOutlet var bottomLayoutConstraint: NSLayoutConstraint!

    let privateDatabase = CKContainer.default().privateCloudDatabase

    var messages = [UTIMessage]()

    // MARK: - View

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

        tableView.dataSource = self
        tableView.delegate = self

        tableView.rowHeight = UITableViewAutomaticDimension
        tableView.estimatedRowHeight = 44

        tableView.allowsSelection = true
        tableView.isUserInteractionEnabled = true

        let predicate = NSPredicate(value: true)
        let query = CKQuery(recordType: DatabaseNameStrings.recordTypeMessage, predicate: predicate)

        privateDatabase.perform(query, inZoneWith: nil) {

            records, error in

            if error != nil {

                print(error!.localizedDescription)

            } else {

                for record in records! {

                    let utiMessage = UTIMessage(ckRecord: record)

                    self.messages.append(utiMessage)

                }

                DispatchQueue.main.async {

                    self.tableView.reloadData()

                }

            }

        }

    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        let defaultCenter = NotificationCenter.default

        defaultCenter.addObserver(self, selector: #selector(self.keyboardWillShow), name: NSNotification.Name.UIKeyboardWillShow, object: nil)

        defaultCenter.addObserver(self, selector: #selector(self.keyboardWillHide), name: NSNotification.Name.UIKeyboardWillHide, object: nil)

        defaultCenter.addObserver(self, selector: #selector(self.keyboardDidHide), name: NSNotification.Name.UIKeyboardDidHide, object: nil)

    }

    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)

        let defaultCenter = NotificationCenter.default

        defaultCenter.removeObserver(self)

    }

    // MARK: - Actions

    @IBAction func actionDone(_ sender: UIBarButtonItem) {

        dismiss(animated: true, completion: nil)

    }

    @IBAction func actionCopyMessage(_ sender: UIBarButtonItem) {

        guard let indexPathForSelectedRow = tableView.indexPathForSelectedRow else {

            let alertMessage = "You must select a message from the list."

            let alert = UIAlertController(title: nil, message: alertMessage, preferredStyle: .alert)

            let actionOK = UIAlertAction(title: "OK", style: .cancel, handler: nil)

            alert.addAction(actionOK)

            present(alert, animated: true, completion: nil)

            return

        }

        let message = messages[indexPathForSelectedRow.row]

        textFieldTitle.text = message.title
        textViewBody.text = message.body

    }

    @IBAction func actionCreateMessage(_ sender: UIBarButtonItem) {

        guard let messageTitle = textFieldTitle.text else {

            let alertMessage = "You must enter a title for the message."

            let alert = UIAlertController(title: nil, message: alertMessage, preferredStyle: .alert)

            let actionOK = UIAlertAction(title: "OK", style: .cancel, handler: nil)

            alert.addAction(actionOK)

            present(alert, animated: true, completion: nil)

            return

        }

        guard let messageBody = textViewBody.text else {

            let alertMessage = "You must enter a message body."

            let alert = UIAlertController(title: nil, message: alertMessage, preferredStyle: .alert)

            let actionOK = UIAlertAction(title: "OK", style: .cancel, handler: nil)

            alert.addAction(actionOK)

            present(alert, animated: true, completion: nil)

            return

        }

        let newCKRecordMessage = CKRecord(recordType: DatabaseNameStrings.recordTypeMessage)

        newCKRecordMessage.setObject(messageTitle as CKRecordValue, forKey: DatabaseNameStrings.fieldNameTitle)

        newCKRecordMessage.setObject(messageBody as CKRecordValue, forKey: DatabaseNameStrings.fieldNameBody)

        privateDatabase.save(newCKRecordMessage) {

            record, error in

            if error != nil {

                print("Error saving record:", error!.localizedDescription)

            } else {

                print("Record saved successfully.")

            }

        }

        let newUTIMessage = UTIMessage(ckRecord: newCKRecordMessage)

        messages.append(newUTIMessage)
        let indexPathNewMessage = IndexPath(row: messages.count - 1, section: 0)
        tableView.insertRows(at: [indexPathNewMessage], with: .automatic)

        textFieldTitle.text = nil
        textViewBody.text = nil

        textFieldTitle.resignFirstResponder()
        textViewBody.resignFirstResponder()

    }

    @IBAction func selectRow(_ sender: Any) {

        let indexPath = IndexPath(row: 0, section: 0)

        tableView.selectRow(at: indexPath, animated: true, scrollPosition: .top)

    }

    // MARK: - Keyboard

    @objc func keyboardWillShow(_ sender: Notification) {

        print("keyboardWillShow(_:)")

        let keyboardSize = (sender.userInfo![UIKeyboardFrameEndUserInfoKey] as! NSValue).cgRectValue

        var offset = keyboardSize.height

        if offset > keyboardSize.height {

            offset = keyboardSize.height

        }

        self.bottomLayoutConstraint.isActive = false

        self.bottomLayoutConstraint = NSLayoutConstraint(item: view, attribute: .bottom, relatedBy: .equal, toItem: viewControls, attribute: .bottom, multiplier: 1, constant: offset + 4)
        self.bottomLayoutConstraint.isActive = true

        print("\ty: \(self.view.frame.origin.y)")

    }

    @objc func keyboardWillHide(_ sender: Notification) {

        print("keyboardWillHide(_:)")

        self.bottomLayoutConstraint.isActive = false

        self.bottomLayoutConstraint = NSLayoutConstraint(item: view, attribute: .bottom, relatedBy: .equal, toItem: viewControls, attribute: .bottom, multiplier: 1, constant: 4)
        self.bottomLayoutConstraint.isActive = true

    }

    @objc func keyboardDidHide(_ sender: Notification) {

        print("keyboardDidHide(_:)")

        textFieldTitle.resignFirstResponder()
        textViewBody.resignFirstResponder()

    }

}

// MARK: - UITableViewDataSource

extension CreateMessagesViewController: UITableViewDataSource {

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

        return messages.count

    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let cell = tableView.dequeueReusableCell(withIdentifier: "messageCell", for: indexPath) as! MessageTableViewCell

        let message = messages[indexPath.row]

        cell.labelTitle.text = message.title
        cell.textViewBody.text = message.body

        return cell

    }

}

// MARK: - UITableViewDelegate

extension CreateMessagesViewController: UITableViewDelegate {

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

        print("didSelectRowAt")

    }

}

1 个答案:

答案 0 :(得分:0)

我修复了它。文本视图没有通过touchesBegan事件传递,因此我将文本字段的class属性设置为具有以下定义的自定义类:

class TextViewWithTouches: UITextView {

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        super.touchesBegan(touches, with: event)

        next?.touchesBegan(touches, with: event)

    }

    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        super.touchesMoved(touches, with: event)

        next?.touchesMoved(touches, with: event)

    }

    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        super.touchesEnded(touches, with: event)

        next?.touchesEnded(touches, with: event)

    }

    override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
        super.touchesCancelled(touches, with: event)

        next?.touchesCancelled(touches, with: event)

    }

}