2010-01-13 30 views
10

我的應用程序有兩個重疊的UIButton。頂部按鈕有時可能會被禁用。但是,在這種情況下,它接收到的任何觸摸事件似乎都會傳遞給底層視圖,在我的情況下是另一個按鈕。防止禁用UIButton傳播觸摸事件

我需要的是頂部按鈕攔截所有觸摸並阻止它們到達底部按鈕,即使在禁用狀態下(即使在禁用狀態下調用指定動作,我也會很高興)。

到目前爲止,我已經試過:

[topButton setUserInteractionEnabled:YES]; 

[topButton setExclusiveTouch:YES]; 

雖然後一種情況可能是不可取的,因爲我還需要底部按鈕對事件作出響應,如果它是第一個視圖點擊。無論哪種方式,他們都沒有工作。

回答

1

創建按鈕的子類,然後重寫這些方法,使得按鈕將捕獲事件,但忽略它們如果按鈕的一些屬性設置爲NO:

touchesBegan:withEvent: 
touchesCancelled:withEvent: 
touchesEnded:withEvent: 
touchesMoved:withEvent: 

這些UIResponder的方法。

如果你想讓事件處理,讓他們只是調用他們的[super ...]方法,否則就不要調用它並返回,如果你想要事件「吃掉」。

也看到這個情況下,有必要:Observing pinch multi-touch gestures in a UITableView

+0

看起來像這些方法在按鈕被禁用時根本不會被調用。 – 2010-01-14 08:10:34

+0

是的,這就是我想的(這就是爲什麼我說「某些屬性」),這就是爲什麼你可能需要使用第二種方法,或者做一些事情,而不是禁用按鈕,像模擬禁用某種方式。第二種方法可能會很痛苦,因爲UIApplication(它調用窗口中的sendEvent)可能是忽略禁用的UIControls。 – Nimrod 2010-01-14 16:42:24

2

我做什麼用的UIButton剛下的UIButton放在UIImageView的大小相同。然後,即使您禁用UIButton,觸摸事件也不會傳播UIImageView。

+0

這實際上是最簡單和最快速的解決方案 – codingFriend1 2017-07-11 13:30:33

13

我添加下面的方法來禁用的按鈕的上海華:

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event 
{ 
    if (!self.watchButton.enabled && 
     [self.watchButton pointInside:[self convertPoint:point toView:self.watchButton] 
          withEvent:nil]) { 
     return nil; 
    } 
    return [super hitTest:point withEvent:event]; 
} 

這與細胞的UITableView效果很好。

1

我設法得到這個工作,因爲我需要上面的@kolyuchiy的答案稍微修改後的版本。我忽略子類中的hitTest:withEvent:方法,禁用時返回self,並且該點位於視圖的框架內,以便觸摸消耗,但不調用按鈕的事件處理。

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event 
{ 
    if (!self.enabled && [self pointInside:[self convertPoint:point toView:self] withEvent:event]) 
    { 
     return self; 
    } 
    return [super hitTest:point withEvent:event]; 
} 
2

試圖@kolyuchiy(這需要修改其範圍之外UIButton行爲)和@帕特里克 - 林奇(這只是沒有工作對我來說)解決方案後,帶着更優雅的一個,它適用於UIButton子:

private static let dummyView: UIView = { 
    let view = UIView(frame: .zero) 
    view.userInteractionEnabled = true 
    return view 
}() 

public override func hitTest(point: CGPoint, withEvent event: UIEvent?) -> UIView? { 
    if !enabled && pointInside(point, withEvent: event) { 
     return self.dynamicType.dummyView 
    } 
    return super.hitTest(point, withEvent: event) 
} 
+1

Up view for view.userInteractionEnabled = true。 – iwill 2017-06-13 04:20:44