iOS7/8 UIButton高亮状态延迟有关问题全解
2017-09-11 17:52
411 查看
iOS7/8 UIButton高亮状态延迟问题全解
估计很多码友都遇到过这样的情况:
UIButton在某些情况下不能立刻响应TouchDown事件,换句话说,迅速点击按钮时,你是永远看不见这个按钮的高亮状态的。
而你会发现,出现这种情况时,这些按钮都在UIScrollView(UITableView)上。
为此我用了一下午时间查贴整理,得到了完美的解决方案。
在介绍解决方案前,必须先科普一些事实,帮助大家理解:
UIScrollView:
1、属性delaysContentTouches,布尔类型,默认值为YES。值为YES时,UIScrollView会在接收到手势时延迟150ms来判断该手势是否能够出发UIScrollView的滑动事件;值为NO时,UIScrollView会立马将接收到的手势分发到子视图上。
(注:仅仅设置这个是不够的,你会发现如果想要拖动scrollView而起点落在其他有手势识别的视图上时会拖不动)
2、方法-
(BOOL)touchesShouldCancelInContentView:(UIView *)view,此方法的重载是帮助我们完美解决问题的重点,决定手势是否取消传递到view上,拖动ScrollView时触发。返回NO时,拖动手势将留在ScrollView上,返回YES则将手势传到view上。(若view是UIControl,则默认返回YES)
UITableView:
不得不说,UITableView(包括UITableViewCell在内)在iOS7和iOS8中的视图结构是不同的,且存在着很
18ae6
多我们在编码时永远接触不到的视图,但我们可通过Debug将其subviews逐个逐个找出来。这关系到我们这个问题坑比较深的层次。
iOS7:UITableView中存在n+1个UIScrollView,一个是UITableView本身,另外n个存在于UITableViewCell与cell的contentView之间,类名为UITableViewCellScrollView,活的不久,仅存在于iOS7中,在iOS8中已被移除。
iOS8:UITableView中存在2个UIScrollView,一个是UITableView本身,另外一个存在于UITableView与UITableViewCell之间,类名为UITableViewWrapperView。需要注意的是,UITableViewWrapperView在iOS7中并不是一个UIScrollView。
科普知识完,那么我们就有了以下的问题解决方案了:
1、将UIButton所有属于UIScrollView的父视图的delaysContentTouches属性设置成为NO。
2、继承UIScrollView或UITableView,并重写-
(BOOL)touchesShouldCancelInContentView:(UIView*)view方法,让其响应拖动方法。
以下是参考代码:
为了简便我将两个类的子类写在同一个文件中
NoDelayButtonScrollView.h:
[objc] view
plain copy
#import <UIKit/UIKit.h>
@interface NoDelayButtonScrollView : UIScrollView
@end
@interface NoDelayButtonTableView : UITableView
@end
NoDelayButtonScrollView.m(1):
[objc] view
plain copy
#import "NoDelayButtonScrollView.h"
@implementation NoDelayButtonScrollView
- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if (self)
{
self.delaysContentTouches = NO;
}
return self;
}
- (BOOL)touchesShouldCancelInContentView:(UIView *)view
{
if ([view isKindOfClass:[UIButton class]])
{
return YES;
}
return [super touchesShouldCancelInContentView:view];
}
@end
NoDelayButtonScrollView.m(2):
[objc] view
plain copy
@implementation NoDelayButtonTableView
- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if (self)
{
self.delaysContentTouches = NO;
// 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;
}
- (BOOL)touchesShouldCancelInContentView:(UIView *)view
{
if ([view isKindOfClass:[UIButton class]])
{
return YES;
}
return [super touchesShouldCancelInContentView:view];
}
@end
以上分别对UIScrollView和UITableView进行继承,重写initWithCoder:方法可保证使用Nib文件也能生效
使用这两个类继承写出来的ScrollView和TableView都能快速响应子Button的TouchDown事件,并显示高亮
但以上代码仍未能解决iOS7下UITableView的子Button高亮延迟问题。
可加入以下代码来解决:
[objc] view
plain copy
for (id obj in cell.subviews)
{
if ([NSStringFromClass([obj class]) isEqualToString:@"UITableViewCellScrollView"])
{
UIScrollView *scroll = (UIScrollView *) obj;
scroll.delaysContentTouches = NO;
break;
}
}
这段代码可加在Custom的UITableViewCell的initWithCoder:方法中,也可以放在UITableViewDelegate的cellForRowAtIndexPath:方法中设置对应cell中的UITableViewCellScrollView。
以上,是所有帮助你解决Button延迟高亮问题的方法。
估计很多码友都遇到过这样的情况:
UIButton在某些情况下不能立刻响应TouchDown事件,换句话说,迅速点击按钮时,你是永远看不见这个按钮的高亮状态的。
而你会发现,出现这种情况时,这些按钮都在UIScrollView(UITableView)上。
为此我用了一下午时间查贴整理,得到了完美的解决方案。
在介绍解决方案前,必须先科普一些事实,帮助大家理解:
UIScrollView:
1、属性delaysContentTouches,布尔类型,默认值为YES。值为YES时,UIScrollView会在接收到手势时延迟150ms来判断该手势是否能够出发UIScrollView的滑动事件;值为NO时,UIScrollView会立马将接收到的手势分发到子视图上。
(注:仅仅设置这个是不够的,你会发现如果想要拖动scrollView而起点落在其他有手势识别的视图上时会拖不动)
2、方法-
(BOOL)touchesShouldCancelInContentView:(UIView *)view,此方法的重载是帮助我们完美解决问题的重点,决定手势是否取消传递到view上,拖动ScrollView时触发。返回NO时,拖动手势将留在ScrollView上,返回YES则将手势传到view上。(若view是UIControl,则默认返回YES)
UITableView:
不得不说,UITableView(包括UITableViewCell在内)在iOS7和iOS8中的视图结构是不同的,且存在着很
18ae6
多我们在编码时永远接触不到的视图,但我们可通过Debug将其subviews逐个逐个找出来。这关系到我们这个问题坑比较深的层次。
iOS7:UITableView中存在n+1个UIScrollView,一个是UITableView本身,另外n个存在于UITableViewCell与cell的contentView之间,类名为UITableViewCellScrollView,活的不久,仅存在于iOS7中,在iOS8中已被移除。
iOS8:UITableView中存在2个UIScrollView,一个是UITableView本身,另外一个存在于UITableView与UITableViewCell之间,类名为UITableViewWrapperView。需要注意的是,UITableViewWrapperView在iOS7中并不是一个UIScrollView。
科普知识完,那么我们就有了以下的问题解决方案了:
1、将UIButton所有属于UIScrollView的父视图的delaysContentTouches属性设置成为NO。
2、继承UIScrollView或UITableView,并重写-
(BOOL)touchesShouldCancelInContentView:(UIView*)view方法,让其响应拖动方法。
以下是参考代码:
为了简便我将两个类的子类写在同一个文件中
NoDelayButtonScrollView.h:
[objc] view
plain copy
#import <UIKit/UIKit.h>
@interface NoDelayButtonScrollView : UIScrollView
@end
@interface NoDelayButtonTableView : UITableView
@end
NoDelayButtonScrollView.m(1):
[objc] view
plain copy
#import "NoDelayButtonScrollView.h"
@implementation NoDelayButtonScrollView
- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if (self)
{
self.delaysContentTouches = NO;
}
return self;
}
- (BOOL)touchesShouldCancelInContentView:(UIView *)view
{
if ([view isKindOfClass:[UIButton class]])
{
return YES;
}
return [super touchesShouldCancelInContentView:view];
}
@end
NoDelayButtonScrollView.m(2):
[objc] view
plain copy
@implementation NoDelayButtonTableView
- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if (self)
{
self.delaysContentTouches = NO;
// 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;
}
- (BOOL)touchesShouldCancelInContentView:(UIView *)view
{
if ([view isKindOfClass:[UIButton class]])
{
return YES;
}
return [super touchesShouldCancelInContentView:view];
}
@end
以上分别对UIScrollView和UITableView进行继承,重写initWithCoder:方法可保证使用Nib文件也能生效
使用这两个类继承写出来的ScrollView和TableView都能快速响应子Button的TouchDown事件,并显示高亮
但以上代码仍未能解决iOS7下UITableView的子Button高亮延迟问题。
可加入以下代码来解决:
[objc] view
plain copy
for (id obj in cell.subviews)
{
if ([NSStringFromClass([obj class]) isEqualToString:@"UITableViewCellScrollView"])
{
UIScrollView *scroll = (UIScrollView *) obj;
scroll.delaysContentTouches = NO;
break;
}
}
这段代码可加在Custom的UITableViewCell的initWithCoder:方法中,也可以放在UITableViewDelegate的cellForRowAtIndexPath:方法中设置对应cell中的UITableViewCellScrollView。
以上,是所有帮助你解决Button延迟高亮问题的方法。
相关文章推荐
- iOS7/8 UIButton高亮状态延迟有关问题全解
- iOS7/8 UIButton高亮状态延迟问题全解
- iOS7/8 UIButton高亮状态延迟问题全解
- UIButton高亮状态延迟问题全解
- BUG: button点击高亮延迟问题
- 解决UIButton 选中状态和未选中状态色差问题
- 有关视图状态(ViewState)的一些问题
- UIButton在Disabled状态下标题混乱的问题
- IE 下双击 checkbox 选中状态延迟问题
- UITextField限制输入字数高亮状态下输入框内真实类容与textFiled(解决中文输入问题)
- 探讨Ajax中有关readyState(状态值)和status(状态码)的问题
- 有关视图状态(ViewState)的一些问题
- UIButton 点击事件响应延迟 问题解决
- json解决hibernate中级联对象延迟加载有关问题
- 安桌可按控件的按下状态高亮不能显示出来的问题
- iOS UIButton选中状态下点击高亮
- swift 取消UIButton选中高亮状态
- IOS 解决UIButton 点击卡顿/延迟的问题
- iOS UIButton的第四种状态(选中高亮)
- tableView又遇到高亮选中状态混乱的问题了