目前我正在尝试创建一个将使用经理类调用的UIProgressView:
func addProgressBar() {
let rect = CGRect(x: 10, y: 70, width: 250, height: 0)
let progressView = UIProgressView(frame: rect)
progressView.progress = 0.0
progressView.tintColor = UIColor.blue
self.view.addSubview(progressView)
}
这个问题出现了这个问题:
self.view.addSubview(progressView)
因为该函数不在viewController中我得到错误:
“NetworkHelper”类型的值没有成员“view”
任何想法如何在viewcontroller之外添加progressView?
答案 0 :(得分:1)
嗯,你可能自己猜对了,你需要view
来放置progressBar
。我认为addProgressBar
方法的调用者应该知道最适合的地方,所以我建议使用progressBar
,其参数为UIViewController
类型,这将是目标负责进行网络呼叫,因此是将进度条放入:
func addProgressBar(targetViewController: UIViewController) {
// moreover, are you sure here that the height of the progressBar should be 0?
let rect = CGRect(x: 10, y: 70, width: 250, height: 0)
let progressView = UIProgressView(frame: rect)
progressView.progress = 0.0
progressView.tintColor = UIColor.blue
targetViewController.view.addSubview(progressView)
}
答案 1 :(得分:0)
你需要有一个视图来放置它。要么你抓住顶部的viewcontroller并把它放在那个或你调用你的NetworkHelper类并传递一个它应该放置进度条的视图。
我使用此方法来抓取顶部viewcontroller
func topViewController() -> UIViewController? {
guard var topVC = UIApplication.shared.keyWindow?.rootViewController else { return nil }
while let presentedViewController = topVC.presentedViewController {
topVC = presentedViewController
}
return topVC
}
答案 2 :(得分:0)
您可以获取最顶层的视图控制器,并将子视图添加到其视图属性中。
答案 3 :(得分:0)
您可以使用"回调",使用委托设计模式
或Swift的闭包(Objective-C块)
你可以退回"关闭"从函数中,这个闭包创造了进步。要在view / viewController上使用
func addProgressBar() -> (UIView) -> () {
return { view in
let rect = CGRect(x: 10, y: 70, width: 250, height: 0)
let progressView = UIProgressView(frame: rect)
progressView.progress = 0.0
progressView.tintColor = UIColor.blue
view.addSubview(progressView)
}
}
然后在视图控制器中使用此返回值,例如:
(networkHelper.addProgressBar())(self.view)
如果您想在视图控制器上创建进度视图,并在那里进行管理,那就是。
class NetworkHelper {
...
func doAnythingWithNetwork(withProgress: @escaping (NSProgress) -> (),
completion: @escaping (Data?, Error?) -> ()) {
...
// When you get any progress (like in Alamofire for example).
// Pass it to the callback
withProgress(progress)
...
}
}
然后在你的viewController中:
let networker = NetworkHelper()
...
@IBAction func buttonClicked(_ sender: Any?) {
networker.doAnythingWithNetwork(withProgress: { [weak self] progress in
// You can use your viewController here (note: use 'self?', not
// 'self', here self is "weak", only to avoid memory leaks).
// Note: Any update of the view must be in DispatchQueue.main
}, completion: { [weak self] data, error in
// Your usual completion handler.
})
}
但推荐的解决方案是让您的NetworkHelper
只是一个模型,只是为了处理Web请求和数据。 SOLID原则具有单一责任原则"即设计每个对象只有一个责任。
视图(或viewcontroller)应该处理addProgressBar
,而NetworkHelper应该通过委托或闭包/块将此进度传递给更新视图的viewcontroller。