I have a ToastViewController
subclass of UIViewController
with a generic ToastContentView
being itself a subclass of UIView
.
class ToastViewController<ContentViewType: ToastContentView>: UIViewController {
}
class ToastContentView: UIView {
}
I'm using custom view controller transitioning, and I need to cast my presenting view controller to ToastViewController
from the UIViewControllerContextTransitioning
instance.
if let toastVC = context.viewController(forKey: .to) as? ToastViewController<ToastContentView> {
Log.debug("OK")
} else {
Log.debug("NOT OK")
}
I have some concrete subclasses like AlertViewController
defined like:
final class AlertViewController: ToastViewController<AlertToastView> {
}
final class AlertToastView: ToastContentView {
}
But the previous cast check always fails (whereas I'm sure the view controller is an instance of AlertViewController
).
How can I make it work? I obviously don't want to cast the presenting view controller to the concrete subclasses...
Thanks
Well, AlertViewController
is a ToastViewController<AlertToastView>
, not a ToastViewController<ToastContentView>
, so you cannot cast.
A simple way to do this is to introduce a protocol with all the things you need from ToastViewController
.
@MainActor
protocol AnyToastViewController: UIViewController {
// declare properties/methods you need from ToastViewController here
}
If you need something of the generic ContentViewType
type, add an associated type requirement to the protocol:
associatedtype Content: ToastContentView
var contentView: Content { get }
ToastViewController
would conform to it:
class ToastViewController<ContentViewType: ToastContentView>: UIViewController, AnyToastViewController {
Then you can cast to any AnyToastViewController
instead.
if let toastVC = context.viewController(forKey: .to) as? ToastViewController<ToastContentView> {
let content = toastVC.contentView
// and so on...
} else {
Log.debug("NOT OK")
}
Note that you can only get properties of the generic ContentViewType
type, or call methods that return ContentViewType
. Setting properties of type ContentViewType
, or calling methods that take ContentViewType
as a parameter is not type safe.