Pull To Refresh Jump in iOS - ios

When I slowly pull down to refresh, I see the UIActivityIndicator circle slowly get more complete before it starts the refresh. Just before the circle is complete and the refresh actually triggers, the content jumps/jerks down and then the circle starts spinning. I only notice this when I pull down slowly.
I'm using the pull to refresh inside a scroll view called mainSV
self.refresh = [[UIRefreshControl alloc] init];
[self.refresh addTarget:self action:#selector(handleRefresh) forControlEvents:UIControlEventValueChanged];
[self.mainSV addSubview:self.refresh];
Why does this jump/jerk happen?

It's probably a bug in iOS. Your setup is correct, and I see the same thing in my app.

I suspect the jump/jerk is due to a "double" action.
There was a change to refresh implementation following the release of Xcode 5.
As such, the requirement to set a target action as described in the Apple Documentation is no longer necessary.
As you are using a Storyboard, in your Interface Builder / Storyboard file, select your storyboard scene (table view controller).
In the attributes inspector, under the subheading Table View Controller, select the item "Refreshing" and change the setting from "Disabled" to "Enabled".
Delete or comment out the three lines of code you have included in your question. (When it was required, i.e. prior to Xcode 5, I placed this code in my viewDidLoad TVC lifecycle method.)
If not automatically inserted into your code, then add this as either a public or private IBAction...
- (IBAction)refresh:(UIRefreshControl *)sender;
and wire to your scene / table view controller to the Sent Event "Value Changed".
Ensure your refresh action is properly configured...
- (IBAction)refresh:(UIRefreshControl *)sender {
[self.refreshControl beginRefreshing];
// Refresh code for your TVC
[self.refreshControl endRefreshing];
}
Note that no property is required to be set for refreshControl - I suspect there is a trigger to automatically synthesise this when you choose the setting Refreshing [Enabled] in your TVC attributes in the storyboard.
If you need to call the refresh from in your code, use this line...
[self refresh:self.refreshControl];

I would need to see the rest of your code (or at least the scrolling + refreshing methods) to diagnose the problem.
Here's our tutorial for implementing custom pull to refresh controls in objective-c and swift. If you follow this tutorial you shouldn't see any jumping or jerking.
http://www.jackrabbitmobile.com/design/ios-custom-pull-to-refresh-control/
Hope it helps!

Old questions but if someone still has this issue and you are using NavigationController just make your NavigationBar "Translucent".
Using non translucent NavigationBar causes the tableview to jump slightly when UIControlEventValueChanged is fired for some reason.
XCode 10.1

Related

TableView didSelectRowAtIndexPath not called

So I have added a UIUITableView to a UIViewController. I can't use a UITableViewController for reasons I don't need to explain since it will be unnecessary information. Anyway, I have set the delegate, and the data source to this viewController. I've added the delegate and datasource protocols as well. The cells are populated correctly, so the datasource is working fine. I can also scroll so it all works fine.
However, I can't get the didSelectRowAtIndexPath to trigger. It SHOULD trigger, but doesn't. I've read and a lot of issues with this can be correlated to a UIGestureRecognizer, but I haven't implemented one. I also use the standard UITableView, so not a custom made one.
If I long press the cells (3-4 sec) then it gets triggered as it's supposed to. This suggests that there is some issue with another view or something absorbing the tap gesture, which I have no control over. How would I solve this?
No, it's not didDeselectRowAtIndexPath.
Yes all delegates and datasources are correct, since I can get the delegates/sources to trigger.
Yes, Single Selection is set on the TableView in the inspector.
Yes, everything has user interaction enabled.
If I just copy the code over to a UITableViewController it will work just fine, but right now that is not an option, I'm afraid. Anyone got any ideas on how to solve this? Most people who've had this issue has either had the issues in the list above, or added a UIGesture on top of the UITableView - I haven't.
I want to start by saying that I appreciate all the answers here provided, it gave me a lot of things to try out so I learned a lot - thanks! None of your suggestions worked, but simply because I'm a complete idiot. I said in the post that I did NOT implement a UIGestureRecognizerwhich I didn't...in that class, but in its super class. So I DID in fact implement it, but in a class that this ViewController was a subclass off. The only reason I didn't remember it was because I haven't looked at that super class for weeks.
Someone did suggest it in the comments that I should check for it, and I did and I was already certain I didn't implement one, so I quickly dismissed it. But now, after about 4 hours of debugging and recreating the project, adding things one by one, I eventually realized that the only thing that differed at this point was the Super Class, and the first piece of code I see when I open the file up was a GestureRecognizer...
So keep this in mind in the future everyone - I know I will. Thanks again for the help!
Sincerely,
The complete idiot.
Make sure you don't add any controller in that cell, which covers the entire cell and also the user interaction of that controller is enabled.
Due to that controller's user interaction enabled the tap action is taken by that controller and when you long press that cell, that cell will receive your tap.
Example :
UIView *_view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, _cellWidth, _cellHeight)];
[_view setUserInteractionEnabled:YES];
[cell.contentView addSubview:_view];
In the above case that view got your tap instated of the cell.

