我创建了自定义循环进度按钮。现在,我想在进度相同的两个视图控制器上显示它。
我创建了singleton类,以便在两个视图控制器上都只更新一个实例。下面是单例课程。
class DownloadView: UIView
{
@IBOutlet var contentView: UIView!
@IBOutlet var circleProgressButton: MyCircularProgressButton!
@IBOutlet var progressLbl: UILabel!
static var downloadView = DownloadView()
func sharedInstance(frame:CGRect)
{
self.frame = frame
commonInit()
}
private func commonInit()
{
Bundle.main.loadNibNamed("DownloadView", owner: self, options: nil)
contentView.fixInView(self)
}
}
extension UIView
{
func fixInView(_ container: UIView!) -> Void
{
self.frame = container.frame
container.addSubview(self)
}
}
实际结果-我在视图控制器1上,它包含圆形进度按钮,它将开始更新进度状态。现在,如果我移到视图控制器2上,它还包含圆形进度按钮,它将也开始更新进度。现在,如果我从视图控制器2移至视图控制器1,则视图控制器1上的圆形进度按钮将停止进行。
预期结果-如果我从视图控制器1移至视图控制器2,反之亦然,则应继续同时更新两个视图控制器上的循环进度按钮。
答案 0 :(得分:1)
因此,假设您有一个拥有进度值的代码。
final class ProgressOwner {
var progress: Float = 0
init() {}
}
let progressOwner = ProgressOwner()
我们需要一种接收通知并在进度视图中更新值的方法。这可以通过使用其中一种框架(NSNotificationCenter
,ReactSwift
,Combine
框架等)来实现,也可以像这样手动实现:
final class ProgressOwner {
var progress: Float = 0 {
didSet {
observers.forEach { $0(progress) } // When the progress changes we send it to every observer
}
}
private var observers: [(Float) -> ()] = [] // Store all the observers.
// Note that we store closures, so should be careful with memory management
init() {}
func observeProgress(_ callback: @escaping (Float) -> ()) {
DispatchQueue.main.async { // Making sure it is the main thread just not to break something in UI
self.observers.append(callback) // Adding callback as an observer
callback(self.progress) // Reporting current progress so that view can update
}
}
}
剩下的就是在视图控制器中设置视图。通常,使用viewDidLoad
方法很方便:
final class ViewController: UIViewController {
let progress: ProgressOwner = ... /// Need to setup the progress owner that you have
let progressView = MyCircularProgressButton()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(progressView) // Adding progress view
NSLayoutConstraint.activate([ // Placing the progress view in the center as an example. We use constraints here, but it can be achieved by setting its frame too
progressView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
progressView.centerYAnchor.constraint(equalTo: view.centerYAnchor)
])
// Adding connection to the progress updates
progress.observeProgress { [weak progressView] progress in
progressView?.progress = progress // Updating theprogress displayed by the view
}
}
}
就是这样。这只是关于如何解决类似任务的一般描述,因为我不知道如何命名代码中的所有类和变量。您可能应该对代码稍微调整一下解决方案。通常,我们不对视图应用单例模式,因为当视图意外从屏幕等上消失时,它会导致难以调试的代码。
答案 1 :(得分:1)
此处具有所有功能:您可能需要做一些可选的链接,所以要花点功夫;)
protocol DownloadDelegate {
func updateProgress(updatedProgress:Double)
}
let AppUtility = Utility.sharedUtility()
class Utility: NSObject {
var progeess:Double = 0.0
var delegate:DownloadDelegate?
class func sharedUtility()->Utility!
{
struct Static
{
static var sharedInstance:Utility?=nil;
static var onceToken = 0
}
Static.sharedInstance = self.init();
return Static.sharedInstance!
}
required override init()
{
}
func netwrokCall(){
progress = updatedProgress
delegate.updateProgress(updatedProgress:progress)
}
}
class firstViewController:UIViewController, DownloadDelegate{
func viewDidLoad(animated:Bool){
AppUtility.delegate=self
AppUtility.networkCall()
}
func updateProgress(updatedProgress:Double){
progressLbl.text = "\(progess)%"
circleProgressButton.progess = progess
}
}
class secondndViewController:UIViewController, DownloadDelegate{
func viewDidLoad(animated:Bool){
AppUtility.delegate=self
}
func updateProgress(updatedProgress:Double){
progressLbl.text = "\(progess)%"
circleProgressButton.progess = progess
}
}
答案 2 :(得分:1)
谢谢你们对我的帮助。我对这两个答案都投了赞成票。现在,在尝试了各种方法之后,我终于找到了解决这个问题的方法。没有单身人士,我已经解决了这个问题。我已经在视图控制器中使DownloadView对象成为静态对象,并从DownloadService类访问它。现在,我从DownloadService类更改了两个视图控制器中的progress值。