ilan
ilan

Reputation: 4462

pull to refresh not working with small amount of cells

I have a feed view controller (implemented with a UICollectionViewController) When i don't have enough cells to cover the hall screen height the pull to refresh isn't working. How can i fix this?

Code:

var refreshControl: UIRefreshControl!

    override func viewDidLoad() {
    super.viewDidLoad()


    self.refreshControl = UIRefreshControl()
    self.refreshControl.attributedTitle = NSAttributedString(string: "Pull to refresh")
    self.refreshControl.addTarget(self, action: "refresh:", forControlEvents: UIControlEvents.ValueChanged)
    self.postCollection.addSubview(refreshControl)
}

    func refresh(sender:AnyObject)
{
    getPost()
}

EDIT: by not working i mean that the uicollectionview cant be pulled down and the animation isn't starting.

Upvotes: 4

Views: 2571

Answers (4)

Magy Elias
Magy Elias

Reputation: 31

Programmatically: self.collectionView.alwaysBounceVertical = true

or From Storyboard: You should enable these two options Bounce options

Upvotes: 0

Manu
Manu

Reputation: 647

Swift 4

The following will force the collection view to always bounce, in this case vertically, even if the items are not filling the entire collection view height.

self.collectionView.alwaysBounceVertical = true

Upvotes: 7

Softlabsindia
Softlabsindia

Reputation: 921

    override func viewDidLoad() {
    super.viewDidLoad()

    refreshControl = UIRefreshControl()
    refreshControl.attributedTitle = NSAttributedString(string: "Pull to refresh")
    self.refreshControl.addTarget(self, action: #selector(refresh), for: .valueChanged)
    listview.addSubview(refreshControl)

}
func refresh(sender:AnyObject) {
    // Your code here
    refreshControl.endRefreshing()
}

Working fine

Upvotes: 0

st.derrick
st.derrick

Reputation: 4919

this means you are most likely not refreshing the tableview in the getPost() method. After you update data, you need to make a call to self.postCollection.reloadData().

Can you post code for cellForRowAtIndexPath? It's also possible that you aren't properly accounting for cells being reused.

EDIT: I believe I've solved it

I saw similar behavior to yours and it was related to Auto Layout and Size Classes

For me, the refresh control showed up on the right side, not centered:

Simulator:

bad-sim http://derrrick.com/stackoverflow/refreshcontrol/bad-sim.png

For you, it may be showing up off screen.

Notice how this appears when looking at the Storyboard (both "Use Auto Layout" and "Use Size Classes" are checked).

Xcode:

bad-xcode http://derrrick.com/stackoverflow/refreshcontrol/bad-xcode.png

One solution is to uncheck "Use Auto Layout". You probably need to then resize your tableview (I had to delete it and re-add it).

Then it should appear correctly.

Simulator:

good-sim http://derrrick.com/stackoverflow/refreshcontrol/good-sim.png

Xcode:

good-xcode http://derrrick.com/stackoverflow/refreshcontrol/good-xcode.png

Lastly, here is my code (although it is missing a method for refresh:)

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    @IBOutlet var postCollection: UITableView!
        var myCollection = ["hi", "there", "bob"]
        var refreshControl: UIRefreshControl!

        override func viewDidLoad() {
            super.viewDidLoad()

            if let myTableView = self.postCollection {
                self.postCollection!.registerClass(UITableViewCell.self, forCellReuseIdentifier: "Cell")
                self.postCollection!.delegate = self
                self.postCollection!.dataSource = self

                self.refreshControl = UIRefreshControl(frame: CGRectMake(0, 0, 40, 40))
                self.refreshControl.attributedTitle = NSAttributedString(string: "Pull to refresh")
                self.refreshControl.addTarget(self, action: "refresh:", forControlEvents: UIControlEvents.ValueChanged)
                self.postCollection.insertSubview(self.refreshControl, atIndex: 0)
            }
        }

         func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
            let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell
            cell.textLabel?.text = self.myCollection[indexPath.row]
            return cell
        }

        func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return self.myCollection.count
        }
    }

Upvotes: 0

Related Questions