1

I have a "TextInputCell" class that inherits from UITableViewCell and represents a UITableViewCell that contains a UITextField. When using this class in a View Controller to add a "TextInputCell" to a row of a UITableView, I set the delegate to the View Controller itself, and the delegate functions are empty (besides return statements) - which I will post below. When running the app the Text Fields appear exactly as I want them do, and allow me to click in the text field and the keyboard pops up, however the second I press any key on the keyboard the app crashes with error Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSNull length]: unrecognized selector sent to instance 0x110277af0'. I tried just adding a regular UITextField to a cell without the class I made and I get the same error. Does anyone know why this is happening or how I can fix it?

TextInputCell class:

//
//  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
    }

}

And the View Controller when assigning delegates and delegate methods etc..

//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)

In 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])

And delegate functions:

/*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;
}

And I add the TextInputCells to the table like so:

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....
coopwatts
  • 670
  • 1
  • 8
  • 31
  • Learn how to debug a crash by visiting http://www.raywenderlich.com/10209/my-app-crashed-now-what-part-1 – rmaddy Jan 29 '16 at 19:52

3 Answers3

1

It should be easy to see what causes this error by adding an All Exceptions breakpoint. Let the application crash and the debugger will stop just when the exception is about to be thrown. You will be able to see the exact line of code that throws the exception, and you can look at the state of the app by using the debugger. Here's a gif that shows how to add the breakpoint: Adding an "All Exeptions" breakpoint

marosoaie
  • 2,352
  • 23
  • 32
  • It stopped at the line: class AppDelegate: UIResponder, UIApplicationDelegate - in the AppDelegate.swift file – coopwatts Jan 29 '16 at 21:02
1

OP said :

It stopped at the line: class AppDelegate: UIResponder, UIApplicationDelegate

AppDelegate crash

I had this same failure and it was because I had attempted to implement a method to handle the Enter key press but I had removed the @IBAction that was associated with it. ibaction Then, later when I ran the app it crashed.

I deleted the entry from the IB action UI thing (shown above), rebuilt and ran and everything worked fine.

raddevus
  • 8,142
  • 7
  • 66
  • 87
0

Turns out that it was related to a corrupted storyboard or .xib file, The issue was resolved by deleting the Tab Bar controller and creating a new one, with newly configured relationships. The answer was found here.

Community
  • 1
  • 1
coopwatts
  • 670
  • 1
  • 8
  • 31