Eureka: SelectorRow documentation is corrupt

How to develop a Custom Presenter row in Eureka 4.x? The offocial documentation is still

public final class CustomPushRow<T: Equatable>: SelectorRow<PushSelectorCell<T>, SelectorViewController<T>>, RowType {

    public required init(tag: String?) {
        super.init(tag: tag)
        presentationMode = .show(controllerProvider: ControllerProvider.callback {
            return SelectorViewController<T>(){ _ in }
            }, onDismiss: { vc in
                _ = vc.navigationController?.popViewController(animated: true)
        })
    }
}

but this couldn’t get compiled.

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 3
  • Comments: 16

Most upvoted comments

So, you’re getting this, because with recent changes, SelectorRow is more specialized (select from list of options) and the functionality just to present a custom TypedRowControllerType is now lost. Try using This row as base, should work:

open class PresenterRow<Cell: CellType, VCType: TypedRowControllerType>: OptionsRow<Cell>, PresenterRowType where Cell: BaseCell, VCType: UIViewController, VCType.RowValue == Cell.Value {

    public var presentationMode: PresentationMode<VCType>?
    public var onPresentCallback: ((FormViewController, VCType) -> Void)?
    public typealias PresentedControllerType = VCType
    
    required public init(tag: String?) {
        super.init(tag: tag)
    }
    open override func customDidSelect() {
        super.customDidSelect()
        guard let presentationMode = presentationMode, !isDisabled else { return }
        if let controller = presentationMode.makeController() {
            controller.row = self
            controller.title = selectorTitle ?? controller.title
            onPresentCallback?(cell.formViewController()!, controller)
            presentationMode.present(controller, row: self, presentingController: self.cell.formViewController()!)
        } else {
            presentationMode.present(nil, row: self, presentingController: self.cell.formViewController()!)
        }
    }
}

ps. It will be a great idea to have a such a row in Eureka.

If anyone needs help implementing @mspasov base row, here’s how I’ve done it:

class CustomFormViewController: FormViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        form +++ Section()
            <<< CustomPresenterRow() { row in
                row.presentationMode = .show(controllerProvider: ControllerProvider.callback {
                    return CustomViewController()
                }, onDismiss: { vc in
                    _ = vc.navigationController?.popViewController(animated: true)
            })
        }
    }
    
}
final class CustomPresenterRow: PresenterRow<PushSelectorCell<String>, CustomViewController>, RowType { 

}
class CustomViewController: UIViewController, TypedRowControllerType {
    
    // protocol conformance
    var row: RowOf<String>!
    var onDismissCallback: ((UIViewController) -> Void)?
    
}

In your code try removing CustomViewController as in the following code

public final class CustomPushRow: SelectorRow<CustomPushCell>, 
RowType {

    public required init(tag: String?) {
        super.init(tag: tag)
        presentationMode = .presentModally(controllerProvider: ControllerProvider.callback {
            let vc = CustomViewController()
            vc.row = self
            return vc
            }, onDismiss: { vc in
                _ = vc.navigationController?.popViewController(animated: true)
        })
    }
}

You should get through the initial error, but then you may find another issue in regards to a type mismatch. This did work on some similar methods for me, but currently I am blocked by an error:

I’m not sure yet what is wrong with my implementation. On the line with presentationMode = .show(… I get this error:

Cannot convert value of type ‘ControllerProvider<MapViewController>’ to expected argument type ‘ControllerProvider<_>’

If anyone has some insight to what I am doing wrong that would be awesome.

public final class GeolocationRow : SelectorRow<PushSelectorCell<CLLocation>>, RowType {
    public required init(tag: String?) {
        super.init(tag: tag)
        presentationMode = .show(controllerProvider: ControllerProvider.callback { return MapViewController(){ _ in } }, onDismiss: { vc in
            let _ = vc.navigationController?.popViewController(animated: true) })
        displayValueFor = {
            guard let location = $0 else { return "" }
            let fmt = NumberFormatter()
            fmt.maximumFractionDigits = 4
            fmt.minimumFractionDigits = 4
            let latitude = fmt.string(from: NSNumber(value: location.coordinate.latitude))!
            let longitude = fmt.string(from: NSNumber(value: location.coordinate.longitude))!
            return  "\(latitude), \(longitude)"
        }
    }
}

I’m facing a similar problem. After following the hints from issue #776, I’m still getting the error messages below: Type ‘CustomPushRow’ does not conform to protocol ‘TypedRowType’ Type ‘CustomPushRow’ does not conform to protocol ‘Taggable’ Type ‘CustomPushRow’ does not conform to protocol ‘RowType’ Type ‘CustomPushRow’ does not conform to protocol ‘BaseRowType’ Generic type ‘SelectorRow’ specialized with too many type parameters (got 2, but expected 1)

My code:

    open class CustomPushCell : Cell<Int>, CellType{
    
        required public init(style: UITableViewCellStyle, reuseIdentifier: String?) {
            super.init(style: style, reuseIdentifier: reuseIdentifier)
        }
    
        required public init?(coder aDecoder: NSCoder) {
            super.init(coder: aDecoder)
        }
        }

    class CustomViewController: UIViewController, TypedRowControllerType{
        public var row: RowOf<Int>!
        public var onDismissCallback : ((UIViewController) -> ())?
    }

    public final class CustomPushRow: SelectorRow<CustomPushCell, CustomViewController>, 
    RowType {
    
        public required init(tag: String?) {
            super.init(tag: tag)
            presentationMode = .presentModally(controllerProvider: ControllerProvider.callback {
                let vc = CustomViewController()
                vc.row = self
                return vc
                }, onDismiss: { vc in
                    _ = vc.navigationController?.popViewController(animated: true)
            })
        }
    }