【问题标题】:Activity Indicator appeared in Wrong View Hierarchy活动指示器出现在错误的视图层次结构中
【发布时间】:2020-05-18 03:27:30
【问题描述】:

我在加载到下一个视图时设置了活动指示器。原始视图包含按钮的 tableView,单击按钮时它将指向下一个视图。但是,当返回原始视图时,它不会出现。它适用于另一个视图转换,但我不知道为什么它在这里不起作用。

这里是处理到下一个视图的按钮点击功能:

@objc func remark(_ sender: UIButton) {
    ViewControllerUtils().showActivityIndicator(uiView: self.tableView)

    DispatchQueue.main.async {
        self.markDetailsDelegate?.getStudentList(paperId: sender.paperId!, schoolClass: sender.schoolClass!, studentToShow: sender.studentToShow, questionNo: sender.questionNo!, readOnlyFlag: false) { returnList, studentReturnList, returnMarkBox, returnMCOptionBox, returnStudentMarkList, error  in
            self.pdfFileList = returnList!
            self.studentList = studentReturnList!
            self.questionMarkBox = returnMarkBox!
            self.mcQuestionOptionBox = returnMCOptionBox!
            self.studentMarkList = returnStudentMarkList!
        }

        DispatchQueue.main.async {
            ViewControllerUtils().hideActivityIndicator(uiView: self.tableView)
        }
    }
}

重新加载tableView的功能(一旦返回到tableView,就调用它重新加载):

@objc func reloadMarkDetails() {
    ViewControllerUtils().showActivityIndicator(uiView: self.tableView)

    DispatchQueue.main.async {
        self.markDetailsDelegate?.reloadMarkDetails(paperId: self.currentPaperId, schoolClass: self.currentSchoolClass) { returnPDFFileList, returnStudentList, returnQuestionMarkBox, returnMCQuestionOptionBox, returnStudentMarkList, returnPaperCommentList, returnPaperSummary, returnMarkSummary, returnTagSummary, returnLastMarkedSummary, returnAnsNoOfPage, returnDatetime, returnPaperFreezedFlag, error in
            self.studentList = returnStudentList
            self.studentMarkList = returnStudentMarkList
            self.markSummary = returnMarkSummary
            self.lastMarkedSummary = returnLastMarkedSummary
            self.paperFreezedFlag = returnPaperFreezedFlag

            DispatchQueue.main.async {
                ViewControllerUtils().hideActivityIndicator(uiView: self.tableView)

                self.tableView.reloadData()
                self.tableView.layoutIfNeeded()
            }
        }
    }
}

管理活动指示器的实用程序类:

class ViewControllerUtils: UIView {

    static var shared = ViewControllerUtils()

    var container: UIView = UIView()
    var loadingView: UIView = UIView()
    var activityIndicator: UIActivityIndicatorView = UIActivityIndicatorView()
    var loadingTextLabel = UILabel()
    let margin: CGFloat = 20.0

    /*
     Show customized activity indicator (with text),
     actually add activity indicator to passing view

     @param uiView - add activity indicator to this view
     @param title - add title to activity indicator
     */
    func showActivityIndicator(uiView: UIView, title: String) {
        container.frame = uiView.frame
        container.center = uiView.center
        container.backgroundColor = UIColorFromHex(rgbValue: 0x444444, alpha: 0.2)

        loadingView.frame = CGRect(x: 0, y: 0, width: 230, height: 60)
        loadingView.center = uiView.center
        loadingView.backgroundColor = UIColorFromHex(rgbValue: 0xffffff, alpha: 1.0)
        loadingView.clipsToBounds = true
        loadingView.layer.cornerRadius = 10
        loadingView.layer.shadowColor = UIColor.black.cgColor
        loadingView.layer.shadowOpacity = 1
        loadingView.layer.shadowOffset = .zero
        loadingView.layer.shadowRadius = 10

        activityIndicator.frame = CGRect(x: 0.0, y: 5.0, width: 40, height: 40);
        activityIndicator.style = UIActivityIndicatorView.Style.gray
        activityIndicator.center = CGPoint(x: (activityIndicator.frame.size.width + margin) / 2, y: loadingView.frame.size.height / 2)

        loadingTextLabel.textColor = UIColor.black
        loadingTextLabel.text = title
        loadingTextLabel.font = .systemFont(ofSize: 16, weight: .medium)
        loadingTextLabel.textAlignment = .center
        loadingTextLabel.sizeToFit()
        loadingTextLabel.adjustsFontSizeToFitWidth = true
        loadingTextLabel.lineBreakMode = NSLineBreakMode.byWordWrapping
        loadingTextLabel.frame = CGRect(x: activityIndicator.frame.size.width + margin * 0.5, y: activityIndicator.frame.origin.y, width: loadingView.frame.size.width - activityIndicator.frame.size.width - margin, height: activityIndicator.frame.size.height)

        loadingView.addSubview(activityIndicator)
        loadingView.addSubview(loadingTextLabel)
        container.addSubview(loadingView)
        uiView.superview?.addSubview(container)
        activityIndicator.startAnimating()
    }

