Is there a way that I can set the textField type from a FieldCell without creating a CustomCell/Row?
I'm trying to implement a PhoneRow with a cell that has a textField with mask. I'm trying to do this with AKMaskField, but to do that I have to set my textField's class as an AKMaskField instead of UITextField. And I don't wanna create a CustomCell because I would like to keep the default design to all rows.
FieldRow.swift
public protocol TextInputCell {
var textInput : UITextInput { get }
}
public protocol TextFieldCell: TextInputCell {
var textField: UITextField { get }
}
public class _FieldCell<T where T: Equatable, T: InputTypeInitiable> : Cell<T>, UITextFieldDelegate, TextFieldCell {
lazy public var textField : UITextField = {
let textField = UITextField()
textField.translatesAutoresizingMaskIntoConstraints = false
return textField
}()
...
}
AKMAskField is a UITextField. Have you tried to set textField = AKMaskField() in cellSetup? You would just have yo cast it later to use it but it should work
Yes, I tried. Here's my setup:
PhoneRow.defaultCellSetup = { cell, row in
let tf = AKMaskField(frame: cell.textField.frame)
tf.mask = "(dd) dddd-dddd"
tf.maskTemplate = "(dd) dddd-dddd"
cell.textField = tf
}
But when I do that I get the following error at runtime execution:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Unable to parse constraint format:
Unable to interpret '|' character, because the related view doesn't have a superview
V:|-11-[textField]-11-|
And it crashes my app.
What you are lacking is a cell.contentView.addSubView(tf).
And maybe you have to remove cell.textField before changing it...
@ramonilho Could you fix this?
as @mats-claassen said, you should remove the text field before setting up textField property, then you should also add it to content view since cell's updateConstraints() method makes use of it.
How's the final solution, please?
To complete your great answer I'd like to say that you should also add this line in the setup closure:
tf.translatesAutoresizingMaskIntoConstraints = false
Here is an example using the great format-as-you-type PhoneNumberKit PhoneNumberTextField() combined with an Eureka PhoneRow:
.cellSetup{ cell, row in
// Remove original textField from cell so we can then replace it with an as-you-type phone formatting field
cell.textField.removeFromSuperview()
// Add as-you-type phone formatting field
let tf = PhoneNumberTextField()
tf.translatesAutoresizingMaskIntoConstraints = false
cell.textField = tf
cell.contentView.addSubview(tf)
}
.onCellHighlightChanged({ (phoneCell, phoneRow) in
phoneRow.value = phoneCell.textField.text
})
Also note that the row value has to be explicitly set for example in onCellHighlightChanged
@JosselinOudry Thanks! It works very well with one issue! The onCellHighlightChange is only called when the PhoneRow has resigned as the first responder. But if one finished typing number in the field and then directly clicked the save button, this method won't be called. I was trying to use the onChange method, but it doesn't have the phoneCell argument. Do you know how to solve this?
Updated with my solution
Move the phoneField definition to the class level, and call for the phoneField.text directly in retrieving the data.
let phoneField = PhoneNumberTextField()
in viewDidLoad()
// Remove original textField from cell so we can then replace it with an as-you-type phone formatting field
<<< PhoneRow(phoneLabel) {
$0.title = phoneLabel
$0.title = phoneLabel
$0.value = ""
}.cellSetup{ cell, row in
cell.textField.removeFromSuperview()
// Add as-you-type phone formatting field
self.phoneField.translatesAutoresizingMaskIntoConstraints = false
cell.textField = self.phoneField
cell.contentView.addSubview(self.phoneField)
}
`
Most helpful comment
To complete your great answer I'd like to say that you should also add this line in the setup closure:
tf.translatesAutoresizingMaskIntoConstraints = falseHere is an example using the great format-as-you-type PhoneNumberKit PhoneNumberTextField() combined with an Eureka PhoneRow:
Also note that the row value has to be explicitly set for example in onCellHighlightChanged