Giter Site home page Giter Site logo

odrefreshcontrol's Introduction

__*Notice:* There’s a new 2.0 branch where I updated the control for iOS7 plus I plan to do some interesting new features. If people could try it out so I can be sure I didn’t break anything it’d be great, and report any issue you find, I’d really appreciate that :)

ODRefreshControl

ODRefreshControl is a “pull down to refresh” control for UIScrollView, like the one Apple introduced in iOS6, but available to anyone from iOS4 and up.

Installation

  • Drag the ODRefreshControl/ODRefreshControl folder into your project.
  • Add the QuartzCore framework to your project.
  • #import "ODRefreshControl.h"

Important note if your project doesn’t use ARC: you must add the -fobjc-arc compiler flag to ODRefreshControl.m in Target Settings > Build Phases > Compile Sources.

Usage

(see sample Xcode project in /Demo)

Adding a refresh control to your table view

ODRefreshControl *refreshControl = [[ODRefreshControl alloc] initInScrollView:self.scrollView];

To know when the refresh operation has started, add an action method to the UIControlEventValueChanged event of the control

[refreshControl addTarget:self action:@selector(dropViewDidBeginRefreshing:) forControlEvents:UIControlEventValueChanged];

If you’d like to programmatically start the refresh operation, use

[refreshControl beginRefreshing];

Remember to tell the control when the refresh operation has ended

[refreshControl endRefreshing];

Customization

The ODRefreshControl can be customized using the following properties:

@property (nonatomic, strong) UIColor *tintColor;
@property (nonatomic, assign) UIActivityIndicatorViewStyle activityIndicatorViewStyle;
@property (nonatomic, strong) UIColor *activityIndicatorViewColor; // iOS5 or more

Credits

ODRefreshControl is brought to you by Fabio Ritrovato and contributors to the project. If you have feature suggestions or bug reports, feel free to help out by sending pull requests or by creating new issues. If you’re using ODRefreshControl in your project, attribution would be nice.

odrefreshcontrol's People

Contributors

dongminkim avatar fernandonf avatar jwhitehorn avatar jwilling avatar lexrus avatar msnexploder avatar nicklockwood avatar sephiroth87 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

odrefreshcontrol's Issues

2.0 Control below section header

The control is appearing below the section header when it isn't displayed yet, so it appears to be appearing out of nowhere in the table

delegate

Hi,
can you add the delegate for enable/disable it??!

Ignore positive content offsets

I've been poking around this component and noticed that it recomputes the paths at every contentOffset change. Is this really necessary? Perhaps I'm missing some sort of edge case here but I've tried to ignore all positive content offsets and it still seems to work fine. This frees up some resources during scrolling.

CGFloat offset = [[change objectForKey:@"new"] CGPointValue].y;
if (offset > 0) {
    return;
}

beginRefreshing has no animation

When I call beginRefreshing, there is no Activity view shown. The table scrolls down to reveal the control, but there's nothing visible.

Pull to refresh for horizontal orientation

First I would like to thank you very much for this sharing. It's awesome and I am adding it to my project.

Is there a way to modify it a little bit so it could support landscape orientation better? Not sure if it's my tableview cell too high or what, I have to pull really fast in order the "refresh" part to work, otherwise, it's just "pull-and-bounds-back". By saying "really fast", I meant almost like a swipe from top to bottom.

For comparison, in portrait orientation, I can slowly drag the tableview down and release to refresh. Any ideas? Many thanks!

bug when fast dragging tableview

Hi. There is a bug when I fast pull tableview down to refresh that will cause tableview cannot back to correct position.
The refresh control works nice when I drag the tableview slowly. But when I fast drag, even like a swipe gesture on the tableview, the refresh control will send event to its target to begin refresh,while the tableview is still scrolling inertially. And before the scrolling stop, the refresh request has finished and ask refresh control to end refreshing. Because of the continuing scrolling, the refresh control still receive the scrolling event and finally "hang the tableview in the air" with a content offset...

I'm not sure whether my description can be understood, you can try this situation under a very fast WIFI. It will occur..

Thx.

ODRefreshControl under NavigationBar

Hello,

I recently upgraded to the newest version of ODRefreshControl. With the Upgrade the ODRefreshControl appears under the UINavigationBar.

I checked the Code, and found the part which was removed, this is causing the error.

WHY this part was removed?

bildschirmfoto 2015-07-21 um 17 24 04

TableView deallocated while key value observers still registered

Hi,

I noticed a crash when you have a navigation stack of tableviewcontroller that use your lib.

