添加点击区域

作者 : 开心源码 本文共3044个字,预计阅读时间需要8分钟 发布时间: 2022-05-12 共137人阅读

项目中很多时候需要扩大点击(交互)区域,或者子试图超出了父视图后,无法点击或者交互等,我们可以通过响应者链
-(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event

来解决,下面是我封装的一个小控件,分享给大家show.jpg
1、在category里增加属性

-(void)setEnlargedMargin:(CGFloat)enlargedMargin{    [self setEnlargeEdge:UIEdgeInsetsMake(enlargedMargin, enlargedMargin, enlargedMargin, enlargedMargin)];}-(void)setEnlargeEdge:(UIEdgeInsets)enlargeEdge{    //拓展后的rect    CGRect rect=CGRectMake(self.bounds.origin.x-enlargeEdge.left, self.bounds.origin.y-enlargeEdge.top, self.frame.size.width+enlargeEdge.left+enlargeEdge.right, self.frame.size.height+enlargeEdge.top+enlargeEdge.bottom);    //存入    objc_setAssociatedObject(self, &key_yjn_enlarged, @[NSStringFromCGRect(rect)], OBJC_ASSOCIATION_RETAIN_NONATOMIC);    //挣脱父试图约束    CGRect windowConvertRect = [self convertRect:self.bounds toView:[[[UIApplication sharedApplication] delegate] window]];    [self freeView:self.superview rect:windowConvertRect enlargeEdge:enlargeEdge];}-(NSArray *)enlargedRect{    NSArray *enlargedArr = objc_getAssociatedObject(self, &key_yjn_enlarged);    if (enlargedArr) {        return enlargedArr;    }else{        return @[NSStringFromCGRect(self.bounds)];    }}

2、挣脱父试图约束

#pragma mark - 挣脱父试图约束-(void)freeView:(UIView *)superview rect:(CGRect)rect enlargeEdge:(UIEdgeInsets)enlargeEdge{    if(superview == nil) return;        //坐标转换    UIWindow * window=[[[UIApplication sharedApplication] delegate] window];    CGRect selfRect = [self convertRect:self.bounds toView:window];    CGRect superViewRect = [superview convertRect:superview.bounds toView:window];        if (CGRectContainsRect(superViewRect,selfRect)) {//完全包含        return;    }else{//不完全包含        NSMutableArray *rectArr = [NSMutableArray arrayWithArray:[superview enlargedRect]];        CGRect newRect = CGRectMake(rect.origin.x - superViewRect.origin.x, rect.origin.y - superViewRect.origin.y, rect.size.width, rect.size.height);                CGRect newEnlargeRect = CGRectMake(newRect.origin.x-enlargeEdge.left, newRect.origin.y-enlargeEdge.top, newRect.size.width+enlargeEdge.left+enlargeEdge.right, newRect.size.height+enlargeEdge.top+enlargeEdge.bottom);                [rectArr addObject:NSStringFromCGRect(newEnlargeRect)];        objc_setAssociatedObject(superview, &key_yjn_enlarged, rectArr, OBJC_ASSOCIATION_RETAIN_NONATOMIC);        [self freeView:superview.superview rect:rect enlargeEdge:enlargeEdge];    }}

3、响应者链传递

#pragma mark - 响应者链-(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event{    for (NSString *edgeStr in [self enlargedRect]) {        CGRect rect= CGRectFromString(edgeStr);        if (CGRectContainsPoint(rect,point)) {            return YES;        }    }    return NO;}-(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event{    // 1.判断下窗口是否接收事件    if (self.userInteractionEnabled == NO || self.hidden == YES ||  self.alpha <= 0.01){        return nil;    }    // 2.判断下点在不在窗口上    // 不在窗口上    if ([self pointInside:point withEvent:event] == NO){        return nil;    }    // 3.从后往前遍历子控件数组    int count = (int)self.subviews.count;    for (int i = count - 1; i >= 0; i--)     {        // 获取子控件        UIView *childView = self.subviews[i];        // 坐标系的转换,把窗口上的点转换为子控件上的点        // 把自己控件上的点转换成子控件上的点        CGPoint childP = [self convertPoint:point toView:childView];        UIView *fitView = [childView hitTest:childP withEvent:event];        if (fitView) {            // 假如能找到最合适的view            return fitView;        }    }    // 4.没有找到更合适的view,也就是没有比自己更合适的view    return self;}

4、【注】假如要挣脱约束,请想把view加到父view上,如[self.view addSubview:view];后才能增加enlargeEdge属性,否则不生效。demo地址 yinjining/hitEnlarged

说明
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » 添加点击区域

发表回复