Cannot implement UIPickerViewDelegateProtocol due to conflicting signatures

I am trying to implement UIPickerViewDelegateProtocol in Kotlin native. The problem is that UIPickerViewDelegateProtocol interface in Kotlin essentially has 3 method definitions that differ only in the return type and the names of the parameters, so I cannot figure out how to actually implement this protocol.

The IDE will happily generate this implementations of the interface, but it doesn’t build. No matter which of the 3 methods you try it thinks you are overriding one of the others.

                    val dg = object : NSObject(), UIPickerViewDelegateProtocol {
                        override fun pickerView(
                            pickerView: UIPickerView,
                            attributedTitleForRow: NSInteger,
                            forComponent: NSInteger
                        ): NSAttributedString? {
                            return super.pickerView(
                                pickerView,
                                attributedTitleForRow,
                                forComponent
                            )
                        }

                        override fun pickerView(
                            pickerView: UIPickerView,
                            didSelectRow: NSInteger,
                            inComponent: NSInteger
                        ) {
                            super.pickerView(pickerView, didSelectRow, inComponent)
                        }

                        override fun pickerView(
                            pickerView: UIPickerView,
                            titleForRow: NSInteger,
                            forComponent: NSInteger
                        ): String? {
                            return super.pickerView(pickerView, titleForRow, forComponent)
                        }
                    }
1 Like

Hmmm, I think some trickery could be done here with a Nothing? return type but that’d probably be still not ideal and will look ugly. Maybe try defining a new KotlinUIPickerViewDelegateProtocol interface in Swift or Objective-C or whatever language you’re using for native that overrides those 3 methods and delegates them to 3 new methods with different names (i.e. something like “pickerViewAttributedString”, “pickerViewString”, and “pickerViewUnit”)

I’ve worked around it by calling out to Swift.

The point is that Kotlin/Native already supplies a definition for UIPickerViewDelegateProtocol, but it is unimplementable for those 3 methods. But I find it confusing because I found a library out there that supposedly is implementing it. That code is 2 years old so maybe things were different then.

I suspect that the interface they designed was for calling into an instance of UIPickerViewDelegate, not for defining an implementation of one. The ambiguous signatures are not a problem for calling as you can use parameter names to disambiguate.

1 Like

Hmmm, they seem to be using @Suppress("CONFLICTING_OVERLOADS") Maybe try that? And then for the super calls call them using parameter names to ensure that the correct method is called.

As far as the super calls that was just placeholders from what was generated there is no need to call super. The content of the method does not change it.

And I did try the @Suppress(“CONFLICTING_OVERLOADS”) and it had no effect.

1 Like

Maybe you need to apply it file-wide? Because this compiles and runs:

@file:Suppress("CONFLICTING_OVERLOADS")
fun main() {
    println(test(name = "test"))
    println(test(number = "42"))
}

fun test(name: String): String {
    return "Name: $name"
}

fun test(number: String): Int {
    return number.toInt()
}

(Note that in the mentioned git repo the suppress was applied to the created anonymous object directly, and so maybe you tried it by including the annotation somewhere else, but in this case you can also just apply it to the whole file.)

Suppressing conflicting overloads is necessary and without it you get errors about conflicting overloads, but it does not solve the problem.

The problem comes from trying to implement an interface that essentially has conflicting overloads. I can get the issue without conflicting overloads implementing only one method:

class PickerDelegate: UIPickerViewDelegateProtocol, NSObject() {
    override fun pickerView(
        pickerView: UIPickerView,
        didSelectRow: NSInteger,
        inComponent: NSInteger
    ) {
        TODO()
    }
}

It gives me an error:

Return type is ‘Unit’, which is not a subtype of overridden public open fun pickerView(pickerView: UIPickerView, titleForRow: NSInteger /* = Long /, forComponent: NSInteger / = Long */): String? defined in platform.UIKit.UIPickerViewDelegateProtocol

It has 3 possible methods it thinks I am overriding and it seems to just randomly pick one

1 Like