ios UIButton點擊范圍設(shè)置 2021-04-13

可以自己寫UIButton分類重寫按鈕響應(yīng)鏈方法,結(jié)合關(guān)聯(lián)對象設(shè)置屬性來控制button的具體實現(xiàn)方法。

  • hitTest中的內(nèi)部實現(xiàn)面試時可能會用到
//  重新實現(xiàn)hittest方法,實現(xiàn)圓形按鈕點擊范圍
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
    if (!self.userInteractionEnabled||self.hidden||self.alpha<0.01) {
        return nil;
    }
    if ([self pointInside:point withEvent:event]) {
        // 遍歷當(dāng)前對象的子視圖
        __block UIView *hit = nil;
        [self.subviews enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(__kindof UIView * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
                // 坐標轉(zhuǎn)換
            //  convertPoint: toView:是(調(diào)用者的point+convertpoint)- toview的point
            //  convertPoint: fromView:是(fromView的point+convertpoint)- 調(diào)用者的point
            CGPoint convertPoint = [self convertPoint:point toView:obj];
            // 調(diào)用子視圖的hittest方法
            hit = [obj hitTest:convertPoint withEvent:event];
            // 如果找到了接受事件的對象,就停止遍歷
            if (hit) {
                *stop=YES;
            }
        }];
        if (hit) {
            return hit;
        }else{
            return self;
        }
    }else{
        return nil;
    }
}
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
    // 點擊的點
    CGFloat x1=point.x;
    CGFloat y1=point.y;
    // 中心
    CGFloat x2=self.frame.size.width/2;
    CGFloat y2=self.frame.size.height/2;
    // 平方差公式
    double dis = sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
    if (dis<=self.frame.size.width/2) {
        return YES;
    }else{
        return NO;
    }
}

針對超出父view之外的部分,比如按鈕點擊無響應(yīng)問題

      原因:響應(yīng)鏈會先判斷點是否在父view范圍內(nèi),在父view范圍內(nèi)就正序遍歷子視圖判斷哪個來響應(yīng),不在就不響應(yīng)該點擊事件。
//超出父層的按鈕部分點擊無效果 ---  可通過父類view重寫如下方法判斷子view能否響應(yīng)
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
    for (UIView *subV in self.subviews) {
        if ([subV isKindOfClass:[UIButton class]]) {
            UIButton *btn=(UIButton *)subV;
            if (CGRectContainsPoint(btn.frame, point)) {
                return YES;
            }
        }
    }
    BOOL ss=[super pointInside:point withEvent:event];
    return ss;
}

在來個CoreAnimation運動動畫的btn無法點擊辦法解決:
自定義子view和自定義父view分別重寫- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event和- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event 方法
自定義父view實現(xiàn):

//超出父層的按鈕部分點擊無效果 ---  可通過重寫如下方法盤點子view能否響應(yīng)時間
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
    if (!self.userInteractionEnabled||self.hidden||self.alpha<0.01) {
        return nil;
    }
    if ([self pointInside:point withEvent:event]) {
        // 遍歷當(dāng)前對象的子視圖
        __block UIView *hit = nil;
        [self.subviews enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(__kindof UIView * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
             // 看情需要否轉(zhuǎn)換坐標
                // 坐標轉(zhuǎn)換
            //  convertPoint: toView:是(調(diào)用者的point+convertpoint)- toview的point
            //  convertPoint: fromView:是(fromView的point+convertpoint)- 調(diào)用者的point
//          CGPoint convertPoint = [self convertPoint:point toView:obj];
            // 調(diào)用子視圖的hittest方法
            hit = [obj hitTest:point withEvent:event];
            // 如果找到了接受事件的對象,就停止遍歷
            if (hit) {
                *stop=YES;
            }
        }];
        if (hit) {
            return hit;
        }else{
            return self;
        }
    }else{
        return nil;
    }
}

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
    for (UIView *subV in self.subviews) {
        if ([subV isKindOfClass:[UIButton class]]) {
            UIButton *btn=(UIButton *)subV;
            // 通過判斷子view的運動layerframe來確定點擊范圍
            if (CGRectContainsPoint(btn.layer.presentationLayer.frame, point) ) {
                return YES;
            }
        }
    }
    BOOL ss=[super pointInside:point withEvent:event];
    return ss;
}

自定義子view實現(xiàn):

// 通過判斷子view的運動layerframe來確定點擊范圍
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
    UIView *vc=[super hitTest:point withEvent:event];
    if (CGRectContainsPoint(self.layer.presentationLayer.frame, point) ) {
        return self;
    }
    return vc;
}

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
    BOOL ss=NO;
    if (CGRectContainsPoint(self.layer.presentationLayer.frame, point) ) {
        ss=YES;
    }else{
        ss=[super pointInside:point withEvent:event];
    }
    return ss;
}

最后送個仿支付寶上下不規(guī)則浮動泡泡的動畫:

    CABasicAnimation *opacityAnim1 =[CABasicAnimation animationWithKeyPath:@"opacity"];
    opacityAnim1.fromValue = [NSNumber numberWithDouble:1];
    opacityAnim1.toValue =[NSNumber numberWithDouble:.5];
    opacityAnim1.duration=5+(double)arc4random()/0x100000000;// 修改漸變動畫時間
    opacityAnim1.repeatCount=MAXFLOAT;
    opacityAnim1.delegate=self;
    opacityAnim1.fillMode =kCAFillModeForwards;
    opacityAnim1.autoreverses=YES;
    opacityAnim1.removedOnCompletion=NO;
    opacityAnim1.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    [btn.layer addAnimation:opacityAnim1 forKey:@"LightopacityAnim"];


    CABasicAnimation *shake1Animation = [CABasicAnimation animationWithKeyPath:@"transform.translation.y"];
    double fw1=50+(double)arc4random()/0x100000000;// 修改位移動畫距離
    shake1Animation.duration=5+(double)arc4random()/0x100000000;// 修改位移動畫時間
    shake1Animation.fromValue = [NSNumber numberWithFloat:-fw1];
    shake1Animation.toValue = [NSNumber numberWithFloat:fw1];
    shake1Animation.autoreverses = YES;
    shake1Animation.repeatCount=MAXFLOAT;
    shake1Animation.fillMode =kCAFillModeForwards;
    shake1Animation.removedOnCompletion=NO;
    shake1Animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    [btn.layer addAnimation:shake1Animation forKey:nil];
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 今天感恩節(jié)哎,感謝一直在我身邊的親朋好友。感恩相遇!感恩不離不棄。 中午開了第一次的黨會,身份的轉(zhuǎn)變要...
    余生動聽閱讀 10,851評論 0 11
  • 彩排完,天已黑
    劉凱書法閱讀 4,475評論 1 3
  • 表情是什么,我認為表情就是表現(xiàn)出來的情緒。表情可以傳達很多信息。高興了當(dāng)然就笑了,難過就哭了。兩者是相互影響密不可...
    Persistenc_6aea閱讀 129,654評論 2 7

友情鏈接更多精彩內(nèi)容