问题
I can't figure this out, and I don't think this really explains it either.
I have a UILabel
that can be tapped by the user to hide or show it, set up like this:
self.numberLabel.userInteractionEnabled = YES;
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc]
initWithTarget:self action:@selector(hideOrShowNumber)];
[self.numberLabel addGestureRecognizer:tapGesture];
I would like to animate the hiding and showing of the label by setting the alpha
value on the UILabel
. However, if I set the alpha value to 0.0f
, the label no longer accepts taps, so even if the user can hide the label, she can't show it anymore!
My workaround goes like this:
When hiding the label: - Animate the alpha value to 0.0f. - Set the text color of the label to black (which makes it invisible because the background is black) - Reset the alpha to 1.0f.
When showing the label: - Set the alpha to 0.0f (because it was left at 1.0f when the label was hidden). - Set the text color to another color than black (depending on game state). - Animate the alpha value to 1.0f.
The code looks like this (there are some state variables included, but self.numberLabel
is the reference to the UILabel
):
NSTimeInterval duration = 0.6f;
if (self.numberIsVisible) {
[UIView animateWithDuration:duration
animations:^{
self.numberLabel.alpha = 0.0f;
}
completion:^(BOOL done) {
self.numberLabel.textColor = [UIColor blackColor];
self.numberLabel.alpha = 1.0f;
}
];
self.numberIsVisible = NO;
}
else {
UIColor *rightColor = [UIColor whiteColor];
if ([GameState sharedGameState].haveMatch) {
rightColor = [UIColor colorWithRed:0.0/255.0 green:127.0/255.0 blue:255.0/255.0 alpha:1.0];
}
self.numberLabel.alpha = 0.0f;
self.numberLabel.textColor = rightColor;
[UIView animateWithDuration:duration
animations:^{
self.numberLabel.alpha = 1.0f;
}
];
self.numberIsVisible = YES;
}
It works, but it is a little clunky.
So the question is, why does setting the transparency of the UILabel
make it lose user interaction? Is this by design, and is it documented somewhere? I can't find anything about this in the UIGestureRecognizer
docs.
回答1:
From the official doc (Regulating Touch Event Delivery section)
Turning off delivery of touch events. By default, a view receives touch events, but you can set its userInteractionEnabled property to NO to turn off delivery of touch events. A view also does not receive these events if it’s hidden or if it’s transparent.
Having full transparency (alpha = 0) on a view is consider to be similar as having a view hidden so there is no reason the user interaction should he handled in that case. You could try to have nearly-transparent UILabel
instead. An alpha of 0.1
seems to be the limit.
回答2:
It seems as though any UIView with an alpha of < 0.1f acts as though the hidden property were set to YES. In other words, since your view is transparent, it will not receive touch events. See this post.
回答3:
At least with iOS 8, you can set the alpha to 0.01 (no longer is the limit 0.1) and touch events will be triggered. If it is 0.0 touch events will not be triggered.
Update: I have discovered in iOS 8.2 and perhaps earlier versions, the limit is 0.001960785. Very close to fully transparent. Perhaps that number could be even smaller, I didn't take the decimal places any further.
回答4:
Apparently this behavior used to be documented, but I can't find it in the current docs.
See this answer: Why doesn't touchesBegan fire on UIViews when alpha is set to zero?
"By default, a view receives touch events, but you can set its userInteractionEnabled property to NO to turn off delivery of events. A view also does not receive events if it’s hidden or if it’s transparent."
There's no reason the UILabel
that you hide needs to be the same view as the one that receives the touches. An easier workaround would be:
- add a wrapper UIView where you want the user to be able to tap
- add the gesture recognizer to the wrapper view
- make the gesture recognizer's action just hide or show the label
回答5:
By design a view wont receive touches when the alpha is set to 0. You can try to set the alpha to 0.1 instead. Check the apple link https://developer.apple.com/library/ios/#documentation/EventHandling/Conceptual/EventHandlingiPhoneOS/MultitouchEvents/MultitouchEvents.html.
回答6:
I solved this by creating a UILabel containing a space, then used Autolayout constraints to grow/shrink as needed.
来源:https://stackoverflow.com/questions/14170329/why-does-setting-a-uilabel-to-be-fully-transparent-lose-tap-gestures