iOS - Delayed "Touch Down" Event for Uibutton in Uitableviewcell

iOS - Delayed Touch Down event for UIButton in UITableViewCell

This is caused by the UIScrollView property delaysContentTouches.

It used to be sufficient to just set that property to NO for the UITableView itself, but that will only work for subviews of the table that are not encased in another UIScrollView.

UITableViewCells contain an internal scroll view in iOS 7 so you will need to change the value of this property on the cell level for all cells with buttons in them.

Here is what you need to do:

1.in viewDidLoad or somewhere similar once your UITableView has been initialized, put this in:

self.tableView.delaysContentTouches = NO;

2.for iOS 7 support, in the initialization method for your UITableViewCell (initWithStyle:reuseIdentifier: or initWithCoder: for NIBs), put this in at the end:

for (UIView *currentView in self.subviews)
{
if([currentView isKindOfClass:[UIScrollView class]])
{
((UIScrollView *)currentView).delaysContentTouches = NO;
break;
}
}

This is unfortunately not a 100% permanent solution as Apple can change the view hierarchy inside cells again in the future (perhaps moving the scroll view another layer down or something which would require you to nest another loop in there), but until they surface the class or at least the property to developers somehow, this is the best we've got.

TouchDown delayed for UIButton at the bottom of the screen

Turns out, hinted by https://stackoverflow.com/a/47255802/581164, the lag is caused by iOS waiting if the user is actually performing a system gesture (like swipe from the bottom of the screen) instead of tapping the button.

If I override var preferredScreenEdgesDeferringSystemGestures: UIRectEdge on the root view controller and set it to [.bottom, .right] there is no lag. I do not know why [.bottom] is not enough, I guess there is some other iOS gesture for swiping from the right edge of the screen and the button is located in the bottom right corner.

Always just setting [.bottom, .right] has some negative effects, the user has to swipe 2x to perform the iOS swipe from bottom gesture.

The key seems to be to set it only when the user is going to press the recording button, like in func point(inside point: CGPoint, with event: UIEvent?) -> Bool and then set it back when the user releases the button.

UIButton touch is delayed when in UIScrollView

Ok I've solved this by subclassing UIScrollView and overriding touchesShouldCancelInContentView

Now my UIButton that was tagged as 99 highlights properly and my scrollview is scrolling!

myCustomScrollView.h:

@interface myCustomScrollView : UIScrollView  {

}

@end

and myCustomScrollView.m:

@implementation myCustomScrollView

- (BOOL)touchesShouldCancelInContentView:(UIView *)view
{
NSLog(@"touchesShouldCancelInContentView");

if (view.tag == 99)
return NO;
else
return YES;
}

UIButton inside UITableViewCell steals touch from UITableView

This is the standard behaviour of UIScrollView which tableviews use. The system doesn't know that you want to scroll until you move your finger, but by that time you have already "pressed" on the button and so it assumes that's what you want to do.

You can play with a couple of properties on your tableview's scrollview to change the behaviour, but you may find they negatively impact the feel of your cells and buttons because of added delays.

self.tableView.delaysContentTouches = YES;

delaysContentTouches
If the value of this property is YES, the scroll view delays handling the touch-down gesture until it can determine if scrolling is the intent...

and

self.tableView.canCancelContentTouches = YES

canCancelContentTouches
If the value of this property is YES and a view in the content has begun tracking a finger touching it, and if the user drags the finger enough to initiate a scroll, the view receives a touchesCancelled:withEvent: message and the scroll view handles the touch as a scroll.

UIButton (inside UIView) in UITableViewCell click event not working

your View height is 0 that's why you not able to tap it

to test it set clips to bound value to yes

and also you need to set height for your view to solve that issue

UiTextField's Touch Down Event on uitableviewcell doesn't work always

Along with EditingDidBegin do call resignFirstResponder on your textfield when you are done.
Now next time you tap the textfield it should work as expected.

Will handling UIButton touch event inside a UITableViewCell subclass violate MVC?

The second option will certainly violate MVC pattern. ViewController works like a glue between your models, views and contains all the business logic.
ViewController should receive action then make your api call and put formatted data to your views.

Usually in my project I always try to move networking code into separated set of classes which can handle fetching data from API, transforming from JSON/XML to model objects and formatting them (string date object to NSDate object etc.). Then I can call simple looking method in my ViewController and populate views/tableview cells.

On the other hand,

If you have some time you can look at MVVM which is getting more popular.
There are some links (start with sprynthesis which is AWESOME):

  1. www.sprynthesis.com
  2. objc.io
  3. cocoasamurai
  4. raywenderlich

And some sample apps:

  1. C-41
  2. vinylogue
  3. GroceryList

That helped me to understand MVC more deeply thanks to comparision to MVVM.

Don't be scared with usage of ReactiveCocoa, you can always adopt MVVM without it but it's worth to look at. (It has really steep learning curve and I still feel like an idiot)

Also there is a great article about design patterns with iOS implementation:

raywenderlich design patterns



Related Topics



Leave a reply



Submit