I'm trying to create a custom View which I need to focus.
According to numerous Sources this is the way to go :
override func canBecomeFocused() -> Bool {
return true
}
However after converting to Swift 3.0 this no longer works.
It throws the error:
Method does not override any method from its superclass.
If i remove the override another error gets thrown:
Method 'canbecomeFocused()' with Objective-C selector 'canBecomeFocused' conflicts with better for 'canBecomeFocused' from superclass 'UIView' with the same Objective-C Selector.
Anyway I can make a UIView Selectable for TvOS?
In Swift 3 it is change to Instance Property, so try like this.
override var canBecomeFocused: Bool {
return true
}
Check Apple Documentation on canBecomeFocused for more details.
I am working on iOS app which is having Obj C code as well as Swift. I am migrating my existing Objective C category to swift code. But when I override existing method in swift extension, it is not compiling. Swift extension is working well for new methods but not for overriding existing methods.
Code:
extension UIViewController {
public override func shouldAutorotate() -> Bool {
return false
}
public override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
return UIInterfaceOrientationMask.Portrait
}
}
Error:
Method 'shouldAutorotate()' with Objective-C selector 'shouldAutorotate' conflicts with previous declaration with the same Objective-C selector
Method does not override any method from its superclass
Method 'supportedInterfaceOrientations()' with Objective-C selector 'supportedInterfaceOrientations' conflicts with previous declaration with the same Objective-C selector
Here, Am I missing anything?
I am using Xcode 7.3.1 and Swift 2.x
EDIT:
From below Answers, I got to know that We cant change behaviour of existing method of class at runtime in Swift extension like in Objective C Categories. Here I should make a base class which will override method and I should use all my ViewControllers as child classes from new base class as parent.
But in my case, I want to change behaviour of all "shouldAutorotate" methods including 3rd party frameworks UIViewController. In above case I cant force all third party frameworks UIviewControllers to become subclass of my base class. In Objective C i could achieve this.
Swift extensions aren't to be used to override methods declared in the class they're extending – especially for Objective-C classes, that's very much like providing two definitions of the same method in the same class. Imagine seeing a class that looked like:
class UIViewController : UIResponder {
public func shouldAutorotate() -> Bool {
return true
}
public func shouldAutorotate() -> Bool {
return false
}
}
Which one wins? That's the conflict you're being warned about.
If you need to override methods for a view controller of yours, you'll need to do that in a subclass, not an extension.
Ninja edit: this may have been possible to do in Objective-C, but was a programming error there. If a category duplicates a method from a main class, which definition gets used is undefined. See this SO post and the backing Apple documentation.
I have a problem with overriding class method from Objective-C in Swift. I can invoke it from Swift no problem but not override it.
Method signature:
+ (id<MyInterface>)newObjectWithId:(NSString *)objectId properties:(NSDictionary *)properties andClient:(Client *)client;
Class hierarchy:
NSObject <-- MyObject1 <-- MyObject2 <-- MySwiftClass
MyObject1 declares and implements aforementioned method and so does MyObject2. However trying to override it in Swift does not work. It is not visible in autocompletion and when I write it manually it says Method does not override any method from its superclass. Signature I wrote looks like this:
override class func newObjectWithId(objectId: String!, properties: NSDictionary!, andClient client: Client!) -> MyInterface
I did overriding for some other class methods in this class too and they work without a problem. I assume it's a problem with new prefix in this method. Has anyone encountered something like this and resolved it successfully?
I have a swift protocol:
#objc protocol SomeDelegate {
optional func myFunction()
}
I one of my classes I did:
weak var delegate: SomeDelegate?
Now I want to check if the delegate has myFunction implemented.
In objective-c I can do:
if ([delegate respondsToSelector:#selector(myFunction)]) {
...
}
But this is not available in Swift.
Edit: This is different from: What is the swift equivalent of respondsToSelector? I focus on class protocols not on classes.
How do I check if my delegate has an optional method implemented?
Per The Swift Programming Language:
You check for an implementation of an optional requirement by writing
a question mark after the name of the requirement when it is called,
such as someOptionalMethod?(someArgument). Optional property
requirements, and optional method requirements that return a value,
will always return an optional value of the appropriate type when they
are accessed or called, to reflect the fact that the optional
requirement may not have been implemented.
So the intention is not that you check whether the method is implemented, it's that you attempt to call it regardless and get an optional back.
You can do
if delegate?.myFunction != nil {
}
I've found it successful to add an extension to the protocol that defines basic default implementation and then any class implementing the protocol need only override the functions of interest.
public protocol PresenterDelegate : class {
func presenterDidRefreshCompleteLayout(presenter: Presenter)
func presenterShouldDoSomething(presenter: Presenter) -> Bool
}
then extend
extension PresenterDelegate {
public func presenterDidRefreshCompleteLayout(presenter: Presenter) {}
public func presenterShouldDoSomething(presenter: Presenter) -> Bool {
return true
}
}
Now any class needing to conform to the PresenterDelegate protocol has all functions already implemented, so it's now optional to override it's functionality.
I normally implement it like this:
self.delegate?.myFunction?()
if the delegate methods returns a value:
var result = defaultValue
if let delegateResult = self.delegate?.myFunction?() else {
result = delegateResult
}
//do something with result
Declaration
#objc public protocol nameOfDelegate: class {
#objc optional func delegateMethod(_ varA: int, didSelect item: Item)
}
Implimetation
if let delegate = nameOfDelegate {
delegate.delegateMethod?(1, didDeselect: node)
}
I know this question is 5 years old, but I would like to share what I found. My solution works as of 2021, XCode 11+, Swift 5.
Say I wanted to figure out whether the function sign follows the GIDSignInDelegate protocol and also know what all the optional functions for GIDSignInDelegate are.
I have to look at the source code of the GIDSignIn module, and this is how.
Click on jump to definition on the main module that is imported. It will lead to a file like this:
Copy the entire line, import GoogleSignIn.GIDSignIn and paste it in the ViewController or whatever .swift file (doesn't really matter).
Within the swift file, right click on the GIDSignIn part of the import line GoogleSignIn.GIDSignIn and jump to definition. This will lead you to the actual module with all the available functions (the functions not marked optional may be stubs, which are required functions in the delegate protocol):
From this file, I can see that there is a sign function that is a stub of GIDSignInDelegate and an optional sign function that is implemented as a method overload.
I used this for GIDSignInDelegate, but you can use the same method to figure out whether any function follows any delegate protocol.
I'm trying to use JSONModel in a Swift project.
I would like to override the method keyMapper from JSONModel but I don't find how to override an Objective-C class method in the model class.
The signature of the method is:
+(JSONKeyMapper*)keyMapper;
How can I do that?
You do it just like you override an instance method, except with the class keyword:
override class func keyMapper() -> JSONKeyMapper! {
//code here
}