To reproduce the bug, open multiple tableviewcontroller. Then simulate a memory warning and you'll see that something is wrong with your KeyValue observing.

The problem comes from this line :

[scrollView addObserver:self forKeyPath:@"contentOffset" options:NSKeyValueObservingOptionNew context:nil];

By the way thx a lot for your lib, great work! :)

KVO issue

Hi, thanks for the amazing control!

App is crashing and log is:

An instance 0xeb38e00 of class UITableView was deallocated while key value observers were still registered with it. Observation info was leaked, and may even become mistakenly attached to some other object. Set a breakpoint on NSKVODeallocateBreak to stop here in the debugger. Here's the current observation info:
<NSKeyValueObservationInfo 0x3457d0> (
<NSKeyValueObservance 0x342350: Observer: 0x345760, Key path: contentOffset, Options: <New: YES, Old: NO, Prior: NO> Context: 0x0, Property: 0xe6ac080>

I tried to use
[refreshControl removeTarget:self action:@selector(dropViewDidBeginRefreshing:) forControlEvents:UIControlEventValueChanged];
but it doesn't help

Overwritten insets

Hi guys
I've localized a bug in your code

  • (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
    {
    if ([keyPath isEqualToString:@"contentInset"]) {
    if (!_ignoreInset) {
    self.originalContentInset = [[change objectForKey:@"new"] UIEdgeInsetsValue];
    self.frame = CGRectMake(0, -(kTotalViewHeight + self.scrollView.contentInset.top), self.scrollView.frame.size.width, kTotalViewHeight);
    }
    return;
    }
    ...

When animation starts, self.originalContentInset={top,left,bottom,right} and self.scrollView.contentInset={top+kOpenedViewHeight,left,bottom,right}. When, if I set scrollView's contentInset - the OpenedViewHeight-part of 'top' will be written to original 'top'; moreover, frame's height will be set to kTotalViewHeight while it is kOpenedViewHeight. As a result we have:
screenshot 2013 09 24 22 16 26

Thin line at the top isn't a cell, it's refresh view; download indicator is hidden under upper bar

Activity not visible if scroll view can scroll horzontally

If I am using ODRefreshControl from my UITableView it is centered fine, but if I use it in my UIScrollView that can scroll horizontally, the activity is invisible if the scroll view is scrolled horizontally. The activity is only visible if the scroll view is at the left edge of the screen, then it is centered at the visible area.

When scrolling down from top, the control can suddenly disappear

I played a lot with the control, and the issue I see is that when you scroll quickly but for a short distance from the top-most position, the refresh control disappears and it looks like a blink. iOS 6 refresh control doesn't behave like that. Instead, from what I can see, if you drag from the top-most position, if always updates. But only if you accelerate from the middle of the list, then it hides the control. Hope you understand what I'm talking about. :)

Refresh

Hi There

Implemented as easy as you said.

So it looks like it is refreshing - but the TableView does not refresh.

I have the iPhone doing a JSON pull from a SQL Database.

Any ideas ?

Iain

TUIRefreshControl in TwUI

Hi, I've written a TUIRefreshControl based on this control for TwUI, and although you don't require crediting, I'd like for you to be very cool with it. Just a heads up. I plan to rework the code to be non-infringing on your code, but I can't deny that ODRefreshControl was the starting point.

UITableView gets stuck with a quick fling gesture.

Hey. This pull-to-refresh class works fine in my app except for one situation. Whenever I make a quick downward "fling" gesture on the tableview, the refreshing code is called but the tableView gets stuck at a position and my app stops showing EXC_BAD_ACCESS. Is this a problem everyone has been facing?

Note: This doesn't happen no matter how far I try to pull the table with a DRAG gesture. This only happens with a FLING.

Any help is appreciated. Thanks. :)

Spinner disappear when pull down too fast.

Sometimes if you pull down too fast (especially along the left side) the spinner does not show up and there are just empty rows displayed until the data populates again. You should be able to see this behavior when testing on the iPad.

Calling beginRefreshing

I am trying to invoke beginRefreshing, but I've noticed some strange behavior. Perhaps there is some guidance you can offer:

I would like to notify the user that data is being refreshed in the UITableView, but I do not want to block the user from the existing data. It looks like (intentionally) calling beginRefreshing does not animate the control down to indicate a refresh. I would like for that behavior to be present in the control or perhaps some guidance as to how to get that to work. For instance, if I animate it myself, I do not want to the user to be able to pull down to refresh. Do you have any examples of doing that?

Crash on self.scrollView removeObserver

My Application crash on dealloc

- (void)dealloc
{
    [self.scrollView removeObserver:self forKeyPath:@"contentOffset" context:nil]; // Crash here
    self.scrollView = nil;
}

Activity View doesn't appear in UITableView when it has a tableHeaderView

Hello,

The UIActivityView doesn't appear after calling "beginRefreshing". That is only happening when a UITableView has a tableHeaderView set up, like this code:

ODRefreshControl *refreshControl = [[ODRefreshControl alloc] initInScrollView:self.tableView];
[refreshControl addTarget:self action:@selector(dropViewDidBeginRefreshing:) forControlEvents:UIControlEventValueChanged];
self.tableView.tableHeaderView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 10)];
[refreshControl beginRefreshing];

