hittest和touch相关事件(粗浅理解,待后续整理)


当我们需要重写某个UIView的继承类UIViewInherit的时候,如果需要重写hitTest:withEvent:方法,就会出现是否调用[super hitTest:withEvent:]方法的疑问?究竟是否需要都是看具体需求,这里只是说明调与不调的效果。
      如果不调用,那么重写的方法hitTest:withEvent:只会调用重写后的代码,根据所重写的代码返回self或nil,如果返回self那么你的这个UIViewInherit类会接受你的按键,然后调用touches系列方法;否则返回nil那么传递给UIViewInherit类的按键到此为止,它不接受它的父view给它的按键,即不会调用touches系列方法。这时,PointInside:withEvent:几乎没有作用。
      如果调用,那么[super hitTest:withEvent:]方法首先是根据PointInside:withEvent:的返回值决定是否递归调用所有子View的hitTest:withEvent:方法。对于子View的hitTest:withEvent:方法调用也是一样的过程,这样一直递归下去,直到最先找到的某个递归层次上的子View的hitTest:withEvent:方法返回非nil,这时候,调用即结束,最终会调用这个子View的touches系列方法。
        如果我们不想让某个视图响应事件,只需要重载 PointInside:withEvent:方法,让此方法返回NO就行了。

附上一段示例代码,留作记忆:

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {

    if (self.isTapAction) {

        if ([self yb_getTapFrameWithTouchPoint:point result:nil]) {

            return self;

        }

    }

    return [super hitTest:point withEvent:event];

}


#pragma mark - touchAction

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event

{

    UITouch *touch = [touches anyObject];

    

    CGPoint point = [touch locationInView:self];

}




#pragma mark - getTapFrame

- (BOOL)yb_getTapFrameWithTouchPoint:(CGPoint)point result:(void (^) (NSString *string , NSRange range , NSInteger index))resultBlock

{

    

    CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((CFAttributedStringRef)self.attributedText);

    

    CGMutablePathRef Path = CGPathCreateMutable();

    

    CGPathAddRect(Path, NULL, CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.height));

    

    CTFrameRef frame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, 0), Path, NULL);

    

    CFRange range = CTFrameGetVisibleStringRange(frame);

    

    if (self.attributedText.length > range.length) {

        

        UIFont *font ;

        

        if ([self.attributedText attribute:NSFontAttributeName atIndex:0 effectiveRange:nil]) {

            

            font = [self.attributedText attribute:NSFontAttributeName atIndex:0 effectiveRange:nil];

            

        }else if (self.font){

            font = self.font;

            

        }else {

            font = [UIFont systemFontOfSize:17];

        }

        

        Path = CGPathCreateMutable();

        

        CGPathAddRect(Path, NULL, CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.height + font.lineHeight));

        

        frame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, 0), Path, NULL);

    }

    

    CFArrayRef lines = CTFrameGetLines(frame);

    

    if (!lines) {

        CFRelease(frame);

        CFRelease(framesetter);

        CGPathRelease(Path);

        return NO;

    }

    

    CFIndex count = CFArrayGetCount(lines);

    

    CGPoint origins[count];

    

    

    CTFrameGetLineOrigins(frame, CFRangeMake(0, 0), origins);

    

    CGAffineTransform transform = [self yb_transformForCoreText];

    

    CGFloat verticalOffset = 0;

    

    for (CFIndex i = 0; i < count; i++) {

        CGPoint linePoint = origins[i];

        

        CTLineRef line = CFArrayGetValueAtIndex(lines, i);

        

        CGRect flippedRect = [self yb_getLineBounds:line point:linePoint];

        

        CGRect rect = CGRectApplyAffineTransform(flippedRect, transform);

        

        rect = CGRectInset(rect, 0, 0);

        

        rect = CGRectOffset(rect, 0, verticalOffset);

        

        NSParagraphStyle *style = [self.attributedText attribute:NSParagraphStyleAttributeName atIndex:0 effectiveRange:nil];

        

        CGFloat lineSpace;

        

        if (style) {

            lineSpace = style.lineSpacing;

        }else {

            lineSpace = 0;

        }

        

        CGFloat lineOutSpace = (self.bounds.size.height - lineSpace * (count - 1) -rect.size.height * count) / 2;

        

        rect.origin.y = lineOutSpace + rect.size.height * i + lineSpace * i;

        

        if (CGRectContainsPoint(rect, point)) {

            NSLog(@"point----:%@",NSStringFromCGPoint(point));

            CGPoint relativePoint = CGPointMake(point.x - CGRectGetMinX(rect), point.y - CGRectGetMinY(rect));


            CFIndex index = CTLineGetStringIndexForPosition(line, relativePoint);

            

            CGFloat offset;

            

            CTLineGetOffsetForStringIndex(line, index, &offset);

            

            if (offset > relativePoint.x) {

                index = index - 1;

            }

            

            NSInteger link_count = self.attributeStrings.count;


            for (int j = 0; j < link_count; j++) {

                

                YBAttributeModel *model = self.attributeStrings[j];

                

                NSRange link_range = model.range;

                if (NSLocationInRange(index, link_range)) {

                    if (resultBlock) {

                        resultBlock (model.str , model.range , (NSInteger)j);

                    }

                    CFRelease(frame);

                    CFRelease(framesetter);

                    CGPathRelease(Path);

                    return YES;

                }

            }

        }

        

        

    }

    CFRelease(frame);

    CFRelease(framesetter);

    CGPathRelease(Path);

    return NO;

}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值