熊屋 | 技術小記

iOS, Web Development Notes

讓 Touch Events 不被上方的透明 UIView 擋住

| Comments

之前在做專案的時候有發生,透明的 UIView 會擋住底層的 touch 事件。原因是當 touch event 觸發的時候,是以最上方可互動的 UI control 為優先,但是還是有辦法可以穿過的。

解法

解法就是在需要穿透的 UIView subclass 中 override UIViewpointInside:withEvent: method 來改變觸控到時的行為。

設定觸發 Touch Event 的條件

根據 Apple 的 Documentation (ref.) 中提到,這個 method 會回傳 BOOL value 。回傳 YES 則可以觸發該 view 的 touch event。

因此根據我的需求(透明的不要觸發)就設下以下條件,就會觸發 touch event ,如果沒有符合條件,則會自動再往後面一層的 UIView 觸發 touch event:

  • view 不是 hidden
  • view 的 alpha 大於 0
  • view 可以互動 (userInteractionEnabled == YES)
  • view 可以接收這個 touch event
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
// In a UIView subclass

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
{
    // 檢查自己
    if ([self checkInteractableWithView:self point:point event:event])
    {
        return YES;
    }

    // 檢查 subviews
    for (UIView *view in self.subviews)
    {
        if ([self checkInteractableWithView:view point:point event:event])
        {
            return YES;
        }
    }

    return NO;
}

- (BOOL)checkInteractableWithView:(UIView *)view point:(CGPoint)point event:(UIEvent *)event
{
    if ( ! view.hidden &&
        view.alpha > 0 &&
        view.userInteractionEnabled &&
        [view pointInside:[self convertPoint:point toView:view] withEvent:event])
    {
        return YES;
    }
    else
    {
        return NO;
    }
}

這樣就可以讓 touch events 穿過任何透明或無法互動的 UIControl 了。

Comments