Thank you for this Refresh Control guys!

Edit

I fixed with this code:

   [refreshControl beginRefreshing];
    //Hack to fix the Bug in the ODRefreshControl when UITableView has a header
    [tableView setContentOffset:CGPointMake(0.0f, -44.0f) animated:YES];

ActivityIndicator Hides

Hello ,
I am facing a issue that is if you scroll the page fast the activityIndicator hides, some times you need to scroll to see it and sometimes it does not show at all.It's happening on iPhone 3GS (iOS sdk 5.1 ) and iPod 5th Gen (iOS sdk 6.0) .I have not tested on other device.Please look in to it.

referencing activityIndicatorViewStyle throws runtime exception

ODRefreshControl *odrc = [ODRefreshControl setupRefreshForTableViewController:self withRefreshTarget:self action:@selector(dropViewDidBeginRefreshing:)]; 

odrc.activityIndicatorViewStyle = UIActivityIndicatorViewStyleWhiteLarge;

Running Xcode 5, iOS 6.0 in the sim:
results in a runtime exception:
2014-03-07 13:42:23.455 ODRefreshControlDemo[30924:c07] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UIRefreshControl setActivityIndicatorViewStyle:]: unrecognized selector sent to instance 0x8145680'

Quick tip: Show UIActivityIndicator above searchBar...

When using ODRefreshControl, I noticed that if a table view has a search bar, the UIActivityIndicator is hidden. Simply add this to your viewDidLoad:

self.tableView.contentOffset = CGPointMake(0, -44);

This will initiate the view -44 above the tableview/searchbar, showing the activity indicator.

Not enough room for landscape refresh

There is not enough room on the screen to pull down the refresh knob all the way down when on landscape orientation.

All i have is one navigation bar and one tab bar.

Can you make it so that it only requires a little bit of pull in landscape orientation so the user can pull the refresh knob down all the way?

Weird unrecognized selector issue

I'm probably doing something wrong but I can't seem to figure out what. I'm getting an unrecognized selector issue error on iOS 5 (works on iOS 6). I try putting in a log right before it happens and the class seems to be correct so I really don't understand it.

Code:

NSLog(@"Scrollview: %@", [self.scrollView class]);

[self.scrollView setContentInset:UIEdgeInsetsMake(kOpenedViewHeight + self.originalContentInset.top, self.originalContentInset.left, self.originalContentInset.bottom, self.originalContentInset.right)];

Result:

2013-01-04 21:16:33.857 xxx[63650:c07] Scrollview: UIScrollView
2013-01-04 21:16:33.857 xxx[63650:c07] -[UIAccessibilityBundle setContentInset:]: unrecognized selector sent to instance 0xe61d510

The problem is caused when I call beginRefreshing and when it executes, the debugger stops on the setContentInset line. I'm not sure why it thinks its a UIAccessibilityBundle

Quick scroll UIWebView the web view falls down

Scroll UIWebView down to refresh, before loading finish, scroll down again (actually my action is do the scroll down one by one without waiting) the WebView falls down, means top of web view falls down every time I scroll down and never scroll up back to original place.

Custom activity view is garbled when portrait/landscape mode gets changed

A strang behaviour occurs using custom activities.

I set a custom activity view (UIProgressView). Using the demo App, I wrapped the ViewController of the demo code in a UINavigationController

    UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:self.viewController];
    self.window.rootViewController = navigationController;

and modified the ViewController as follows.

- (void)viewDidLoad
{
    [super viewDidLoad];

    UIProgressView *progressView = [[UIProgressView alloc] initWithFrame:CGRectMake(0, 0, 200, 20)];
    progressView.progress = 0.5;

    refreshControl = [[ODRefreshControl alloc] initInScrollView:self.tableView activityIndicatorView:progressView];
    [refreshControl addTarget:self action:@selector(dropViewDidBeginRefreshing:) forControlEvents:UIControlEventValueChanged];

    self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemRefresh target:self action:@selector(doRefresh)];
}

