I need to move a method for adding and removing a logging view inside an Extension, in order to give it to every controller. to do so I added a inout UIVew parameter to original method, where I used a global var for the view. no I have this error
Value of type 'UIViewController' has no member 'containerForLoading'
removing self from self.containerForLoading
will give error:
Escaping closure captures 'inout' parameter 'containerForLoading'
inside the animate closure (see the comment) is all wrong the entire process or I am lost at the last step?
extension UIViewController {
func showLoadingView(containerForLoading: inout UIView, uponView: UIView) {
containerForLoading = UIView(frame: uponView.bounds)
uponView.addSubview(containerForLoading)
containerForLoading.backgroundColor = .white
containerForLoading.alpha = 0
UIView.animate(withDuration: 0.24) { self.containerForLoading.alpha = 0.8 } //here the error
let activivityIndicator = UIActivityIndicatorView()
containerForLoading.addSubview(activivityIndicator)
activivityIndicator.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
activivityIndicator.centerYAnchor.constraint(equalTo: uponView.centerYAnchor),
activivityIndicator.centerXAnchor.constraint(equalTo: uponView.centerXAnchor)
])
activivityIndicator.startAnimating()
}
func removeLoading(containerForLoading: inout UiView, uponView: UIView) {
containerForLoading.removeFromSuperview()
}
}
this is the code inside the original viewController
using this var
var containerForLoading = UIView()
called this way when needed
self.showLoadingView(uponView: self.view)
extension ViewController {
func showLoadingView(uponView: UIView) {
containerForLoading = UIView(frame: uponView.bounds)
uponView.addSubview(containerForLoading)
containerForLoading.backgroundColor = .white
containerForLoading.alpha = 0
UIView.animate(withDuration: 0.24) { self.containerForLoading.alpha = 0.8 }
let activivityIndicator = UIActivityIndicatorView()
containerForLoading.addSubview(activivityIndicator)
activivityIndicator.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
activivityIndicator.centerYAnchor.constraint(equalTo: uponView.centerYAnchor),
activivityIndicator.centerXAnchor.constraint(equalTo: uponView.centerXAnchor)
])
activivityIndicator.startAnimating()
}
func removeLoading(uponView: UIView) {
containerForLoading.removeFromSuperview()
}
}
You could make
loadingContainerTag
a local variable, and change the parameter name to something else. Then assign to the parameter just after you create the container view:removeLoading
could just have one non-inout
parameter:But...
It is very weird for a method that shows a loading indicator, to need an
inout
parameter. It shouldn't assign to a special property that the caller provides. It should just show the loading indicator!The purpose of your
containerForLoading
property is so that inremoveLoading
, you know which view to remove. If you don't store thecontainerForLoading
view somewhere in a property, you wouldn't know which view to remove, right? Well, we can use thetag
property of a view to identify views, so you can just makecontainerForLoading
a local variable, and later inremoveLoading
, use its tag to find it.