spierce7
06/28/2018, 8:40 PM@ExportObjCClass
class ViewController : UIViewController {
constructor(aDecoder: NSCoder) : super(aDecoder)
override fun initWithCoder(aDecoder: NSCoder) = initBy(ViewController(aDecoder))
@ObjCOutlet lateinit var label: UILabel
@ObjCOutlet lateinit var textField: UITextField
@ObjCOutlet lateinit var button: UIButton
override fun viewDidLoad() {
super.viewDidLoad()
button.addTarget(this, action=sel_registerName("buttonPressed"), forControlEvents=UIControlEventTouchDown)
}
@ObjCMethod(selector = "buttonPressed", bridge = "ViewController") fun buttonPressed() {
label.text = "Konan says: '2, ${textField.text}!'"
}
}
Vyacheslav Karpukhin [JB]
06/28/2018, 8:43 PM@ObjCMethod
annotation with @ObjCAction
, like in the sample, it seems to work.spierce7
06/28/2018, 8:51 PMVyacheslav Karpukhin [JB]
06/28/2018, 9:06 PMspierce7
06/29/2018, 1:11 AM@ExportObjCClass
class ViewController : UIViewController {
constructor(aDecoder: NSCoder) : super(aDecoder)
override fun initWithCoder(aDecoder: NSCoder) = initBy(ViewController(aDecoder))
@ObjCOutlet lateinit var label: UILabel
@ObjCOutlet lateinit var textField: UITextField
@ObjCOutlet lateinit var button: UIButton
override fun viewDidLoad() {
super.viewDidLoad()
button.onClick {
label.text = "Konan says: 'Hello, ${textField.text}!'"
}
}
}
fun UIButton.onClick(onClick: () -> Unit) {
val handler = ClickHandler(onClick)
this.addTarget(handler, sel_registerName("buttonPressed"), UIControlEventTouchUpInside)
}
@ExportObjCClass
class ClickHandler(private val onClick: () -> Unit) {
@Suppress("unused")
@ObjCAction fun buttonPressed() {
onClick()
}
}
svyatoslav.scherbina
06/29/2018, 4:21 AMIt does. Why does it work?
@ObjCMethod
annotation is not supposed to be applied this way, thus it doesn’t work.
@ObjCAction
annotation is designed for this case, so it works.I’m also interested why something like this won’t work to make click listeners easier...Your code has a couple of issues: 1)
ClickHandler
should extend NSObject
class
2) addTarget
requires the target object (handler
in your case) to be stored somewhere to prevent from being removed:
The control does not retain the object in the target parameter. It is your responsibility to maintain a strong reference to the target object while it is attached to a control.So you can create a list of handlers in
ViewController
and add all handlers to that list.
The list should be cleared when view is being unloaded, because otherwise you would leave a cycle of objects referencing each other with strong references, and since that cycle would contain Objective-C object (ViewController
), it would not be deleted by Kotlin/Native garbage cycle collector.
By the way, it is not necessary to add @ExportObjCClass
to ClickHandler
.spierce7
06/29/2018, 6:10 AM