- (void)doRefresh {
    [refreshControl beginRefreshing];
    [self.tableView setContentOffset:CGPointMake(0, -44) animated:YES];
    [self dropViewDidBeginRefreshing:refreshControl];
}

I perform one refresh in portrait, rotate to landscape and perform a second refresh. I get several copies of the UIProgressView drawn. The same happens if I start on landscape and then turn to portrait.

Add activity view style choice

I absolutely love this control, it works perfectly and does what it says. My only niggle with it is the inability to change the colour of the activity spinner. On some of my views, the background is dark so I need it to be white, but in others the background is white so I need it to be dark.

Could you add in a quick fix for this? I've altered my local copy by adding the new init method

- (id)initInScrollView:(UIScrollView *)scrollView withActivityStyle:(UIActivityIndicatorViewStyle)style;

The original init method now simply contains

return [self initInScrollView:scrollView withActivityStyle:UIActivityIndicatorViewStyleWhite];

And in the now main init method, change the _activity initialisation to

_activity = [self setupActivityIndicatorWithStyle:style center:CGPointMake(floor(self.frame.size.width / 2), floor(self.frame.size.height / 2))];

Obviously this is a bit different, as I've moved the activity view init code into the following private method

- (UIActivityIndicatorView *) setupActivityIndicatorWithStyle:(UIActivityIndicatorViewStyle)style center:(CGPoint)center
{
    UIActivityIndicatorView *activity = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:style];
    activity.center = center;
    activity.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
    activity.alpha = 0;

    return activity;
}

Obviously if you do want to integrate this feature you can implement however you like, but this is what I've done locally. I just feel it would be a useful addition to this control

New title or attributedTitle property

It would be nice to be able to set a title, or even better, an attributed title as part of ODRefreshControl. It would be useful for developers who want to implement Loading… and Last Updated: 2 minutes ago kind of messages.

Leaking 48 Bytes after a refresh.

While debugging my app and looking for leaks, I discovered that 48 Bytes of data are leaked every time the control refreshes. I have confirmed that I am not the cause by running your demo project and scanning it.

How can i have a label to the bottom the the Refresher?

I would like to have something like this [
UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];
[refreshControl addTarget:self action:@selector(addReceipt:)
forControlEvents:UIControlEventValueChanged];
self.refreshControl = refreshControl;
NSString *s = @"Swipe Down to Add Receipt";
NSMutableAttributedString *a = [[NSMutableAttributedString alloc] initWithString:s];
[a addAttribute:NSForegroundColorAttributeName value:[UIColor darkGrayColor] range:NSRangeFromString(s)];
refreshControl.attributedTitle = a;]

for this Control

referencing activityIndicatorViewStyle throws runtime exception

ODRefreshControl *odrc = [ODRefreshControl setupRefreshForTableViewController:self withRefreshTarget:self action:@selector(dropViewDidBeginRefreshing:)]; 

odrc.activityIndicatorViewStyle = UIActivityIndicatorViewStyleWhiteLarge;

Running Xcode 5, iOS 6.0 in the sim:
results in a runtime exception:
2014-03-07 13:42:23.455 ODRefreshControlDemo[30924:c07] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UIRefreshControl setActivityIndicatorViewStyle:]: unrecognized selector sent to instance 0x8145680'

ODRefreshControl does not work when tableView is not used ?

I would like to use this control without a tableview but with a classical "View".
I have added my view in a scrollView and I have initialized the ODRefreshControl with this scrollView.

It does not work.

How to make it work with a view / scrollView ?

Tx

A quick scroll will lead to refresh unpurposely

In iOS 6 mail, only when your finger keep staying on screen to pull will trigger the refresh, which is the correct behavior.

This control is great, but my users complain very often they just scroll from bottom to top with a high acceleration, the refresh will also be trigger. Can fix this? Cos this also add more burden to server actually. Thanks.

2.0 - UITableView causes crash when refresh begins

When pulling down a table view to refresh, I crash in tableView:cellForRowAtIndexPath when I access my datasource.

As a workaround, I added a try catch block around where I use [indexPath row] to access my datasource.

In this specific crash, I have 2 sections and 2 datasources. The crash happens when indexPath has a section of 1 (2nd section). When inspecting indexPath in the debugger, it shows that [indexPath row] is <nil>. This is when the control is stretched far enough to begin refreshing, but crashes before it does

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.