iOS-擴大按鈕點擊范圍


更新記錄

  • 2020年3月28日,初稿

文章背景

近日,接到頭頭突然讓我改一個東西,讓我馬上把某個按鈕的點擊相應區域擴大一點。作為一個iOS三個月的新人,還真不了解要怎么做。隨后,頭頭說只要加一行代碼就行了,然后讓某位前輩直接把參考代碼發給我。
后來,我加了一行類似於如下的代碼:

[button setHitTestEdgeInsets:UIEdgeInsetsMake(-10, -10, -10, -10)];

就使得按鈕點擊區域擴大了。但是,我不明白其中的原理。於是乎,想要一探究竟。

探索過程

  • 網上搜索iOS擴展按鈕點擊區域,發現有一個千篇一律的方法:
    增加UIButton的點擊范圍,那么從中也可以窺探出,這個方法大概率就是業界常用的,擴大按鈕點擊區域的方法。
  • 上述鏈接可以優化的一點的是:不要重寫UIButton類的pointInside:withEvent:方法,使用swizzle交換IMP
  • 具體源碼如下:
+ (void)load {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        NSError *error = nil;
        [self jr_swizzleMethod:@selector(pointInside:withEvent:) withMethod:@selector(hitTest_pointInside:withEvent:) error:&error];
        NSAssert(!error, @"UIView+HitTest.h swizzling failed: error = %@", error);
    });
}

- (BOOL)hitTest_pointInside:(CGPoint)point withEvent:(UIEvent *)event {
    if (UIEdgeInsetsEqualToEdgeInsets(self.hitTestEdgeInsets, UIEdgeInsetsZero)) {
        return [self hitTest_pointInside:point withEvent:event];
    }
    CGRect relativeFrame = self.bounds;
    CGRect hitFrame = UIEdgeInsetsInsetRect(relativeFrame, self.hitTestEdgeInsets);
    return CGRectContainsPoint(hitFrame, point);
}

探索其中的知識點

dispatch_once

  • 源碼及原理可參考玩轉dispatch_once
  • 原理還是挺深入的,在此不便深入。僅知道可以保證只初始化一次,且保證多線程安全。(可和Java中的單例模式Double CheckLock初始化比較一下)

關聯對象(如何給分類添加屬性)

CGRectInset

事件響應鏈

  • 在這個例子中的使用還是很簡單的。通過pointInside:withEvent:函數判斷,該點擊點是否在該view的點擊范圍內,否則就往時間響應鏈的下游傳遞。

寫在后面的話

  • 因為剛入門iOS,而且工作的大多時間都花在業務邏輯上,對iOS基礎知識這一塊還很不熟悉。本例中的很多知識點,我也是解除了這個例子之后我才了解得到。
  • 所以這篇文章也是比較水,沒有什么深度,僅作為自己初級學習過程中的一個總結。
  • 這里的不少知識點,沒有過多地寫個人總結,因為本身也是比較簡單的知識,網上搜索已經有一大堆的參考了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM