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):
- www.sprynthesis.com
- objc.io
- cocoasamurai
- raywenderlich
And some sample apps:
- C-41
- vinylogue
- 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
What's the Equivalent of the Uisplitviewcontroller in Swiftui
Could Not Find an Overload for "Init" That Accepts the Supplied Arguments in Swift
Swift - Image Data from Ciimage Qr Code/How to Render Cifilter Output
How to Pass Data from One Container to Another, Both Embedded in the Same Uiviewcontroller in Swift
Auto Adjust Custom Uitableviewcell and Label in It to the Text
Set a Maximum Number of Children in Firebase
iOS 9 Orientation Auto-Rotation Animation Not Working, But Always on Main Thread
Reverse an Audio File Swift/Objective-C
How to Consecutively Present Two Alert Views Using Swiftui
How to Create Otp Verification Screen and Detect Delete Backward on Multiple Uitextfield Is Swift
Getter VS Computed Property. What Would Warrant Using One of These Approaches Over the Other
How to Make the View Update Instant in Swiftui
Dateformatter Returns Unexpected Date for Timezone
Upload Files to Dropbox from iOS App with Swift