当我返回查看控制器时,在tableview顶部刷新控制

时间:2016-07-04 12:01:09

标签: ios xcode swift uirefreshcontrol

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

When I go back to view controller

这是代码的一部分:

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!)
}

}

有什么想法吗?

10 个答案:

答案 0 :(得分:10)

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

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

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

答案 1 :(得分: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)

答案 2 :(得分:3)

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

refreshControl.layer.zPosition = -1

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

两者必须成对使用。

答案 3 :(得分:1)

在索引0处插入刷新控件无效,只需将其设置为表格视图的背景视图即可:

tableView.backgroundView = refreshControl

答案 4 :(得分:0)

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

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

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

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

答案 5 :(得分:0)

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

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就足够了,而且往往更灵活。

希望有所帮助

答案 6 :(得分:0)

不幸的是,上面没有一个解决方案帮助过我。

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

但我发现另一种解决方法是立即隐藏刷新控件。此处必须进行async来电。

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

我在另一篇文章中受到this回答的启发。

答案 7 :(得分:0)

对我来说,我在表视图的第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()
    }

如果我只是将表格分配给刷新控件懒惰变量,它会在109像素的内容上偏移20像素,从而使a跳转,因此我将其固定为这样。我使用的是UIViewController而不是UITableViewController,希望这会有所帮助

答案 8 :(得分:0)

我们必须做一个简单的配置,将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
    }
} 

希望对人民有帮助:-)

答案 9 :(得分:0)

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
}()