【问题标题】:Programmatically added UITextField - Keyboard causes app to crash on first key press - Swift以编程方式添加 UITextField - 键盘导致应用程序在第一次按键时崩溃 - Swift
【发布时间】:2016-01-29 19:25:49
【问题描述】:

我有一个“TextInputCell”类,它继承自 UITableViewCell,代表一个包含 UITextField 的 UITableViewCell。在视图控制器中使用此类将“TextInputCell”添加到 UITableView 的一行时,我将委托设置为视图控制器本身,并且委托函数为空(除了返回语句) - 我将在下面发布。运行应用程序时,文本字段完全按照我想要的方式显示,并允许我单击文本字段并弹出键盘,但是当我按下键盘上的 any 键时,应用程序崩溃错误Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSNull length]: unrecognized selector sent to instance 0x110277af0'。我尝试在没有我创建的类的情况下将常规 UITextField 添加到单元格中,但我得到了同样的错误。有谁知道为什么会发生这种情况或我该如何解决?

TextInputCell 类:

//
//  TextInputCell.swift
//  AdminApp
//
//  Created by Cooper Watts on 2016-01-27.
//  Copyright © 2016 DefineYoga. All rights reserved.

//
//  Based on the DatePickerCell.swift Created by Dylan Vann

import Foundation
import UIKit

/**
 * Text Input Cell for table views.
 */
public class TextInputCell: UITableViewCell {

    var textField: UITextField!

    /**
     Creates the TextInputCell

     - parameter style:           A constant indicating a cell style. See UITableViewCellStyle for descriptions of these constants.
     - parameter reuseIdentifier: A string used to identify the cell object if it is to be reused for drawing multiple rows of a table view. Pass nil if the cell object is not to be reused. You should use the same reuse identifier for all cells of the same form.

     - returns: An initialized TextInputCell object or nil if the object could not be created.
     */
    override public init(style: UITableViewCellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)

        setup()
    }

    private func setup() {
        // The InputField overhangs the view slightly to avoid invalid constraints.
        self.clipsToBounds = true

        textField = UITextField(frame: CGRect(x: 0, y: 15, width: self.contentView.frame.size.width - 15.0, height: self.contentView.frame.size.height))

        textField.placeholder = "PlaceHolder"

        textField.autoresizingMask = [.FlexibleRightMargin, .FlexibleLeftMargin, .FlexibleBottomMargin, .FlexibleTopMargin]
        textField.translatesAutoresizingMaskIntoConstraints = true

        self.contentView.addSubview(textField)

    }

    /**
     Needed for initialization from a storyboard.
     - parameter aDecoder: An unarchiver object.
     - returns: An initialized TextInputeCell object or nil if the object could not be created.
     */
    required public init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        setup()
    }

    /**
     Update the placeholder specific to the Input Field
     - Parameter placeholder: the place holder for the input field
     */
    public func updatePlaceHolder(placeholder: String) {
        textField.placeholder = placeholder
    }

}

以及分配委托和委托方法等时的视图控制器。

//Configure the Text Input Cells
var clientNameInput = TextInputCell(style: UITableViewCellStyle.Default, reuseIdentifier: nil)
var invoiceEmailInput = TextInputCell(style: UITableViewCellStyle.Default, reuseIdentifier: nil)
var invoiceAddressInput = TextInputCell(style: UITableViewCellStyle.Default, reuseIdentifier: nil)
var amountChargedInput = TextInputCell(style: UITableViewCellStyle.Default, reuseIdentifier: nil)

在 viewDidLoad() 中:

clientNameInput.textField.delegate = self
invoiceEmailInput.textField.delegate = self
invoiceAddressInput.textField.delegate = self
amountChargedInput.textField.delegate = self

clientNameInput.updatePlaceHolder(mainOptions[0])
invoiceEmailInput.updatePlaceHolder(mainOptions[1])
invoiceAddressInput.updatePlaceHolder(mainOptions[2])
amountChargedInput.updatePlaceHolder(billingOptions[0])

以及委托功能:

/*UITextField Delegate Methods*/

func textFieldDidBeginEditing(textField: UITextField) {
}
func textFieldDidEndEditing(textField: UITextField) {
}
func textFieldShouldBeginEditing(textField: UITextField) -> Bool {
    return true;
}
func textFieldShouldClear(textField: UITextField) -> Bool {
    return true;
}
func textFieldShouldEndEditing(textField: UITextField) -> Bool {
    return true;
}
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
    return true;
}
func textFieldShouldReturn(textField: UITextField) -> Bool {
    textField.resignFirstResponder()
    return true;
}

然后我将 TextInputCells 添加到表中,如下所示:

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

        //Assigns UIDatePickerView and UIPickerView cells
        if(indexPath.section == 0 && mainOptions[indexPath.row] == mainOptions[0]) {

            return clientNameInput as UITableViewCell

        } else if(indexPath.section == 0 && mainOptions[indexPath.row] == mainOptions[1]) {

            return invoiceEmailInput as UITableViewCell

        } else if(indexPath.section == 0 && mainOptions[indexPath.row] == mainOptions[2]) {

            return invoiceAddressInput as UITableViewCell

        } //etc....

【问题讨论】:

标签: ios swift uitableview uitextfield


【解决方案1】:

通过添加All Exceptions 断点应该很容易看出是什么导致了这个错误。让应用程序崩溃,调试器将在即将抛出异常时停止。您将能够看到引发异常的确切代码行,并且您可以使用调试器查看应用程序的状态。 这是一个显示如何添加断点的 gif:

【讨论】:

  • 它停在这一行:class AppDelegate: UIResponder, UIApplicationDelegate - 在 AppDelegate.swift 文件中
【解决方案2】:

OP 说:

它停在这一行:class AppDelegate: UIResponder, UIApplicationDelegate

我遇到了同样的失败,这是因为我试图实现一种方法来处理 Enter 按键,但我删除了与之关联的 @IBAction。 然后,后来当我运行应用程序时它崩溃了。

我从 IB 操作 UI 事物(如上所示)中删除了该条目,重新构建并运行,一切正常。

【讨论】:

    【解决方案3】:

    原来它与损坏的故事板或 .xib 文件有关,该问题已通过删除标签栏控制器并创建一个具有新配置关系的新控制器来解决。找到了答案here

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-29
      • 1970-01-01
      • 2015-05-13
      • 1970-01-01
      相关资源
      最近更新 更多