Wait, I know this question title looks very duplicated, but it really is not.
I have been searching for whole day but cannot find any good solution.
Definition of terms
BaseViewController
: A class that extends UIViewController
, responsible for some common behaviors across different subclassed ViewControllers.
VC
: Short form of ViewController, I will use it from now on
dialog
: In other words, popup; a VC that does not cover the whole screen, and is present modally.
Scenario
Let me use an example to illustrate my needs.
Let say I have an app that displays dialogs in different places.
These dialogs have something in common, including:
- They will blur the background when displayed
- They have a same width
- They have a same dialog container style (e.g. rounded corner radius)
And they also have non common things - the content inside the dialog container.
In order to reduce code duplication, I want to create a BaseDialogVC
to implement the above 3 common things first, and then child class that subclass BaseDialogVC
will provide the view inside the container.
Therefore, I created a storyboard file which contains BaseDialogVC
and implemented the 3 common things using Interface Builder of storyboard.
It has an empty UIView
that acts as a container for its child class to provide their content.
And then, I created a subclass of BaseDialogVC
, for example, AddItemDialogVC
. This AddItemDialogVC
is then responsible for providing its content view, and the logic of this dialog.
Then I am stuck - I tried to instantiate from storyboard an AddItemDialogVC
, but it will crash because storyboard does not have AddItemDialogVC
. It only has BaseDialogVC
.
Question
Actually, I know one alternative that can achieve similar things.
That is - I do not subclass BaseDialogVC
, instead I instantiate it, and add subview to it by calling an instance method of it, passing in an UIView
.
But I still very much want to know what's wrong with my original approach, or,
What is the best approach to this problem?
By "the best approach", I mean it effectively reduced duplication and is easy to maintain.
What I have tried
I found this post for changing BaseDialogVC
to AddItemDialogVC
. But even if it successfully created an AddItemDialogVC
, the AppItemDialogVC
cannot init its content view (A custom View that is subclass of UIView
, and I got an "Thread 1: EXC_BAD_ACCESS" exception.
I think the most similar question out there is this thread.
However, the accepted answer does not elaborate enough; while the second most voted answer is the same as set_object
that I have tried before.
FYI, my class for AddItemDialogView
(NOT VC!):
class AddChoiceDialogView: UIView {
@IBOutlet weak var rootView: AddChoiceDialogView!
override init (frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init? (coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
commonInit()
}
private func commonInit () {
Bundle.main.loadNibNamed("AddChoiceDialogView", owner: self, options: nil)
addSubview(rootView)
rootView.frame = self.bounds
rootView.autoresizingMask = [.flexibleHeight, .flexibleWidth]
}
}