【问题标题】:Refresh Control on top of tableview when I go back to view controller当我返回视图控制器时,在 tableview 顶部刷新控件
【发布时间】:2016-11-06 03:48:28
【问题描述】:

由于某种原因,第一次加载视图控制器时,刷新控件的行为符合预期(向下滑动时显示在 tableview 下)。问题是当我点击另一个选项卡,然后返回视图控制器时,刷新控件不再淡入并且在 tableview 顶部可见。

这是代码的一部分:

class CoreTableViewController : UIViewController, UITableViewDataSource, UITableViewDelegate {

var tableView:UITableView!
var tableData:Array<AnyObject> = []
var dataFetched:Bool = false
var refreshControl:UIRefreshControl?

override func viewDidLoad() {
    super.viewDidLoad()

    self.edgesForExtendedLayout = UIRectEdge.None;

    self.tableView = self.assignTableView()
    self.tableView.delegate = self
    self.tableView.dataSource = self
    self.tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "Cell")
    self.tableView.separatorStyle = UITableViewCellSeparatorStyle.None;

    if self.enableRefresher() {
        self.setRefreshControl()
    }
}

func enableRefresher() -> Bool {
    return true
}

func fetchData(cleanFirst:Bool = false) {
    // Fetch data.
}

func refresh() {
    self.fetchData(true)
    self.refreshControl!.endRefreshing()
}

func setRefreshControl() {
    self.refreshControl = UIRefreshControl()
    //self.refreshControl!.attributedTitle = NSAttributedString(string: "Actualizar")
    self.refreshControl!.addTarget(self, action: #selector(CoreTableViewController.refresh), forControlEvents: UIControlEvents.ValueChanged)
    self.tableView.addSubview(refreshControl!)
}

}

有什么想法吗?

【问题讨论】:

  • 请说清楚,我不明白你想要什么,你得到什么

标签: ios xcode swift uirefreshcontrol


【解决方案1】:

我在这里找到了解决方法:https://stackoverflow.com/a/29088409/209200

应该是self.tableView.insertSubview(refreshControl!, atIndex: 0),而不是self.tableView.addSubview(refreshControl!)

这导致 refres 控件出现在 tableview 上。

【讨论】:

  • 即便如此,从 ios 11.x 开始的表格上方仍显示 refreshesControl(ios 9 工作正常)
  • iOS 11 存在模拟器错误,但设备运行正常。
【解决方案2】:

尝试将 z 索引设置为 -1,这意味着 UIRefreshControl 在任何视图后面。

refreshControl.layer.zPosition = -1

tableView.refreshControl?.beginRefreshing()
self.tableView.refreshControl?.endRefreshing()

两者必须成对使用。

【讨论】:

  • 这对我有用,谢谢!
【解决方案3】:

试试这个,

上述解决方案都很好,但 tableView.refreshControl 仅适用于 UITableViewController,直到 iOS 9.x 并且从 iOS 10.x 开始进入 UITableView。

要解决这个问题,只需使用:

用 Swift 3 编写 -

