美文网首页iOS
UIButton高亮延时

UIButton高亮延时

作者: 6129b93b59e2 | 来源:发表于2016-06-12 10:03 被阅读117次

    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中的视图结构是不同的,且存在着很多我们在编码时永远接触不到的视图,但我们可通过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方法,让其响应拖动方法。

    创建 类继承于 UIScrollView

    .h
    #import <UIKit/UIKit.h>
    @interface NoDelayButtonScrollView : UIScrollView
    @end
    @interface NoDelayButtonTableView : UITableView
    @end

    .m
    #import "NoDelayButtonScrollView.h"
    @implementation NoDelayButtonScrollView
    //这个方法 可以替换- (id)initWithFrame:(CGRect)frame style:(UITableViewStyle)style
    - (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

    创建 类继承于 UITableView

    .h
    #import <UIKit/UIKit.h>
    @interface NoDelayButtonTableView : UITableView
    @end

    .m
    @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  
    

    iOS7要单独设置下下面代码可加在Custom的UITableViewCell的initWithCoder:方法中,也可以放在UITableViewDelegate的cellForRowAtIndexPath:方法中设置对应cell中的UITableViewCellScrollView。

     for (id obj in cell.subviews)  
    {  
    if ([NSStringFromClass([obj class]) isEqualToString:@"UITableViewCellScrollView"])  
    {  
        UIScrollView *scroll = (UIScrollView *) obj;  
        scroll.delaysContentTouches = NO;  
        break;  
    }  
    }  

    相关文章

      网友评论

      • 前年的邂逅_Jerry:楼主,问你一个问题,把按钮放在屏幕最下面,将宽度调成屏幕宽,高度为30。按钮的左半边UIControlEventTouchDown延时触发。

      本文标题:UIButton高亮延时

      本文链接:https://www.haomeiwen.com/subject/jwmrrttx.html