【问题标题】:Place activity indicator over uitable view将活动指示器放在合适的视图上
【发布时间】:2019-11-21 23:28:55
【问题描述】:

我在情节提要的UITableView 中放置了一个活动指示器。 如何将其置于屏幕中间和表格视图前面?

我试过了:

self.activityIndicator.center = self.tableView.center

但是现在,活动指示器位于视图的顶部中间!

【问题讨论】:

    标签: swift


    【解决方案1】:

    要在UITableView 中加载数据时显示活动指示器,您可以创建一个 UIView 并将其添加到主视图(在UITableView 的中心)。如果要显示如下:

    您可以使用函数setLoadingScreenremoveLoadingScreen 来做到这一点(如果您想查看示例项目,您可以转到here):

    class TableViewController: UITableViewController {
    
        // MARK: Properties
    
        /// Data source of the tableView
        var rows: [String] = []
    
        /// View which contains the loading text and the spinner
        let loadingView = UIView()
    
        /// Spinner shown during load the TableView
        let spinner = UIActivityIndicatorView()
    
        /// Text shown during load the TableView
        let loadingLabel = UILabel()
    
    
        // MARK: Methods
    
        override func viewDidLoad() {
    
            super.viewDidLoad()
    
            setLoadingScreen()
    
            loadData()
    
        }
    
        override func didReceiveMemoryWarning() {
    
            super.didReceiveMemoryWarning()
    
        }
    
    
        // MARK: - Table view data source
    
        override func numberOfSections(in tableView: UITableView) -> Int {
    
            return 1
    
        }
    
        override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    
            return rows.count
    
        }
    
        override func tableView(tableView: UITableView, cellForRowAt indexPath: NSIndexPath) -> UITableViewCell {
    
            let cell = tableView.dequeueReusableCell(withIdentifier: "myCell", for: indexPath)!
            cell.textLabel!.text = rows[indexPath.row]
    
            return cell
    
        }
    
    
        // MARK: Private methods
    
        // Load data in the tableView
        private func loadData() {
    
            // Simulate a delay of some operations as a HTTP Request            
            DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(20)) {
    
                self.rows = ["Row 1", "Row 2", "Row 3", "Row 4", "Row 5"]
    
                self.tableView.reloadData()
                self.tableView.separatorStyle = .singleLine
                self.removeLoadingScreen()
    
            }
    
        }
    
        // Set the activity indicator into the main view
        private func setLoadingScreen() {
    
            // Sets the view which contains the loading text and the spinner
            let width: CGFloat = 120
            let height: CGFloat = 30
            let x = (tableView.frame.width / 2) - (width / 2)
            let y = (tableView.frame.height / 2) - (height / 2) - (navigationController?.navigationBar.frame.height)!
            loadingView.frame = CGRect(x: x, y: y, width: width, height: height)
    
            // Sets loading text
            loadingLabel.textColor = .gray
            loadingLabel.textAlignment = .center
            loadingLabel.text = "Loading..."
            loadingLabel.frame = CGRect(x: 0, y: 0, width: 140, height: 30)
    
            // Sets spinner
            spinner.activityIndicatorViewStyle = .gray
            spinner.frame = CGRect(x: 0, y: 0, width: 30, height: 30)
            spinner.startAnimating()
    
            // Adds text and spinner to the view
            loadingView.addSubview(spinner)
            loadingView.addSubview(loadingLabel)
    
            tableView.addSubview(loadingView)
    
        }
    
        // Remove the activity indicator from the main view
        private func removeLoadingScreen() {
    
            // Hides and stops the text and the spinner
            spinner.stopAnimating()
            spinner.isHidden = true
            loadingLabel.isHidden = true
    
        }
    
    }
    

    【讨论】:

    • +1,但在我的情况下 removeLoadingScreen() 行为不正常,即使在表格单元格出现后标签和指示器仍然可见。几秒钟后,标签和指示器消失了。我在 removeLoadingScreen() 中使用 self.loadingView.removeFromSuperview() 修复了它
    【解决方案2】:

    步骤如下:按照 Chrissukhram 的说明进行操作。

    1. 在表格视图上拖一个视图步骤
    2. 拖动活动 视图上的指示器
    3. 将活动指示器与 容器中的水平和垂直中心

    4. 制作 IBOutlet 视图和活动指示器的连接

    5. 启动 活动指标
    6. 停止并隐藏:activityIndicatorLarge.hidesWhenStopped = true activityView.hidden = true

    【讨论】:

      【解决方案3】:

      最简单的方法是在你的tableView backgroundView中添加一个UIActivityIndi​​catorView

          let spinner = UIActivityIndicatorView(activityIndicatorStyle: .gray)
      
          spinner.startAnimating()
          tableView.backgroundView = spinner
      

      默认居中。

      【讨论】:

      • 你在 TableViewController 中测试过这个吗?这对我不起作用。
      • 使用 let spinner = UIActivityIndi​​catorView(style: .large)
      【解决方案4】:

      如果你使用复杂视图:

       func setupSpinner(){
          spinner = UIActivityIndicatorView(frame: CGRect(x: 0, y: 0, width: 40, height:40))
          spinner.color = UIColor(Colors.Accent)
          self.spinner.center = CGPoint(x:UIScreen.main.bounds.size.width / 2, y:UIScreen.main.bounds.size.height / 2)
          self.view.addSubview(spinner)
          spinner.hidesWhenStopped = true
      }
      

      【讨论】:

        【解决方案5】:

        如果此活动指示器用于将信息加载到UITableView,您应该创建一个与UITableView 大小相同的单独加载UIView,并将活动指示器放置在该视图的中心,而不是@ 987654324@自己。

        然后将加载UIView 添加到您的主视图(表格视图上方)并根据加载状态将其设置为隐藏或可见。

        【讨论】:

        • 如何将 uiView 放在 tableView 上?
        • 添加 UITableView 后,您可以将正在加载的 UIView 添加到 ViewControllers 主视图 (self.view)。本质上,您相互添加视图的顺序就是它们在显示时的堆叠顺序。
        • 所以我必须以这种方式更改情节提要:
        • 是的,如果您在情节提要中执行此操作会容易得多,只需在文档大纲视图(情节提要左侧)中的 tableView“下方”添加 UIView
        • @chrissukhram,这在 Xcode 8 中仍然有效吗?当我尝试在文档大纲中的 tableView 下拖动 uiview 时,Xcode 会在 First ResponderExit 之间而不是在控制器内部推动它?
        【解决方案6】:

        我认为您在情节提要中直接使用了 UITableView。这就是为什么你不能拖动主视图(tableview)的uiview顶部。删除 UItableview 控制器并将 UIViewController 拖到情节提要中。然后拖一个tableview进去。然后将另一个视图拖到 tableview 上以获取活动指示器。不要忘记在你的 UIViewController 中处理 UItableviewdelegate 和 datasource 方法。

        【讨论】:

          【解决方案7】:

          在你的 tableViewController 的 viewDidLayoutSubviews 方法中试试这个:

          override func viewDidLayoutSubviews() {
              let screenSize = UIScreen.main.bounds
              activityIndicator.frame = CGRect(x: screenSize.width / 2, y: screenSize.height / 2, width: 5, height: 5)
              activityIndicator.color = .white
              activityIndicator.hidesWhenStopped = true
          
              if let baseView = view.superview {
                  baseView.addSubview(activityIndicator)
              }
          }
          

          activityIndicator 是我的TableViewController 类的存储属性。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2017-08-04
            • 2016-06-25
            • 2019-11-12
            • 2016-12-12
            • 1970-01-01
            • 2014-01-08
            • 1970-01-01
            相关资源
            最近更新 更多