Is there a migration guide somewhere for moving to Swift 4? Apparently this is no longer valid;
final class FolderRow:
SelectorRow<PushSelectorCell<Folder>,
FolderViewController>,
RowType {
It throws generic type 'SelectorRow' specialized with too many type parameters (got 2, but expected 1). I don't see anything relevant in the docs, which leads me to believe they're not updated yet. Any hints on how to fix my code or pointers to updated docs would be appreciated!
SelectorRow did rename to open class SelectorRow<Cell: CellType>: OptionsRow<Cell>, PresenterRowType where Cell: BaseCell
our code maybe like this
final class FolderRow: SelectorRow<PushSelectorCell<Folder>>, RowType {
...
typealias PresenterRow = FolderViewController
}
But typealias can't be override, stackoverflow - Swift: overriding typealias inside subclass
So we need refactor this implementation. @mtnbarreto
@KevinGong2013 I tried this last night;
final class FolderRow: SelectorRow<PushSelectorCell<Folder>>, RowType {
required init(tag: String?) {
super.init(tag: tag)
presentationMode = .show(
controllerProvider: ControllerProvider<FolderViewController>.callback {
return FolderViewController() {_ in}
},
onDismiss: { vc in vc.navigationController?.popViewController(animated: true) });
But then I get cannot convert value of type 'ControllerProvider<FolderViewController>' to expected argument type 'ControllerProvider<_>'
@japhar81 typealias PresenterRow = FolderViewController is the key point.
But swift4 does't support this syntax.
Have a workaround for this problem:
SelectorRow and rename to FloderRow.public typealias PresenterRow = SelectorViewController<SelectorRow<Cell>> to typealias PresenterRow = FolderViewControllerSorry my poor english.
@KevinGong2013 thanks for this! I nuked my old comment in favor of this one that's current. I got things to compile, doing this;
final class FolderRow<Cell: PushSelectorCell<Folder>>: OptionsRow<Cell>, PresenterRowType {
typealias PresenterRow = FolderViewController
/// Defines how the view controller will be presented, pushed, etc.
public var presentationMode: PresentationMode<PresenterRow>?
/// Will be called before the presentation occurs.
public var onPresentCallback: ((FormViewController, PresenterRow) -> Void)?
required public init(tag: String?) {
super.init(tag: tag)
self.title = "Folder"
self.noValueDisplayText = "Choose Folder"
presentationMode = .show(
controllerProvider: ControllerProvider<FolderViewController>.callback {
return FolderViewController() {_ in}
},
onDismiss: { vc in vc.navigationController?.popViewController(animated: true) });
displayValueFor = { folder in
if let title = folder?.title {
self.cell.detailTextLabel?.textColor = UIColor.black
return title
} else {
self.cell.detailTextLabel?.textColor = UIColor.lightGray
return self.noValueDisplayText
}
}
}
/**
Extends `didSelect` method
*/
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()!)
}
}
/**
Prepares the pushed row setting its title and completion callback.
*/
open override func prepare(for segue: UIStoryboardSegue) {
super.prepare(for: segue)
guard let rowVC = segue.destination as? PresenterRow else { return }
rowVC.title = selectorTitle ?? rowVC.title
rowVC.onDismissCallback = presentationMode?.onDismissCallback ?? rowVC.onDismissCallback
onPresentCallback?(cell.formViewController()!, rowVC)
rowVC.row = self
}
}
FolderViewController is just a simple class FolderViewController: UITableViewController, TypedRowControllerType, UISearchResultsUpdating
And I add it to the form this way;
folderRow = FolderRow(tag: "Folder")
The good news is it builds, and I see the picker. The bad news is, there's no longer an onChange handler, so I have no way to get the resulting value?
Two things:
Make your struct Folder implement Equatable protocol
You will get a ton of default implementations from Eureka then you can use this initializer let folderRow = FolderRow("Folder") { row in }
Make sure you did set row's value in your FolderViewController.
This is my suggestion, I hope this can help you.
@KevinGong2013 I actually did that already.. but I still see no way to bind an onChange event?
check this.
TestEureka.zip
@KevinGong2013 got it working, thanks so much!
This was helpful for me too.
I noticed in this change https://github.com/xmartlabs/Eureka/commit/63ec7059e2313f9b38cce2ebe45679b67f98556f that rows that were previously subclassing SelectorRow changed to subclassing OptionsRow which then lets you define your own presentationMode and type of controller it expects. So it seems that if you need a custom view controller for your row this is the route you have to take.
Thanks for this workaround. Note: It doesn't work with other PresenterMode case (nibFile, storyboard) but not a big deal.
@loryhuz check my solution in #1282, The issue there is similar.
@mspasov I was just saying it wasn't working in others PresenterMode enum case like nibFile ;) Your solution is not based on nib instantiating from PresenterMode enum case, it's the same in this thread, so my note is still relevant. But like I said, not a big deal, just switch from the working PresenterMode case make it working.