Delegate Property with Different Type in Swift

Override property with different type

The way it works for Objective C is because of the dynamic nature of the language. You can redeclare the type of super class and instead of synthesizing the property you would make it a dynamic type, which would let you redeclare it.

@protocol MyTableViewDelegate<UITableViewDelegate>

- (void)demoDelegateMethod;

@end

@interface WrapperTableView: UITableView

@property (nonatomic, weak, nullable) id <MyTableViewDelegate> delegate;

@end

@implementation WrapperTableView

@dynamic delegate;

@end

But, I doubt this would be possible with Swift, since, you are changing the type completely. It is because of Swift being strong static language.

Answer Edited

I got your approach. I write above approach in Objective-C and then inherit this class in Swift.
So if I have to override SuperClass property with different type I need to create a wrapper class in Objective-C inherit from desired SuperClass and then finally instead of inheriting directly from desired super class I should inherit from the newly created WrapperClass which is written in Objective-C

class MyTableView: WrapperTableView {
//Now Here the delegate object is of type MyTableViewDelegate
}

This approach is far better then

class MyTableView: UITableView {
private var myDelegate: MyTableViewDelegate?
override var delegate: UITableViewDelegate {
set{
myDelegate = newValue
}
get{
return myDelegate
}

}
}

Overriding superclass property with different type

The reason it works with UIScrollView and UITableView and their delegates is that they are generated Swift interfaces from the original Objective-C headers.

Objective-C lets you do this. While you can't create Swift classes that do this directly, Swift class interfaces generated from an Objective-C bridging header can result is the case you see here.

Overriding delegate property of UIScrollView in Swift (like UICollectionView does)

I think overriding an inherited property is something that's possible in Objective-C but not (at least currently) in Swift. The way I've handled this is to declare a separate delegate as a computed property of the correct type that gets and sets the actual delegate:

@objc protocol MyScrollViewDelegate : UIScrollViewDelegate, NSObjectProtocol {
func myHeight() -> CGFloat
// ...
}

class MyScrollView: UIScrollView {
var myDelegate: MyScrollViewDelegate? {
get { return self.delegate as? MyScrollViewDelegate }
set { self.delegate = newValue }
}
}

This way anything that calls the scroll view delegate normally still works, and you can call your particular delegate methods on self.myDelegate, like this:

if let height = self.myDelegate?.myHeight() {
// ...
}

Overriding a superclass delegate in Swift

It's not ideal, but if one protocol is inherited from the other, rather than using different types, use the same type, but implement validation in didSet:

class MyView : UIView {

/// The `MyViewDelegate` delegate

weak var delegate: MyViewDelegate?
}

class MyViewSubclass: MyView {

/// The `MyViewSubclassDelegate` delegate.
///
/// **Note: This must be MyViewSubclassDelegate**

override weak var delegate: MyViewDelegate? {
didSet {
assert(delegate == nil || delegate is MyViewSubclassDelegate, "The delegate of MyViewSubclass must be of type `MyViewSubclassDelegate`")
}
}
}

It's inelegant, but at least you'll get an immediate runtime error that will bring the problem to the programmer's attention. And by including the /// comment, it will also be shown in the Quick Help, too.

--

Alternatively you can adopt more radical changes, e.g. something like delegate and peoplePickerDelegate properties of ABPeoplePickerNavigationController, where the subclass delegate is specified via a different property.

Overriding Swift var with a Different Type

In your class example, SearchBar is a subtype of UISearchBar. However in your protocol example, Optional<SplitViewDelegate> is not a subtype of Optional<UISplitViewControllerDelegate>. The Problem really is: The type Optional<Wrapped> is not covariant on Wrapped. Swift does not and probably will never support co- and contravariance.



Related Topics



Leave a reply



Submit