Reputation: 1017
I am looking to create a custom subclass of UIAlertController
.
If I understand correctly, I need to call the super.init(title...
somewhere during the subclasses initialization.
But I keep running into problems with designated initializers. I have read the documentation and cannot figure out how to get it to work. Here's my code (note the comments in the code):
class AccountInfoActionSheet: UIAlertController {
required init?(coder aDecoder: NSCoder) { //xcode says I need this
super.init(coder: aDecoder) //it also says I need to call a designated initializers so here it is
super.init(title: "Info", message: "Heres the Info", preferredStyle: .actionSheet) //but now I can't call this initializer
fatalError("init(coder:) has not been implemented")
}
}
EDIT: Since UIAlertController
cannot be subclassed I simply created a function that returns the correctly configured UIAlertController
inside the ViewController where it is needed.
Upvotes: 5
Views: 3869
Reputation: 4886
You should not subclass UIAlertController
.
Check this link:
you can add methods using extensions
but should not subclass it.
Upvotes: 11
Reputation: 1429
As limon's answer to another question says, you are not supposed to subclass UIAlertController
.
The UIAlertController class is intended to be used as-is and does not support subclassing. The view hierarchy for this class is private and must not be modified.
Upvotes: 1
Reputation: 1391
As was stated in other answers you are not supposed to subclass UIAlertController
. As an option you could create an extension with a factory method:
extension UIAlertController {
static func accountInfoActionSheet() -> UIAlertController {
return UIAlertController(title: "Title", message: "Message", preferredStyle: .actionSheet)
}
}
However, other answers are not particularly truthful saying that you cannot subclass UIAlertController. You are not supposed to, but you very much can if you want to.
UIAlertController
is a subclass of UIViewController
, therefore they have the same designated initializer which is init(nibName: String?, bundle: Bundle?)
.
You are not supposed to call it in init?(coder aDecoder: NSCoder)
though because it is a designated initializer itself. It's being called when, for example, the controller is being initialized from a storyboard.
Here's the example how to achieve what you want (even though Apple does not approve that):
class AccountInfoActionSheet: UIAlertController {
// preferredStyle is a read-only property, so you have to override it
override var preferredStyle: UIAlertControllerStyle {
return .actionSheet
}
init() {
super.init(nibName: nil, bundle: nil)
initialize()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
initialize()
}
// all of the configuration code that init methods might share
// separated into a method for the sake of convenience
private func initialize() {
title = "Info"
message = "Heres the Info"
// any other setup needed
}
}
Upvotes: 4
Reputation: 150605
If you want an easier way of creating common alert controllers, what you can do instead of creating a subclass is to create an extension of UIAlertController that has a factory method to return the kind of configured Alert controller that you want. For example:
extension UIAlertController {
static func accountInfo() -> UIAlertController {
// If you want to add Alert Actions you can add them to the controller before returning them.
return UIAlertController(title: "Info", message: "Here's the Info", preferredStyle: .actionSheet)
}
}
And now you can create the controller simply with:
let ac = UIAlertController.accountInfo()
Upvotes: 3