文森說技術

iOS, Web Development Notes
- ,

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

之前在做專案的時候有發生,透明的 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
37
// 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 了。

如果覺得這篇對你有幫助,歡迎幫忙分享給其他人 😀