SVPullToRefresh - Refresh view does not show

Sorry if my question seems stupid but I've been trying everything to get it to work for several days now and nothing comes to my mind anymore.
I'm trying to use SVPullToRefresh on a UIScrollView which is, in my storyboard, fixed to the main view of my View Controller (space constraints to superview 0,0,0,0).
Code is pretty straightforward :
__weak ALExploreViewController *weakSelf = self;
[self.globalScrollView addPullToRefreshWithActionHandler:^{
[weakSelf refreshData];
}];
[self.globalScrollView triggerPullToRefresh];
The thing is, when I launch the app, the pull to refresh appears as I triggered it in code. Then I make it disappear when my data are updated (self.globalScrollView.showsPullToRefresh = NO;). And then when I scroll up to refresh, the "pull to refresh" view won't show. If I deactivate bouncing, the view won't event scroll upper than y=0, and if I activate it, it bounces but no sign of the P2R view.
Any ideas ? Please ?
You should not use self.globalScrollView.showsPullToRefresh = NO;, this is used to disable the refreshView.
When your data is updated, you can call
- (void)stopAnimating;
Try it!

Adding and Removing UIView From Springboard

I am developing a little MS tweak that adds a view on the Springboard. I want it to be constantly updated so I called it into the
- (void)showSpringBoardStatusBar
Then I create and add the view using this:
[[UIApplication sharedApplication].keyWindow addSubview:view1];
Is this the right way?
But the problem is this view uses a low alpha level to be transparent and every time the view is updated by the showSpringBoardstatus bar another UIView is added onto of it eventually just making the view solid. This also is uneconomical in terms of memory. so then I went back an added what I thought would remove the code:
view1 = nil;
[view1 removeFromSuperview];
But it seems like this doesn't make a difference as it is still there and nothing changes.
I have been searching for the last few days for anything to help me with this but got nothing out of it. All I can think of is that I can't remove an added subview from a key window like I would from a normal view or I just don't how to do it correctly.
Any help would be appreciated. Thank you.
Setting view1 to nil and than calling "removeFromSuperView" might be a bad idea. How about adding the view only once, keeping a reference and updating this reference constantly without adding it to keyWindow again?

iOS: Tapping on UITableView does not call didSelectRowAtIndexPath

