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.
Related
I'm trying to find a way to globally set the delegate of UITextFields used in my app without having to manually do it for each and every UITextField. My initial thought was to do this using a Swift extension, but that doesn't seem to be possible. Any thoughts...?
What I have now:
extension UITextField {
var delegate : UITextFieldDelegate {
get {
return UnoccludedTextFieldDelegate.sharedInstance
}
}
}
This throws a compile error - 'delegate' used within its own type
I have a protocol declared in a class
public protocol demoDelegate {
func willShowdemoResult(DemoGraph: UIView)
}
Now I am calling this in the same class where the protocol is declared.
public class Demo:UIViewController {
public var delegate : demoDelegate!
//some code
self.delegate.willShowdemoResult(self.demoGraph())
}
where demo graph returns a UI graph
func demoGraph() -> UIView {
//some code
return demoGraphView
}
I am getting an error that unexpectedly found nil while wrapping an optional value. I know the reason that I have not initialised the delegate. Can somebody guide me How to initialise the delegate here.
The function is being called in other class
class DemoResult: UIViewController, demoDelegate{
func willShowdemoResult(DemoGraph: UIView)
// some code
}
Please Help
You are getting the error, because Demo.delegate is nil when calling:
delegate.willShowdemoResult(self.demoGraph())
Before you make this call, make sure, that you have set the delegate property. I would recommend this right after initializing Demo or right after DemoResult got the address of the Demo-instance.
Let's assume, you have stored an instance of Demo in DemoResult.demoVC. Then you can set the delegate in DemoResult like this:
demoVC.delegate = self
BTW: It's better to use optional types to store delegates:
public var delegate: demoDelegate?
When delegate is optional, delegate?.willShowdemoResult(self.demoGraph()) won't crash, if delegate has not been initialized yet.
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.
In a custom subclass of GroupOperation, I'm trying to override operationDidFinish(). When I attempt to implement the function in my subclass, I get this error message:
Method does not override any method from its superclass
If I remove the override keyword, I get
Method 'operationDidFinish(:withErrors:)' with Objective-C selector
'operationDidFinish:withErrors:' conflicts with method
'operationDidFinish(:withErrors:)' from superclass 'GroupOperation'
with the same Objective-C selector
Weirdness. I'm pretty sure my method signature is spot on, and I'm not trying to overload an obj-c method, so all should be well. What gives?
For reference, my class looks like this:
class ServerAuthenticationOperation: GroupOperation {
// properties... initializer stuff...
override func operationDidFinish(operation: NSOperation, withErrors errors: [NSError]) {
print("I finished!")
}
}
I assume you're using Swift 2.
Objective-C does not support method overloading, so you have to select a different name for your method. Or, you can try these options:
Rename the method using the #objc(newMethodName:)
Use #nonobjc
Edit:
It seems working for the repo you provided, you can check it here. https://www.dropbox.com/s/hb07u3hyjhjuews/OverrideTest.zip?dl=0
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.