Something is not exactly right here. If I declare my cell subclass in Obj-C:
@interface MyObjcCell: UICollectionViewCell
@end
@implementation MyObjcCell
- (void)updateConfigurationUsingState:(UICellConfigurationState *)state {
NSLog(@"MyObjcCell. updateConfigurationUsingState: %@, b4 calling super", state);
[super updateConfigurationUsingState:state];
NSLog(@"after calling super");
}
@end
and call its update from Swift:
let cell = MyObjcCell()
let state = UICellConfigurationState(traitCollection: .current)
cell.updateConfiguration(using: UICellConfigurationState(traitCollection: .current))
that will not call my Obj-C overridden method.
I can call the hidden (from Swift) method:
cell.__updateConfiguration(using: __UICellConfigurationState(traitCollection: .current))
in which case the Obj-C's the "updateConfigurationUsingState" override is called, but I guess I am not supposed to, as it is prefixed with "__".
Ditto would happen if I make a Swift's subclass of Obj's "MyObjcCell".
I would expect a more transparent interop story here, with Swift's updateConfiguration(using:)
converting the passed Swift struct into obj-c class and calling through Obj-C updateConfigurationUsingState:
.
Regardless of this I still don't understand how could I add an overridable method like "updateConfiguration(using: Swift_only_type)" to an Obj-c defined class like UICollectionViewCell
.
Until a better solution is found you may try this approximation:
// api.h
#import <Foundation/Foundation.h>
NS_REFINED_FOR_SWIFT
@interface UICellConfigurationState: NSObject // UIViewConfigurationState but let's keep it simpler
@property BOOL isDisabled;
// other fields here
@end
NS_REFINED_FOR_SWIFT
@interface UICollectionViewCell: NSObject
- (void)updateConfigurationUsingState:(UICellConfigurationState*)state NS_REFINED_FOR_SWIFT;
@end
Here NS_REFINED_FOR_SWIFT is used to hide (double underscore) the corresponding names from Swift.
// api.m
@implementation UICellConfigurationState
@end
@implementation UICollectionViewCell
- (void)updateConfigurationUsingState:(UICellConfigurationState*)state {
printf("objc updateConfigurationUsingState");
}
@end
Nothing special in objc implementation, business as usual.
// api.swift
public struct UICellConfigurationState {
var isDisabled: Bool
// other fields here
}
Completely redefine what UICellConfigurationState
is in Swift
class UICollectionViewCell: __UICollectionViewCell {
open func updateConfiguration(using state: UICellConfigurationState) {
let objState = __UICellConfigurationState()
objState.isDisabled = state.isDisabled
// other fields here
super.__updateConfiguration(using: objState)
}
}
Here use the underscored name as a base class and underscored method to reach out for obj-c implementation.
// test.swift
class MyCell: UICollectionViewCell {
override func updateConfiguration(using state: UICellConfigurationState) {
}
}
In your subclass in the app everything should work as expected.