My app uses a UITableView with a UINavigationController to show a more detailed view when a row of the table is tapped - the basic drill-down routine.
When I tap on a row, it is highlighted, but the delegate methods tableView:willSelectRowAtIndexPath: or tableView:didSelectRowAtIndexPath: are not called (verified using debugger).
Now here's the weird part:
There are some other table views in the app (they don't drill down) and none of them exhibit the issue.
If I tap the row rapidly and repeatedly, after many tries (10 - 20 is normal), tableView:willSelectRowAtIndexPath: and tableView:didSelectRowAtIndexPath: are called and processing continues normally.
The problem occurs only on an (any, actually) iPad running iOS 6. It works fine with iPads running iOS 5, or with any iPhone running any iOS version, 6. It also works with the iPad simulator using iOS 5 or 6.
So it seems that something is receiving the tap before the delegate methods are called. But what?
I not using any UITapGestureRecognizer, so that is not the issue.
I am not using multiple UITableViewControllers for the table, so this is also not the issue.
I was having this issue with an app when running in iOS6. The tableView:didSelectRowAtIndexPath: method was never being triggered, even though it was working before updating to iOS6.
I finally figured it out by looking at the xib and the attribute inspector for the table. In the Table View section I had the Selection option set to No Selection and Show Selection on Touch was not selected.
Changing the Selection option to Single Selection actually got this working for me again and leaving the Show Selection on Touch unselected means that I don't see any flash or change of colour when the row is selected.
I encountered a similar issue. iOS 6 appears to be much more sensitive to the slightest upward movement on a tap on a table view cell. It appears it is registering the slightest movement as a scroll request rather than a cell selection. My table view was set to scrollEnabled = NO because it is a table view with static selection values. The table view appears within a small area of a larger iPad view. If I carefully tap a cell and lift directly up, the cell is selected.
To resolve it, I changed scrollEnabled to YES and made sure the area dedicated to my tableView was larger than the actual area needed to show the table view, thus preventing it from scrolling. Not sure if this is is the cause of the issue you are experiencing, but hope it helps.
I had the same problem. The UITableView was not triggering the didSelectRowAtIndexPath method when running in iOS6, but it was working fine in iOS5.1.
I had also implemented the
- (BOOL)tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath{
return NO;
}
and returned NO. In iOS5 it was all working fine, but the minute I switched to iOS6 it would cease to trigger the didSelectRowAtIndexPath. Once I removed that shouldHighlightRow method, everything worked in iOS6 again. Cheers!
The usual reason that didSeletRowAtIndexPath() doesn't get called is having a UITapGestureRecognizer on your viewcontroller with Cancels touches in view set to YES.
The correct and only sensible fix is to set Cancels touches in view to NO. Then your table row selection should work nicely.
Obviously this has some implications in your gesture handlers - you may need to add some code to your gesture handler to stop some touches going on to your views i.e.
- (IBAction)onTapGesture:(UITapGestureRecognizer *)sender {
if (sender.view == someOldViewThatINeedToDealWith) {
sender.cancelsTouchesInView = true;
}
}
I tried all the other answers posted, and although they seemed promising, they didn't solve the problem.
I've since discovered the cause of problem in my case: I was calling [self.tableView reloadData] on a different thread (due to handling an NSNotification event posted from a background worker thread).
I fixed the problem by changing [self.tableView reloadData] to
[self.tableView performSelectorOnMainThread:#selector(reloadData) withObject:nil waitUntilDone:NO];
Hope this helps.
The other suspect could be a Tap Gesture Recognizer set to the view controller's view swallowing all taps like a blackhole. Remove the gesture recognizer will enable did select. I just had the same issue and the tap gesture was the cause.
The resolution is really weird: the UITableViewController registered for all notifications. In the handler for the notifications, the table view data was being reloaded using
[self.tableView reloadData]
According to Apple DTS, when the table reloads data, this causes a notification to be sent to the observer, causing a race condition ...
No explanation for why it would work sometimes or why it would always work on an iPhone. But registering only for a small subset of notifications (i.e. the ones I was really interested in) fixed the problem!
Setting
recognizer.cancelsTouchesInView = NO;
takes care of it if your use case allows simultaneous handling
of touches by [tap] gesture recognizer (kdb dismiss for example)
and the view the recognizer is attached to.
in my case I hade button which received all touch events before tableviewcell

Adding a custom UIButton and action to a view in window app delegate (ios)

I am working on a tab bar application which needs a global title bar with a setttings button attached. I have achieved adding an imageview to the main window, then a label, another image, and finally a button. However, I cannot get this button to fire an action. it is set up like this:
[settingsButton addTarget:self action:#selector(settings) forControlEvents:UIControlEventTouchupInside];
Then the action defined like:
-(void)settings{
NSLog(#"please do something");
}
However nothing happens, the image doesn't even change like it is being pressed. Can i not define buttons in the app delegate this way? is it because the target is not something that is control based? i tried different targets but i must not fully understand what setting a target is. thanks for any help.
P.S.- i tried setting up the method like so as well:
-(void) settings:(id)sender{
}
and calling it by replacing the action with #selector(settings:) to no avail. Thank you.
I solved it. I forgot I changed the view behind the button to a UIImageView. I can't believe I didn't think of this before since this same issue cost me 2 hours the other day. When you have an imageView always remember to set this flag if you want stuff on it:
(someImageView).userInteractionEnabled = YES;
Hopefully I save someone an hour or two of needless headaches.
P.S. Thanks for the speedy comment !

Resources