I am attempting to place a UIButton in a UICollectionView supplementary view (footer). I have connected the UIButton using storyboards to a subclass of UICollectionViewCell and can change it's properties programmatically including the background image. However, when I wire up the touch up inside event of the button to a method, it does not fire. In fact, the button does not even appear to be responding visually to the user's touch. In troubleshooting, I attempted to add a UIButton to the collection view's header and see identical behavior. Adding the button to an unrelated view produces interaction effects when pressed.
Is there something special I need to do to implement a UIButton in a UICollection supplementary view?
A supplementary view should be a UICollectionReusableView
(or subclass thereof), not a UICollectionViewCell
.
Anyway, if the button's not responding, the first thing to do is check that all of its ancestor views have userInteractionEnabled
set to YES
. Pause in the debugger once the button is on screen and do this:
(lldb) po [[UIApp keyWindow] recursiveDescription]
Find the button in the list and copy its address. Then you can check it and each superview. Example:
(lldb) p (BOOL)[0xa2e4800 isUserInteractionEnabled]
(BOOL) $4 = YES
(lldb) p (BOOL)[[0xa2e4800 superview] isUserInteractionEnabled]
(BOOL) $5 = YES
(lldb) p (BOOL)[[[0xa2e4800 superview] superview] isUserInteractionEnabled]
(BOOL) $6 = YES
(lldb) p (BOOL)[[[[0xa2e4800 superview] superview] superview] isUserInteractionEnabled]
(BOOL) $8 = YES
(lldb) p (BOOL)[[[[[0xa2e4800 superview] superview] superview] superview] isUserInteractionEnabled]
(BOOL) $9 = YES
(lldb) p (BOOL)[[[[[[0xa2e4800 superview] superview] superview] superview] superview] isUserInteractionEnabled]
(BOOL) $10 = NO
(lldb) po [[[[[0xa2e4800 superview] superview] superview] superview] superview]
(id) $11 = 0x00000000 <nil>
Here I found that all views up to the root (the UIWindow
) return YES
from isUserInteractionEnabled
. The window's superview is nil.
I have a custom button which subclasses UIControl
and put it inside a UICollectionReusableView
. To make it work, I made every single subview of the control and its subviews' subviews handle no user interaction.
func disableUserInteractionInView(view: UIView) {
view.userInteractionEnabled = false
for view in view.subviews {
self.disableUserInteractionInView(view)
}
}
// My control has a subview called contentView which serves as a container
// of all my custom button's subviews.
self.disableUserInteractionInView(self.contentView)
Since adding that code, all event listeners to .TouchUpInside
would fire, and the control will visually highlight when pressed down.