    /*
     Show customized activity indicator (without text),
     actually add activity indicator to passing view

     @param uiView - add activity indicator to this view
     */
    func showActivityIndicator(uiView: UIView) {
        container.frame = uiView.frame
        container.center = uiView.center
        container.backgroundColor = UIColorFromHex(rgbValue: 0xffffff, alpha: 0.5)

        loadingView.frame = CGRect(x: 0, y: 0, width: 80, height: 80)
        loadingView.center = container.center
        loadingView.backgroundColor = UIColorFromHex(rgbValue: 0x444444, alpha: 0.7)
        loadingView.clipsToBounds = true
        loadingView.layer.cornerRadius = 10
        loadingView.layer.cornerRadius = 10
        loadingView.layer.shadowColor = UIColor.black.cgColor
        loadingView.layer.shadowOpacity = 1
        loadingView.layer.shadowOffset = .zero
        loadingView.layer.shadowRadius = 10

        loadingTextLabel.removeFromSuperview()

        activityIndicator.frame = CGRect(x: 0.0, y: 0.0, width: 40.0, height: 40.0);
        activityIndicator.style = UIActivityIndicatorView.Style.whiteLarge
        activityIndicator.center = CGPoint(x: loadingView.frame.size.width / 2, y: loadingView.frame.size.height / 2);

        loadingView.addSubview(activityIndicator)
        container.addSubview(loadingView)
        uiView.superview?.addSubview(container)
        activityIndicator.startAnimating()
    }

    /*
     Change text of activity indicator

     @param message - modified text
     */
    func changeTextToActivityIndicator(message: String) {
        loadingTextLabel.text = message
    }

    /*
     Hide activity indicator
     Actually remove activity indicator from its super view

     @param uiView - remove activity indicator from this view
     */
    func hideActivityIndicator(uiView: UIView) {
        activityIndicator.stopAnimating()
        container.removeFromSuperview()

        print("[DEBUG] Stop Activity Indicator at View - \(uiView)")
    }

    /*
     Define UIColor from hex value

     @param rgbValue - hex color value
     @param alpha - transparency level
     */
    func UIColorFromHex(rgbValue:UInt32, alpha:Double=1.0)->UIColor {
        let red = CGFloat((rgbValue & 0xFF0000) >> 16)/256.0
        let green = CGFloat((rgbValue & 0xFF00) >> 8)/256.0
        let blue = CGFloat(rgbValue & 0xFF)/256.0
        return UIColor(red:red, green:green, blue:blue, alpha:CGFloat(alpha))
    }

}

我试图通过使用 Debug View Hierarchy 找出为什么在返回原始视图时指示器没有显示,结果如下:

在 segue 过渡期间我做错了什么吗?如果有人可以帮助我,非常感谢!

【问题讨论】:

  • 当你回到你的视图时,你的指标代码可能没有被调用,所以把你的代码放在 viewwillappear 方法中,它会起作用并从 viewdidload 中删除你的代码。
  • 感谢@VipinPareek!但是我已经尝试过了,但它不起作用。在 ViewDidLoad 中没有调用它,因为它是 tableView 内的一组按钮,并且通过点击这些按钮触发移动到 View B。

标签: ios swift uiactivityindicatorview


【解决方案1】:

我认为应该是

@objc func remark(_ sender: UIButton) {
    ViewControllerUtils().showActivityIndicator(uiView: self.tableView)

    self.markDetailsDelegate?.getStudentList(paperId: sender.paperId!, schoolClass: sender.schoolClass!, studentToShow: sender.studentToShow, questionNo: sender.questionNo!, readOnlyFlag: false) { returnList, studentReturnList, returnMarkBox, returnMCOptionBox, returnStudentMarkList, error  in

        DispatchQueue.main.async {
            ViewControllerUtils().hideActivityIndicator(uiView: self.tableView)

            self.pdfFileList = returnList!
            self.studentList = studentReturnList!
            self.questionMarkBox = returnMarkBox!
            self.mcQuestionOptionBox = returnMCOptionBox!
            self.studentMarkList = returnStudentMarkList!
        }
    }
}

【讨论】:

  • 谢谢,但没有任何改变。
  • @markandshare,那么它不在提供的代码中。你会显示那些 showActivityIndi​​cator/hideActivityIndi​​cator 代码吗?
  • 这是点击tableView的一个按钮指向下一个视图的功能。但是在返回后重新加载 tableView 时,还有另一个地方显示/隐藏活动指示器。我已经用showActivityIndicatorhideActivityIndicator 更新了代码。请看一看。
猜你喜欢
  • 1970-01-01
  • 2018-05-24
  • 2017-08-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-24
  • 2012-10-16
  • 2014-01-24
相关资源
最近更新 更多