iOS

Custom picker row in Eureka iOS

Eureka is a framework used to implement form input in iOS. It provides many powerful features which helps creating form more easily. But this framework does not support very well for some specific case, for example, custom picker row. So in this post I’ll provide a solution to solve this problem.

Normally Eurek does support us to custom UI to a row by using cellProvider :

<<< PostalAddressRow() {
     $0.cellProvider = CellProvider<PostalAddressCell>(nibName: "CustomNib", bundle: Bundle.main)
}

Unfortunately this method only work for Row with non generic data type, while PickerRow is a generic type:

public final class PickerInputRow<T>

If we try to load a custom xib into PickerInputRow by cellProvider the application will crash like this:

2021-07-11 09:01:02.826041+0700 EurekaPickerInputRow[3341:90020] [Storyboard] Unknown class _TtC6Eureka15PickerInputCell in Interface Builder file.
Could not cast value of type 'UITableViewCell' (0x104ec3748) to 'Eureka.PickerInputCell<EurekaPickerInputRow.Scientist>' (0x104ec3040).

It turns out the reason for that is ios does not support use a generic class as a custom view in Interface Builder.

So the workaround for this is instead of loading xib into UITableViewCell we’re gonna switch into a separate UIView, then add this view into content of UITableViewCell in method setup:

    open override func setup() {
        super.setup()
        customContentView = (row as? PickerInputHasCustomContentView)?.contentViewProvider?.makeView()
        if let unwrapped = customContentView {
            contentView.addSubview(unwrapped)
            unwrapped.translatesAutoresizingMaskIntoConstraints = false
            unwrapped.topAnchor.constraint(equalTo: contentView.topAnchor).isActive = true
            unwrapped.bottomAnchor.constraint(equalTo: contentView.bottomAnchor).isActive = true
            unwrapped.leftAnchor.constraint(equalTo: contentView.leftAnchor).isActive = true
            unwrapped.rightAnchor.constraint(equalTo: contentView.rightAnchor).isActive = true
        }
    }

Using this way, we can custom UI not only for picker row but also rows with generic type without breaking form data architecture of Eureka.

That’s it! If you want more detail, please go to the sample source code here. Thank you for reading this post.

Leave a Reply

Your email address will not be published. Required fields are marked *