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]) {
        // 遍歷當前對象的子視圖
        __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]) {
        // 遍歷當前對象的子視圖
        __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)系作者
  • 序言:七十年代末严肪,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子谦屑,更是在濱河造成了極大的恐慌驳糯,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,946評論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件氢橙,死亡現(xiàn)場離奇詭異酝枢,居然都是意外死亡,警方通過查閱死者的電腦和手機悍手,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,336評論 3 399
  • 文/潘曉璐 我一進店門帘睦,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人谓苟,你說我怎么就攤上這事官脓。” “怎么了涝焙?”我有些...
    開封第一講書人閱讀 169,716評論 0 364
  • 文/不壞的土叔 我叫張陵,是天一觀的道長孕暇。 經(jīng)常有香客問我仑撞,道長,這世上最難降的妖魔是什么妖滔? 我笑而不...
    開封第一講書人閱讀 60,222評論 1 300
  • 正文 為了忘掉前任隧哮,我火速辦了婚禮,結(jié)果婚禮上座舍,老公的妹妹穿的比我還像新娘沮翔。我一直安慰自己,他們只是感情好曲秉,可當我...
    茶點故事閱讀 69,223評論 6 398
  • 文/花漫 我一把揭開白布采蚀。 她就那樣靜靜地躺著,像睡著了一般承二。 火紅的嫁衣襯著肌膚如雪榆鼠。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,807評論 1 314
  • 那天亥鸠,我揣著相機與錄音妆够,去河邊找鬼识啦。 笑死,一個胖子當著我的面吹牛神妹,可吹牛的內(nèi)容都是我干的颓哮。 我是一名探鬼主播,決...
    沈念sama閱讀 41,235評論 3 424
  • 文/蒼蘭香墨 我猛地睜開眼鸵荠,長吁一口氣:“原來是場噩夢啊……” “哼冕茅!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起腰鬼,我...
    開封第一講書人閱讀 40,189評論 0 277
  • 序言:老撾萬榮一對情侶失蹤嵌赠,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后熄赡,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體姜挺,經(jīng)...
    沈念sama閱讀 46,712評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,775評論 3 343
  • 正文 我和宋清朗相戀三年彼硫,在試婚紗的時候發(fā)現(xiàn)自己被綠了炊豪。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,926評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡拧篮,死狀恐怖词渤,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情串绩,我是刑警寧澤缺虐,帶...
    沈念sama閱讀 36,580評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站礁凡,受9級特大地震影響高氮,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜顷牌,卻給世界環(huán)境...
    茶點故事閱讀 42,259評論 3 336
  • 文/蒙蒙 一剪芍、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧窟蓝,春花似錦罪裹、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,750評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至滑臊,卻和暖如春口芍,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背雇卷。 一陣腳步聲響...
    開封第一講書人閱讀 33,867評論 1 274
  • 我被黑心中介騙來泰國打工鬓椭, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留颠猴,地道東北人。 一個月前我還...
    沈念sama閱讀 49,368評論 3 379
  • 正文 我出身青樓小染,卻偏偏與公主長得像翘瓮,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子裤翩,可洞房花燭夜當晚...
    茶點故事閱讀 45,930評論 2 361

推薦閱讀更多精彩內(nèi)容

  • 今天感恩節(jié)哎资盅,感謝一直在我身邊的親朋好友。感恩相遇踊赠!感恩不離不棄呵扛。 中午開了第一次的黨會,身份的轉(zhuǎn)變要...
    迷月閃星情閱讀 10,576評論 0 11
  • 彩排完筐带,天已黑
    劉凱書法閱讀 4,236評論 1 3
  • 表情是什么今穿,我認為表情就是表現(xiàn)出來的情緒。表情可以傳達很多信息伦籍。高興了當然就笑了蓝晒,難過就哭了。兩者是相互影響密不可...
    Persistenc_6aea閱讀 125,403評論 2 7