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....