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
Unresponsive Uibutton in Subview Added to Uistackview
How to 'Addtarget' to Uilabel in Swift
Swift - Getting Only Alphanumeric Characters from String
Selectively Remove and Delete Objects from a Nsmutablearray in Swift
Are Built-In Intrinsic Functions Available in Swift 3
Use of Nspathcontrol to Represent Virtual Path
Could Not Find a Storyboard Named 'Maintabcontroller' in Bundle Nsbundle
Loading Multiple Google Interstitial Ads Makes App Crash
Swift Change the Tableviewcell Border Color According to Data
Why Are Properties of an Immutable Object Mutable in Swift
Swift: Reflecting Properties of Subclass of Nsmanagedobject