let refreshControl = UIRefreshControl()
refreshControl.addTarget(self, action: #selector(FeedViewController.loadNewData), for: UIControlEvents.valueChanged)
// Fix for the RefreshControl Not appearing in background
tableView?.addSubview(refreshControl)
tableView.sendSubview(toBack: refreshControl)

【讨论】:

    【解决方案4】:

    在索引0处插入刷新控件不起作用,只需将其设置为tableview的背景视图:

    tableView.backgroundView = refreshControl
    

    【讨论】:

    • 太棒了!这就是我要找的东西 - 谢谢!
    【解决方案5】:

    当我检查你的代码和你的问题时,我认为问题出在:

    “除了将刷新控件分配给表格视图控制器的refreshControl 属性外,您还必须配置控件本身的目标和操作。” https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIRefreshControl_class/index.html#//apple_ref/occ/instm/UIRefreshControl/endRefreshing

    因此,从文档中,您需要使用 UITableViewController,而不是 UIViewController。并设置它的 refreshControl 属性。

    在当前状态下,您只需将 UIRefreshControl 添加为常规子视图。

    【讨论】:

    • 如果你想使用集合视图怎么办?我对集合视图中的刷新控件有完全相同的问题。
    • @Ricardo,查看集合视图文档。看起来 UIRefreshControl 是专门为 UITableView 制作的。也许您需要浏览已经实现的解决方案或自己制作......无论如何,这是一个不同问题的主题。
    【解决方案6】:

    看起来没问题,我怀疑这是因为一些关于创建控件本身的竞争条件。我发现在这种情况下使用惰性属性有很大帮助。我会这样做:

    lazy var refreshControl: UIRefreshControl = {
        let refreshControl = UIRefreshControl()
        refreshControl.addTarget(self, action:#selector(CoreTableViewController.refresh(_:)), forControlEvents: .ValueChanged)
        return refreshControl
    }()
    
    override public func viewDidLoad() {
        super.viewDidLoad()
        if self.enableRefresher() {
            tableView.addSubview(refreshControl)
        }
        ........
    }
    
    func refresh(refreshControl: UIRefreshControl) {
        self.fetchData(true)
        refreshControl.endRefreshing()
    }
    

    您不需要使用 TableViewController,UIViewController 就足够了,而且通常更灵活。

    希望对你有帮助

    【讨论】:

      【解决方案7】:

      不幸的是,以上任何一种解决方案都没有帮助我。

      在我的例子中,当表格视图为空时,在重新加载表格视图后会出现一个刷新控件。也许如果表格视图至少有一行它只是隐藏了刷新控件,我还没有检查它。此外,当我的视图控制器再次出现时,它就像一种解决方法,它隐藏了刷新控件。

      但我找到了另一种解决方法来立即隐藏刷新控件。此处必须拨打async

      tableView.reloadData()
      DispatchQueue.main.async {
        refreshControl.endRefreshing()
      }
      

      我受到this 在另一篇帖子中的回答的启发。

      【讨论】:

        【解决方案8】:

        对我来说,在表视图的第 0 个索引处使用插入并像惰性 var 一样初始化:

          private lazy var refreshControl: UIRefreshControl = {
                let refreshControl = UIRefreshControl()
                refreshControl.tintColor = .gray
                refreshControl.addTarget(self, action: #selector(refreshFollowingList(_:)), for: .valueChanged)
                return refreshControl
            }()
        
            func setupRefresher() {
                self.tableView.insertSubview(refreshControl, at: 0)
            }
        
            override func viewDidLoad() {
                super.viewDidLoad()
        
                setupRefresher()
            }
        

        如果我刚刚将惰性 var 分配给 tableviews 刷新控件,它会在 109 像素的内容偏移处跳跃 20 像素,所以我像这样修复它。我使用的是 UIViewController 而不是 UITableViewController,希望这会有所帮助

        【讨论】:

          【解决方案9】:

          我们必须做一个简单的配置来将 UIRefreshControl 分配给 tableView,如下所示。

          @IBOutlet weak var tableView : UITableView! {
              didSet {
                  tableView.dataSource = self
                  tableView.delegate = self
                  tableView.refreshControl = UIRefreshControl()
                  tableView.refreshControl?.addTarget(self, action: #selector(handleRefresh(_:)), for: UIControl.Event.valueChanged)
          
              }
          }
          

          现在添加 handleRefresh 方法来处理你的逻辑

          @objc
          func handleRefresh(_ refreshControl: UIRefreshControl) {
              // Here i am disabling the user interaction while refreshing
              tableView.alpha = 0.5        
              self.view.isUserInteractionEnabled = false
              // Get your work done here
          
              // At the end stop the refresh control and enable user interaction again.      
              tableView.refreshControl?.endRefreshing()
              tableView.alpha = 1.0        
              self.view.isUserInteractionEnabled = true
          }
          

          现在,当您从另一个标签页返回时,刷新控件停止旋转。所以要处理这个添加下面的代码行......

          override func viewWillAppear(_ animated: Bool) {
              super.viewWillAppear(animated)
              // Here we are forcefully end refreshing and again starting, as we know it works when we scroll down the table. We are doing it programmatically.
              if tableView.refreshControl!.isRefreshing {
                  let contentOffset = tableView.contentOffset
                  tableView.refreshControl?.endRefreshing()
                  tableView.refreshControl?.beginRefreshing()
                  tableView.contentOffset = contentOffset
              }
          } 
          

          希望它能帮助人们:-)

          【讨论】:

            【解决方案10】:

            UIRefreshControl 的容器视图类似于 UIView,你也应该设置isOpaque = trueclipToBounds = true

            private lazy var refreshControl: UIRefreshControl = {
                let refreshControl = UIRefreshControl(frame: .zero)
                refreshControl.isOpaque = true
                refreshControl.clipsToBounds = true
                refreshControl.backgroundColor = .black
                refreshControl.addTarget(self, action: #selector(self.refresh(_:)), for: .valueChanged)
                return refreshControl
            }()
            

            【讨论】:

              猜你喜欢
              • 2016-11-21
              • 2021-09-08
              • 2013-03-31
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2016-07-28
              • 2018-04-02
              相关资源
              最近更新 更多