如何更新两个视图控制器上的循环进度按钮?我正在为循环进度按钮使用单例类

时间:2019-07-08 06:13:18

标签: ios swift iphone

我创建了自定义循环进度按钮。现在,我想在进度相同的两个视图控制器上显示它。

我创建了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,反之亦然,则应继续同时更新两个视图控制器上的循环进度按钮。

3 个答案:

答案 0 :(得分:1)

因此,假设您有一个拥有进度值的代码。

final class ProgressOwner {
    var progress: Float = 0
    init() {}
}

let progressOwner = ProgressOwner()

我们需要一种接收通知并在进度视图中更新值的方法。这可以通过使用其中一种框架(NSNotificationCenterReactSwiftCombine框架等)来实现,也可以像这样手动实现:

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值。