11

I have decided to use UIScrollView instead of UITableView in my app for many reasons. When I was using UITableView, I was able to add a UIRefreshControl with no issue whatsoever. When I use the same code on my UIScrollView however, nothing happens. I have tried several third-party refresher libraries, and none seem to work. Any help is appreciated.

Source:

var scroll: UIScrollView!
var refreshControl: UIRefreshControl!

override func viewDidLoad()
{
    super.viewDidLoad()

    self.scroll = UIScrollView(frame: self.view.frame)
    self.scroll.contentSize = CGSize(width: self.view.bounds.width, height: 10)

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

    self.view.addSubview(self.scroll)

    //self.loadPostsIntoCards()
}

The loadPostsIntoCards method does my API call, and creates UIViews ("cards") that are added to the UIScrollView. I then change the contentSize of the UIScrollView based upon the total height of all the cards. The cards are added perfectly, and the scroll view acts as expected, except with regards to the UIRefreshControl.

Thanks in advance for any help!

Connor Hicks
  • 755
  • 2
  • 8
  • 25

1 Answers1

18

EDIT:
After some fooling around I found another solution that will allow the scrollview to scroll (and trigger the refresh control) even when the contentSize is smaller than the scrollView height. Just set the alwaysBounceVertical property to true:

self.scroll.alwaysBounceVertical = true

OLD ANSWER:
Your content size should be larger than your scrollview's height in order to make this work. Change this line:

self.scroll.contentSize = CGSize(width: self.view.bounds.width, height: 10)

To:

self.scroll.contentSize = CGSize(width: self.view.bounds.width, height: self.view.bounds.height+1)

That would allow your RefreshControl to kick in.

Or, in your case you should probably calculate the height of your cards and then set that as the height for your contentSize.

donnywals
  • 7,241
  • 1
  • 19
  • 27
  • Setting alwaysBounceVertical doesn't seem to be working for me :/ – Connor Hicks May 26 '15 at 18:15
  • 1
    I just copied your code, added alwaysBounceVertical and it works.. :/ – donnywals May 26 '15 at 18:18
  • do you have a navigation bar? I think that may be what's causing my issues. – Connor Hicks May 26 '15 at 18:19
  • I don't, I just have a plain viewController. My guess is that somehow the refresh control might be below your navigation bar. Is your content not under the navigation bar? – donnywals May 26 '15 at 18:21
  • no, the content is not covered by the navigation bar. The view controller is embedded in a navigation controller, which supplies the navigation bar. – Connor Hicks May 26 '15 at 18:24
  • I tested your code with a navigationController. It still works just fine.. I added my demo code to github https://github.com/donnywals/RefreshControl – donnywals May 26 '15 at 18:56
  • Alright so now I've realized that when there is no content in my scrollView, the refreshControl works properly, but after the refresh is triggered and the content is loaded, the refreshControl stops working. – Connor Hicks May 26 '15 at 19:15
  • @donnywals interesting. Although the docs says "If this property is set to true and **bounces** is true, vertical dragging is allowed even if the content is smaller than the bounds of the scroll view. The default value is false" – onmyway133 Jun 06 '16 at 07:40
  • @onmyway133 correct, My initial answer was to make the contentSize larger that the scrollview. In the edit I figured out that `alwaysBounceVertical` does the trick like you said ;) – donnywals Jun 06 '16 at 08:49