Search code examples
iosswifteureka-forms

How can I create a custom TextCell and TextRow that has a subclass of UITextField in it?


I am using Eureka Forms and SearchTextField.

In my form, I want to have something very similar as the (Eureka) built-in TextRow. The difference is that this custom TextRow will use a SearchTextField instead of the regular UITextField.

I first thought that I could copy all the code related to TextRow and TextCell and rename the classes a bit. However, I find the code in _FieldRow quite hard to understand and I don't know exactly what code I should copy.

Then I saw that I could set the cellProvider property to provide a custom cell:

<<< TextRow() {
    $0.cellProvider = CellProvider<TextCell>(nibName: "NewCustomCell", bundle: .main)
    $0.title = "TextRow"
}

So I thought I just need an xib file. I tried to find the xib file that Eureka uses for its TextCell so that I can copy it and edit it slightly but I couldn't find a single xib file under the Pods/Eureka directory. Then I tried to make my own xib file.

After adding a table view cell, I set its class to TextCell because I need a CellProvider<TextCell>. Then I tried to connect the text fields and labels to the IBOutlets in _FieldCell (this is what I'm supposed to do, right?) but the outlets just don't show up. I changed the class to _FieldCell and they showed up properly, but I can't pass a nib with a _FieldCell into a CellProvider<TextCell>, can I?

To reiterate my goal: create a form cell that has a SearchTextField as the text field and behaves the same as TextCell for everything else.


Solution

  • You need to use custom rows and cells.. something like this

    class _SearchTextFieldCell<T>: _FieldCell<T> where T: Equatable, T: InputTypeInitiable {
    
        required init(style: UITableViewCellStyle, reuseIdentifier: String?) {
    
            super.init(style: style, reuseIdentifier: reuseIdentifier)
    
            self.textField.removeFromSuperview()
    
            let searchTextField = SearchTextField()
            searchTextField.translatesAutoresizingMaskIntoConstraints = false
            contentView.addSubview(searchTextField)
            self.textField = searchTextField
        }
    
        required init?(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
    }
    
    class SearchTextCell: _SearchTextFieldCell<String>, CellType {
    
        required public init(style: UITableViewCellStyle, reuseIdentifier: String?) {
            super.init(style: style, reuseIdentifier: reuseIdentifier)
        }
    
        required public init?(coder aDecoder: NSCoder) {
            super.init(coder: aDecoder)
        }
    
        open override func setup() {
            super.setup()
        }
    }
    
    class _SearchTextRow: FieldRow<SearchTextCell> {
    
        public required init(tag: String?) {
            super.init(tag: tag)
        }
    }
    
    final class SearchTextRow: _SearchTextRow, RowType {
    
        required public init(tag: String?) {
            super.init(tag: tag)
        }
    }
    

    then you can use the custom row with

    <<< SearchTextRow() {
    
        $0.title = "Search"
    
        guard let tf = $0.cell.textField as? SearchTextField else {
            return
        }
    
        tf.filterStrings(["lorem", "ipsum", "dolor", "sit", "amet"])
    }