I'm trying to do something like this:
public extension UIImage {
public convenience init(whatever: Int) {
UIGraphicsBeginImageContextWithOptions(...)
//...
let image = UIGraphicsGetImageFromCurrentContext()
UIGraphicsEndImageContext()
return image // <- impossible
}
}
But this is not possible as "nil" is the only valid return for an initializer... How do i do this?
For example, the Objtive-C method [UIImage imageNamed:] is a class method (that can return whatever it wants in Objective-C) and it was mapped to the swift initializer UIImage(named:).
You implement this initialization process by defining initializers, which are like special methods that can be called to create a new instance of a particular type. Unlike Objective-C initializers, Swift initializers don't return a value.
Unlike Objective-C initializers, Swift initializers do not return a value. please explain below syntax. It does initialize a String object by calling the initializer and return it. Value get assigned to instanceOfString .
Swift init() Initialization is the process of preparing an instance of a class, structure, or enumeration for use. This process involves setting an initial value for each stored property on that instance and performing any other setup or initialization that is required before the new instance is ready for use.
You write a failable initializer by placing a question mark after the init keyword ( init? ). Note: You cannot define a failable and a nonfailable initializer with the same parameter types and names. A failable initializer creates an optional value of the type it initializes.
What you want is a class factory method, not an initializer. Most factory methods in Foundation/Cocoa are automatically bridged to initializers, but if what you want can't be done via init
, you can add a new class method:
public extension UIImage {
class func imageWithWhatever(whatever: Int) -> UIImage {
UIGraphicsBeginImageContextWithOptions(...)
//...
let image = UIGraphicsGetImageFromCurrentContext()
UIGraphicsEndImageContext()
return image
}
}
This is because you are returning a new object, not self. The point of init is to create the structure of your object, not a new one, so if you want to do it as a convenience init, you need to do it like this:
public extension UIImage {
public convenience init?(whatever: Int) {
defer {
UIGraphicsEndImageContext()
}
UIGraphicsBeginImageContextWithOptions(...)
//...
guard let currentContext = UIGraphicsGetCurrentContext() else { return nil }
guard let image = currentContext.makeImage() else { return nil }
self.init(cgImage:image)
}
}
perhaps instead of a convenience init, you want to create a class function that is doing what you are asking:
public class func createImage(whatever: Int) -> UIImage? {
defer {
UIGraphicsEndImageContext()
}
UIGraphicsBeginImageContextWithOptions(...)
//...
guard let currentContext = UIGraphicsGetCurrentContext() else { return nil }
guard let cgImage = currentContext.makeImage() else { return nil }
let image = UIImage(cgImage: cgImage)
return image
}
I apologize that this is not 100% to code, but that is basically the gist of it
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With