ios UIButton 在 iOS7 中点击时不显示高亮
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19256996/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
UIButton not showing highlight on tap in iOS7
提问by Eric
I've looked at a ton of posts on similar things, but none of them quite match or fix this issue. Since iOS 7, whenever I add a UIButton
to a UITableViewCell
or even to the footerview it works "fine", meaning it receives the target action, but it doesn't show the little highlight that normally happens as you tap a UIButton
. It makes the UI look funky not showing the button react to touch.
我查看了大量关于类似内容的帖子,但没有一个完全匹配或解决此问题。从 iOS 7 开始,每当我UIButton
向 aUITableViewCell
或什至页脚视图添加 a 时,它都会“正常”工作,这意味着它会接收目标操作,但它不会显示通常在您点击 a 时发生的小亮点UIButton
。它使 UI 看起来很时髦,不显示按钮对触摸的反应。
I'm pretty sure this counts as a bug in iOS7, but has anyone found a solution or could help me find one :)
我很确定这算作 iOS7 中的一个错误,但有没有人找到解决方案或可以帮我找到一个 :)
Edit: I forgot to mention that it will highlight if I long hold on the button, but not a quick tap like it does if just added to a standard view.
编辑:我忘了提到如果我长时间按住按钮它会突出显示,但不会像添加到标准视图那样快速点击。
Code:
代码:
Creating the button:
创建按钮:
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button.titleLabel.font = [UIFont systemFontOfSize:14];
button.titleLabel.textColor = [UIColor blueColor];
[button setTitle:@"Testing" forState:UIControlStateNormal];
[button addTarget:self action:@selector(buttonPressed:) forControlEvents: UIControlEventTouchDown];
button.frame = CGRectMake(0, 0, self.view.frame.size.width/2, 40);
Things I've Tested:
我测试过的东西:
//Removing gesture recognizers on UITableView
in case they were getting in the way.
//删除手势识别器UITableView
,以防它们挡路。
for (UIGestureRecognizer *recognizer in self.tableView.gestureRecognizers) {
recognizer.enabled = NO;
}
//Removing gestures from the Cell
//从单元格中移除手势
for (UIGestureRecognizer *recognizer in self.contentView.gestureRecognizers) {
recognizer.enabled = NO;
}
//This shows the little light touch, but this isn't the desired look
//这显示了轻微的触摸,但这不是想要的外观
button.showsTouchWhenHighlighted = YES;
回答by subramani
In that tableview you just add this property.
在该 tableview 中,您只需添加此属性。
tableview.delaysContentTouches = NO;
And add in cellForRowAtIndexPath after you initiate the cell you just add below code. The structure of the cell is apparently different in iOS 6 and iOS 7.
iOS 7 we have one control UITableViewCellScrollView In between UITableViewCell and content View.
并在您启动您刚刚添加以下代码的单元格后添加 cellForRowAtIndexPath。单元格的结构在 iOS 6 和 iOS 7 中明显不同
。iOS 7 我们在 UITableViewCell 和内容视图之间有一个控件 UITableViewCellScrollView。
for (id obj in cell.subviews)
{
if ([NSStringFromClass([obj class]) isEqualToString:@"UITableViewCellScrollView"])
{
UIScrollView *scroll = (UIScrollView *) obj;
scroll.delaysContentTouches = NO;
break;
}
}
回答by Roman B.
Since iOS 8 we need to apply the same technique to UITableView subviews (table contains a hidden UITableViewWrapperView scroll view). There is no need iterate UITableViewCell subviews anymore.
从 iOS 8 开始,我们需要将相同的技术应用于 UITableView 子视图(表包含一个隐藏的 UITableViewWrapperView 滚动视图)。不再需要迭代 UITableViewCell 子视图。
for (UIView *currentView in tableView.subviews) {
if ([currentView isKindOfClass:[UIScrollView class]]) {
((UIScrollView *)currentView).delaysContentTouches = NO;
break;
}
}
This answershould be linked with this question.
这个答案应该与这个问题相关联。
回答by Eric
I tried to add this to the accepted answer but it never went through. This is a much safer way of turning off the cells delaysContentTouches property as it does not look for a specific class, but rather anything that responds to the selector.
我试图将其添加到已接受的答案中,但从未通过。这是关闭单元的更安全的方法 delaysContentTouches 属性,因为它不寻找特定的类,而是任何响应选择器的东西。
In Cell:
在单元格中:
for (id obj in self.subviews) {
if ([obj respondsToSelector:@selector(setDelaysContentTouches:)]) {
[obj setDelaysContentTouches:NO];
}
}
In TableView:
在表视图中:
self.tableView.delaysContentTouches = NO;
回答by Quentin
For a solution that works in both iOS7 and iOS8, create a custom UITableView
subclass and custom UITableViewCell
subclass.
对于适用于 iOS7 和 iOS8 的解决方案,请创建自定义UITableView
子类和自定义UITableViewCell
子类。
Use this sample UITableView
's initWithFrame:
使用这个样本UITableView
的initWithFrame:
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self)
{
// iterate over all the UITableView's subviews
for (id view in self.subviews)
{
// looking for a UITableViewWrapperView
if ([NSStringFromClass([view class]) isEqualToString:@"UITableViewWrapperView"])
{
// this test is necessary for safety and because a "UITableViewWrapperView" is NOT a UIScrollView in iOS7
if([view isKindOfClass:[UIScrollView class]])
{
// turn OFF delaysContentTouches in the hidden subview
UIScrollView *scroll = (UIScrollView *) view;
scroll.delaysContentTouches = NO;
}
break;
}
}
}
return self;
}
Use this sample UITableViewCell
's initWithStyle:reuseIdentifier:
使用这个样本UITableViewCell
的initWithStyle:reuseIdentifier:
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self)
{
// iterate over all the UITableViewCell's subviews
for (id view in self.subviews)
{
// looking for a UITableViewCellScrollView
if ([NSStringFromClass([view class]) isEqualToString:@"UITableViewCellScrollView"])
{
// this test is here for safety only, also there is no UITableViewCellScrollView in iOS8
if([view isKindOfClass:[UIScrollView class]])
{
// turn OFF delaysContentTouches in the hidden subview
UIScrollView *scroll = (UIScrollView *) view;
scroll.delaysContentTouches = NO;
}
break;
}
}
}
return self;
}
回答by Rapha?l Pinto
What I did to solve the problem was a category of UIButton using the following code :
我为解决这个问题所做的是使用以下代码的 UIButton 类别:
- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[super touchesBegan:touches withEvent:event];
[NSOperationQueue.mainQueue addOperationWithBlock:^{ self.highlighted = YES; }];
}
- (void) touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
[super touchesCancelled:touches withEvent:event];
[self performSelector:@selector(setDefault) withObject:nil afterDelay:0.1];
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
[super touchesEnded:touches withEvent:event];
[self performSelector:@selector(setDefault) withObject:nil afterDelay:0.1];
}
- (void)setDefault
{
[NSOperationQueue.mainQueue addOperationWithBlock:^{ self.highlighted = NO; }];
}
the button reacts correctly when I press on it in a UITableViewCell, and my UITableView behaves normally as the delaysContentTouches
isn't forced.
当我在 UITableViewCell 中按下按钮时,该按钮会正确反应,并且我的 UITableView 表现正常,因为delaysContentTouches
不是强制的。
回答by brandonscript
Here's Roman B's answer in Swift 2:
这是 Roman B 在 Swift 2 中的回答:
for view in tableView.subviews {
if view is UIScrollView {
(view as? UIScrollView)!.delaysContentTouches = false
break
}
}
回答by skg
I was having similar issues with a text-only UIButton in a UITableViewCell not highlighting upon touch. What fixed it for me was changing the buttonType from Custom back to System.
我在 UITableViewCell 中的纯文本 UIButton 遇到了类似的问题,没有在触摸时突出显示。对我来说修复它的是将 buttonType 从自定义更改回系统。
Setting delaysContentTouches to NO did the trick for the image-only UIButton in the same UITableViewCell.
将 delaysContentTouches 设置为 NO 对同一 UITableViewCell 中的纯图像 UIButton 起到了作用。
self.tableView.delaysContentTouches = NO;
回答by Gank
- (void)viewDidLoad
{
[super viewDidLoad];
for (id view in self.tableView.subviews)
{
// looking for a UITableViewWrapperView
if ([NSStringFromClass([view class]) isEqualToString:@"UITableViewWrapperView"])
{
// this test is necessary for safety and because a "UITableViewWrapperView" is NOT a UIScrollView in iOS7
if([view isKindOfClass:[UIScrollView class]])
{
// turn OFF delaysContentTouches in the hidden subview
UIScrollView *scroll = (UIScrollView *) view;
scroll.delaysContentTouches = NO;
}
break;
}
}
}
回答by Chris Harrison
This is a Swiftversion of Rapha?l Pinto's answer above. Don't forget to upvote him too :)
这是上面 Rapha?l Pinto 答案的Swift版本。也不要忘记给他点赞:)
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
super.touchesBegan(touches, withEvent: event)
NSOperationQueue.mainQueue().addOperationWithBlock { () -> Void in self.highlighted = true }
}
override func touchesCancelled(touches: NSSet!, withEvent event: UIEvent!) {
super.touchesCancelled(touches, withEvent: event)
let time = dispatch_time(DISPATCH_TIME_NOW, Int64(0.1 * Double(NSEC_PER_SEC)))
dispatch_after(time, dispatch_get_main_queue()) {
self.setDefault()
}
}
override func touchesEnded(touches: NSSet, withEvent event: UIEvent) {
super.touchesEnded(touches, withEvent: event)
let time = dispatch_time(DISPATCH_TIME_NOW, Int64(0.1 * Double(NSEC_PER_SEC)))
dispatch_after(time, dispatch_get_main_queue()) {
self.setDefault()
}
}
func setDefault() {
NSOperationQueue.mainQueue().addOperationWithBlock { () -> Void in self.highlighted = false }
}
回答by Chris
Solution in Swift, iOS8 only (needs the extra work on each of the cells for iOS7):
仅适用于 Swift、iOS8 的解决方案(需要对 iOS7 的每个单元格进行额外工作):
//
// NoDelayTableView.swift
// DivineBiblePhone
//
// Created by Chris Hulbert on 30/03/2015.
// Copyright (c) 2015 Chris Hulbert. All rights reserved.
//
// This solves the delayed-tap issue on buttons on cells.
import UIKit
class NoDelayTableView: UITableView {
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
delaysContentTouches = false
// This solves the iOS8 delayed-tap issue.
// http://stackoverflow.com/questions/19256996/uibutton-not-showing-highlight-on-tap-in-ios7
for view in subviews {
if let scroll = view as? UIScrollView {
scroll.delaysContentTouches = false
}
}
}
override func touchesShouldCancelInContentView(view: UIView!) -> Bool {
// So that if you tap and drag, it cancels the tap.
return true
}
}
To use, all you have to do is change the class to NoDelayTableView
in your storyboard.
要使用,您所要做的就是将类更改为NoDelayTableView
故事板中的。
I can confirm that in iOS8, buttons placed inside a contentView in a cell now highlight instantly.
我可以确认在 iOS8 中,放置在单元格中 contentView 中的按钮现在会立即突出显示。