可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I'm running into a small issue in my app.
I essentially have a series of UIButtons
added as subviews in a UIScrollView
which is part of a nib. Every time I tap on a button there is a noticeable delay before the button is highlighted. I essentially have to hold it for about half a second before the button dims and appears selected.
I'm assuming this is because the UIScrollView
needs to determine if the touch is a scroll or if it's a touch that is meant for a subview.
Anyways, I'm a little unsure on how to proceed. I simply want the button to appear selected as soon as I tap it.
Any help is appreciated!
Edit:
I've tried setting delaysContentTouches
to NO but scrolling becomes almost impossible since a majority of my scrollView is filled with UIButtons
.
回答1:
Jeff's solution wasn't quite working for me, but this similar one does: http://charlesharley.com/2013/programming/uibutton-in-uitableviewcell-has-no-highlight-state
In addition to overriding touchesShouldCancelInContentView
in your scroll view subclass, you still need to set delaysContentTouches
to false
. Lastly, you need to return true
rather than false
for your buttons. Here's a modified example from the above link. As commenters suggested, it checks for any subclass of UIControl
rather than UIButton
specifically so that this behavior applies to any type of control.
Objective-C:
- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
self.delaysContentTouches = false;
}
return self;
}
- (BOOL)touchesShouldCancelInContentView:(UIView *)view {
if ([view isKindOfClass:UIControl.class]) {
return true;
}
return [super touchesShouldCancelInContentView:view];
}
Swift 4:
override func touchesShouldCancel(in view: UIView) -> Bool {
if view is UIControl {
return true
}
return super.touchesShouldCancel(in: view)
}
回答2:
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;
}
回答3:
Try to set UIScrollView delaysContentTouches
property to NO.
回答4:
Storyboard solution: Select the scroll view, open the "Attributes Inspector" and uncheck "Delays Content Touches"
回答5:
In Swift 3:
import UIKit
class ScrollViewWithButtons: UIScrollView {
override init(frame: CGRect) {
super.init(frame: frame)
myInit()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
myInit()
}
private func myInit() {
self.delaysContentTouches = false
}
override func touchesShouldCancel(in view: UIView) -> Bool {
if view is UIButton {
return true
}
return super.touchesShouldCancel(in: view)
}
}
You can then use this ScrollViewWithButtons
in IB or in code.
回答6:
None of the existing solutions worked for me. Maybe my situation is more unique.
I have many UIButtons
within a UIScrollView
. When a UIButton
is pressed a new UIViewController
is presented to the user. If a button is pressed and held long enough, the button will show its depressed state. My client was complaining that if you tap too quickly, no depressed state is shown.
My solution:
Inside the UIButtons
' tap method, where I load the new UIViewController
and present it on screen, I use
[self performSelector:@selector(loadNextScreenWithOptions:)
withObject:options
afterDelay:0.]
This schedules the loading of the next UIViewController
on the next event loop. Allowing time for the UIButton
to redraw. The UIButton
now shows its depressed state before loading the next UIViewController
.
回答7:
Swift 3 :
scrollView.delaysContentTouches = false