The first trigger goes ok, but after that, if I try to pull it down, it always shows its still loading.
here is my simple code example on my UITableViewController:
- (void)viewDidLoad
{
[super viewDidLoad];
__weak StoresViewController * bSelf = self;
[self.tableView addPullToRefreshWithActionHandler:^{
[bSelf callStoresService];
}];
[self.tableView triggerPullToRefresh];
}
- (void)callStoresService {
[self.tableView.pullToRefreshView stopAnimating];
}
Adding a breakpoint to [self.tableView.pullToRefreshView stopAnimating]; I can see it never gets called again...
I have an old project with almost the same code and its working... anything I am missing here?
Since I am only developing for iOS 6, I decided to use the native refresh:
on my viewDidLoad:
// managing pullToRefresh
UIRefreshControl *refresh = [[UIRefreshControl alloc] init];
refresh.attributedTitle = [[NSAttributedString alloc] initWithString:#"Pull down to refresh"];
[refresh addTarget:self action:#selector(refreshView:) forControlEvents:UIControlEventValueChanged];
self.refreshControl = refresh;
[self refreshView:refresh];
[self.refreshControl beginRefreshing];
Then create a refreshView method:
-(void)refreshView:(UIRefreshControl *)refresh {
refresh.attributedTitle = [[NSAttributedString alloc] initWithString:#"Refreshing..."];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"dd/MM HH:mm:ss"];
// do what you need
NSString *lastUpdated = [NSString stringWithFormat:#"Last update: %#", [formatter stringFromDate:[NSDate date]]];
refresh.attributedTitle = [[NSAttributedString alloc] initWithString:lastUpdated];
}
dont forget to call [refresh endRefreshing]; when your are done
Related
I have implemented Pull to Refresh on my app but it crashes when I try to scroll while it is still refreshing. here is the code I'm using:
FYI, I'm calling webServices while refreshing.
In ViewDidLoad:
UIRefreshControl *refresh = [[UIRefreshControl alloc] init];
refresh.attributedTitle = [[NSAttributedString alloc] initWithString:#"Pull to Refresh"];
[refresh addTarget:self action:#selector(callWebService:) forControlEvents:UIControlEventValueChanged];
self.refreshControl = refresh;
[self callWebService:refresh];
Method for refresh:
-(void)callWebService:(UIRefreshControl *)refresh
{
static BOOL refreshInProgress = NO;
MessageWebServices *messageWebService = [[MessageWebServices alloc]init];
MessageBO *tempBO = [[MessageBO alloc]init];
if(self.flag)
{
self.navigationItem.title = #"My Posts";
tempBO.projectId = [AppConstants getProjectId];
tempBO.customerId =[AppConstants getCustomerId];
}
else
{
tempBO.projectId = [AppConstants getProjectId];
}
self.messageStore = [[NSMutableArray alloc] init];
if (!refreshInProgress)
{
refreshInProgress = YES;
refresh.attributedTitle = [[NSAttributedString alloc] initWithString:#"Refreshing"];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
self.messageStore = [messageWebService getMessageList:tempBO];
dispatch_async(dispatch_get_main_queue(), ^{
[refresh beginRefreshing];
[self.tableView reloadData];
[refresh endRefreshing];
refreshInProgress = NO;
});
});
}
}
Please Help!
I have never used beginRefreshing method. You can easily add refresh control to your tableView.
#pragma mark Refresh Method
-(void)startRefreshing {
if (!self.refreshControl) {
// Initialize the refresh control.
self.refreshControl = [[UIRefreshControl alloc] init];
self.refreshControl.backgroundColor = CRREFRESHBGCOLOR;
self.refreshControl.tintColor = [UIColor whiteColor];
[self.refreshControl addTarget:self action:#selector(callWebservice) forControlEvents:UIControlEventValueChanged];
[yourTable addSubview:self.refreshControl];//add refresh control to your table
}
}
-(void)endRefreshing {
if (self.refreshControl) {
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"MMM d, h:mm a"];
NSString *title = [NSString stringWithFormat:#"Last update: %#", [formatter stringFromDate:[NSDate date]]];
NSDictionary *attrsDictionary = [NSDictionary dictionaryWithObject:[UIColor whiteColor]
forKey:NSForegroundColorAttributeName];
NSAttributedString *attributedTitle = [[NSAttributedString alloc] initWithString:title attributes:attrsDictionary];
self.refreshControl.attributedTitle = attributedTitle;
[self.refreshControl endRefreshing];
}
}
After calling/finishing web-service method call [self endRefreshing]; method and reload your table [yourTable reloadData].
Is there a way to apply a refresh control to a UITableView which is set in a UIViewController?
The solution I found requires subclassing of UITableViewController, which is troublesome for me because I need to subclass a UIViewController not a UITableViewController, and I don't see any method under the documentation of UITableView that allows me to set a refresh control on it.
Any help would be very much appreciated!
use this UIRefreshControl control :
UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];
[refreshControl addTarget:self action:#selector(refresh1:) forControlEvents:UIControlEventValueChanged];
[Delivered_TBL addSubview:refreshControl];
- (void)refresh1:(UIRefreshControl *)refreshControl
{
[self Service_Call];
[refreshControl endRefreshing];
}
UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];
refreshControl.backgroundColor = [UIColor clearColor];
refreshControl.tintColor = [UIColor whiteColor];
[refreshControl addTarget:self
action:#selector(getLatestData)
forControlEvents:UIControlEventValueChanged];
[yourTableviewName addSubview:refreshControl];
-(void)getLatestData
{
// here add your reload method
[self XXXXX];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"MMM d, h:mm a"];
NSString *title = [NSString stringWithFormat:#"Last update: %#", [formatter stringFromDate:[NSDate date]]];
NSDictionary *attrsDictionary = [NSDictionary dictionaryWithObject:[UIColor whiteColor]
forKey:NSForegroundColorAttributeName];
NSAttributedString *attributedTitle = [[NSAttributedString alloc] initWithString:title attributes:attrsDictionary];
refreshControl.attributedTitle = attributedTitle;
[refreshControl endRefreshing];
}
I am pretty new to iOS programming and for a class project I was trying to implement "pull to refresh feature"
I tried from this link, and implemented same in my MoviesViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.moviesTableView.delegate = self;
self.moviesTableView.dataSource = self;
// pull to refresh
UIRefreshControl *refresh = [[UIRefreshControl alloc] init];
refresh.attributedTitle = [[NSAttributedString alloc] initWithString:#"Pull to Refresh"];
[refresh addTarget:self action:#selector(refreshView:) forControlEvents:UIControlEventValueChanged];
self.refreshControl = refresh;
// progress bar
MBProgressHUD *HUD = [self getLoadingController];
[HUD showWhileExecuting:#selector(generateMovies) onTarget:self withObject:nil animated:YES];
self.moviesTableView.rowHeight = 100;
[self.moviesTableView registerNib:[UINib nibWithNibName:#"MovieViewCell" bundle:nil] forCellReuseIdentifier:#"MovieViewCell"];
}
and
-(void)refreshView:(UIRefreshControl *)refresh {
refresh.attributedTitle = [[NSAttributedString alloc] initWithString:#"Refreshing data..."];
// custom logic: get data from server
NSLog(#"refreshing view");
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"MMM d, h:mm a"];
NSString *lastUpdated = [NSString stringWithFormat:#"Last updated on %#",[formatter stringFromDate:[NSDate date]]];
refresh.attributedTitle = [[NSAttributedString alloc] initWithString:lastUpdated];
[refresh endRefreshing];
}
But when I run this in simulator, I do not see it while pulling down the movies table.
What could be the issue here?
I think you're missing adding the HUD into the refresh control. Depending on your view structure, you'd need something like:
[self.refreshLoadingView addSubview:self.hud];
We'd need to see the rest of your code to debug the problem, but here's a tutorial I wrote explaining custom pull-to-refresh controls for iOS (including Swift): http://www.jackrabbitmobile.com/design/ios-custom-pull-to-refresh-control/
I am showing images in UIScrollView with UIImageView.I added UIGestureRecognizer to each ImageView and also I am setting tag property of Image View.I want tag of Image view on Tap on particular Image View.But I am only getting Tag of last ImageView.Pasting Code below.Your help will be appreciated.
UITapGestureRecognizer *tapRecognizer;
tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(imageViewDidTapped:)];
tapRecognizer.numberOfTapsRequired = 1;
tapRecognizer.delegate = self;
scrollView = [[UIScrollView alloc]initWithFrame:CGRectMake(5, 60, self.view.bounds.size.width-20, self.view.bounds.size.height-100)];
scrollView.delegate = self;
scrollView.pagingEnabled = YES;
scrollView.scrollEnabled = YES;
scrollView.indicatorStyle = UIScrollViewIndicatorStyleWhite;
[scrollView setCanCancelContentTouches:YES];
[scrollView setUserInteractionEnabled:YES];
float width;
for (NSDictionary *dict in object) {
UIImageView *backgroundImageView = [[UIImageView alloc]initWithFrame:CGRectMake(width, 0, self.view.bounds.size.width-20, self.view.bounds.size.height-40)];
NSDateFormatter *dateformatter = [[NSDateFormatter alloc]init];
[dateformatter setDateFormat:#"yyyy-MM-dd"];
[dateformatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
NSDate *date = [dateformatter dateFromString:[NSString stringWithFormat:#"%#",[dict objectForKey:#"id"]]];
NSTimeInterval timeStamp = [date timeIntervalSince1970];
backgroundImageView.tag = timeStamp;
[backgroundImageView setUserInteractionEnabled:YES];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:[dict objectForKey:#"coverImage"]]];
AFImageRequestOperation *operation = [AFImageRequestOperation imageRequestOperationWithRequest:request
imageProcessingBlock:nil
success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image){
backgroundImageView.image = image;
}
failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error) {
NSLog(#"Error %#",error);
}];
[operation start];
width = width + backgroundImageView.frame.size.width;
[backgroundImageView addGestureRecognizer:tapRecognizer];
[imageViewArray addObject:backgroundImageView];
[scrollView addSubview:backgroundImageView];
}
And added method for getting gesture event
- (void)imageViewDidTapped:(UIGestureRecognizer *)gesture{
UITapGestureRecognizer *tapGesture = (UITapGestureRecognizer *)gesture;
UIImageView *tappedImageView = (UIImageView *)[tapGesture view];
NSDateFormatter *dateformatter = [[NSDateFormatter alloc]init];
[dateformatter setDateFormat:#"yyyy-MM-dd"];
[dateformatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
NSLog(#"Issue Date :%#",[dateformatter stringFromDate:[NSDate dateWithTimeIntervalSince1970:tappedImageView.tag]]);
}
you have many imageView but only one UITapGestureRecognizer. you should add a gesture recognizer for each imageView.
Create UITapGestureRecognizer inside the for loop.
for (NSDictionary *dict in object) {
UITapGestureRecognizer *tapRecognizer;
tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(imageViewDidTapped:)];
tapRecognizer.numberOfTapsRequired = 1;
tapRecognizer.delegate = self;
// your code for image imageview
[imageview addGestureRecognizer:tapRecognizer];
}
I have a UIView subclass and it is connected with a xib. I am not creating views in layoutSubviews method and only in xib. Its confusing when to use self.ivar and _ivar. I tried to set the text for a textField which is a subview of my UIView subclass. Can anyone help me?? I tried to set or get the text to my textfield from my viewController. But I can't succeed. Here is a code.
Here it is my UIView custom class DateRangeView.m
#import "DateRangeView.h"
#implementation DateRangeView
#synthesize tfStartDate = _tfStartDate;
#synthesize tfEndDate = _tfEndDate;
#synthesize startDate = _startDate;
#synthesize endDate = _endDate;
#synthesize dateFormatter = _dateFormatter;
#synthesize datePicker = _datePicker;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"DateRangeView" owner:self options:nil];
[self addSubview:[topLevelObjects objectAtIndex:0]];
[self baseInit];
}
return self;
}
- (id)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
if (self) {
// Initialization code
[self baseInit];
}
return self;
}
- (void)baseInit {
NSDateFormatter *df = [[NSDateFormatter alloc]init];
[df setDateStyle:NSDateFormatterMediumStyle];
_dateFormatter = df;
_startDate = [NSDate date];
_endDate = [NSDate date];
}
- (void)awakeFromNib {
[super awakeFromNib];
_datePicker = [[UIDatePicker alloc]initWithFrame:CGRectMake(0, 200, 320, 216)];
[_datePicker setDatePickerMode:UIDatePickerModeDate];
[_datePicker setDate:[NSDate date]];
_tfStartDate.inputView = _datePicker;
_tfEndDate.inputView = _datePicker;
UIToolbar *keyboardToolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0,self.frame.size.width, 44)];
UIBarButtonItem *cancelBtn = [[UIBarButtonItem alloc] initWithTitle:#"Cancel" style:UIBarButtonItemStyleBordered target:self action:#selector(cancelButtonPressed:)];
UIBarButtonItem *flexibleSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(doneButtonPressed:)];
[keyboardToolbar setItems:[[NSArray alloc] initWithObjects:cancelBtn, flexibleSpace, doneButton, nil]];
[keyboardToolbar setTranslucent:YES];
[keyboardToolbar setTintColor:[UIColor blackColor]];
[_tfStartDate setInputAccessoryView:keyboardToolbar];
[_tfEndDate setInputAccessoryView:keyboardToolbar];
_tfStartDate.text = [_dateFormatter stringFromDate:_startDate];
_tfEndDate.text = [_dateFormatter stringFromDate:_endDate];
}
- (void)doneButtonPressed:(id)sender {
if ([_tfStartDate isFirstResponder]) {
self.startDate = _datePicker.date;
[_tfStartDate resignFirstResponder];
}else if ([_tfEndDate isFirstResponder]) {
self.endDate = _datePicker.date;
[_tfEndDate resignFirstResponder];
}
}
- (void)cancelButtonPressed:(id)sender {
[_tfStartDate resignFirstResponder];
[_tfEndDate resignFirstResponder];
}
- (void)setStartDate:(NSDate *)startDate {
_startDate = startDate;
_tfStartDate.text = [_dateFormatter stringFromDate:_startDate];
}
- (void)setEndDate:(NSDate *)endDate {
_endDate = endDate;
_tfEndDate.text = [_dateFormatter stringFromDate:_endDate];
}
Here is my code for adding view into viewcontroller and assigning text to textfield and tried to getting the text? But i am not successful in both setting and getting the text.
rangeView = [[DateRangeView alloc]initWithFrame:CGRectMake(0, 0, 320, 150)];
[self.view addSubview:rangeView];
rangeView.startDate = [NSDate date];
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *startDateComponents = [calendar components:NSDayCalendarUnit fromDate:[NSDate date]];
[startDateComponents setDay:5];
NSDate *beginDate = [calendar dateByAddingComponents:startDateComponents toDate:[NSDate date] options:0];
rangeView.endDate = beginDate;
NSLog(#"start %#", rangeView.tfStartDate.text);
NSLog(#"end %#", rangeView.tfEndDate.text);
Log shows null.. Any help would be appreciated. I have attached a whole code of my UIView only to understand what I am doing.
In your code, I cannot see the initialization for self.tfStartDate and self.tfEndDate.
So, there are 2 possibilities:
they are meant to be IBOutlets: then, check in your nib file that they are also connected to the relevant views;
they are not defined in your xib: in this case just initialize them in viewDidLoad.
As to the use of self.ivar vs. _ivar, the only difference is in the fact that the former will handle reference counting for you; with the latter, you have to do it yourself. So, in this case it is not relevant which one you are using. The issue lies with their initialization so that they reference your subviews correctly.