How to highlight a UIView like Apple does
You can use a custom view like this for example:
class HighlightView: UIView {
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
DispatchQueue.main.async {
self.alpha = 1.0
UIView.animate(withDuration: 0.4, delay: 0.0, options: .curveLinear, animations: {
self.alpha = 0.5
}, completion: nil)
}
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
DispatchQueue.main.async {
self.alpha = 0.5
UIView.animate(withDuration: 0.4, delay: 0.0, options: .curveLinear, animations: {
self.alpha = 1.0
}, completion: nil)
}
}
override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
DispatchQueue.main.async {
self.alpha = 0.5
UIView.animate(withDuration: 0.4, delay: 0.0, options: .curveLinear, animations: {
self.alpha = 1.0
}, completion: nil)
}
}
}
Then you can use it instead of UIView
and whenever you will click on it, it will change it's alpha
value so it will look like a highlight.
I don't think there is an easy or definitive answer to that.
DISCLAIMER: All the code in this answer was written from the top of my head, so please excuse mistakes.
I would suggest doing something like this:
Proposal 1: decrease opacity for all the view's subviews, which would not affect color...
Objective C:
-(void)buttonTouched{
for(UIView *subview in self.subviews){
subview.alpha = 0.5;
}
}
Swift:
func buttonTouched() {
for subview in subviews {
subview.alpha = 0.5
}
}
Proposal 2 (not tested): try to cover all subviews by doing it kind of manually (drawback: you would have to set the colors back manually as well, which would be insane if it is not monochromatic):
Objective C:
-(void)buttonTouched{
for(UIView *subview in self.subviews){
if([subview respondsToSelector:@selector(setBackgroundColor:)]){
//for generic views - changes UILabel's backgroundColor too, though
subview.backgroundColor = [UIColor grayColor];
}
if([subview respondsToSelector:@selector(setTextColor:)]){
//reverse effect of upper if statement(if needed)
subview.backgroundColor = [UIColor clearColor];
subview.textColor = [UIColor grayColor];
}
}
}
Swift:
func buttonTouched() {
for subview in subviews {
if subview.responds(to: #selector(setter: AVMutableVideoCompositionInstruction.backgroundColor)) {
//for generic views - changes UILabel's backgroundColor too, though
subview.backgroundColor = UIColor.gray
}
if subview.responds(to: #selector(setter: UILabel.textColor)) {
//reverse effect of upper if statement(if needed)
subview.backgroundColor = UIColor.clear
subview.textColor = UIColor.gray
}
}
}
This is really bad design and will probably cause a lot of problems, but it could potentially help you. The example above needs a lot of improvement, I just want to give you a hint. You would have to revert the colors in the touchesEnded: method. Maybe it helps you...
Proposal 3: would be to overlay your whole view with a transparent view (if it is rectangular)
Objective C:
-(void)buttonTouched{
UIView *overlay = [[UIView alloc]initWithFrame:self.bounds];
overlay.backgroundColor = [[UIColor grayColor]colorWithAlphaComponent:0.5];
[self addSubview: overlay];
}
Swift:
func buttonTouched() {
let overlay = UIView(frame: bounds)
overlay.backgroundColor = UIColor.gray.withAlphaComponent(0.5)
addSubview(overlay)
}
You would have to remove it when the user releases the finger of course.
Proposal 4 : Another option would be to create a bitmap of your current view and modify the pixels to your liking, which is quite a bit of work, so I will omit code here.
Apple probably does a mix of the last two. When a button is touched it will go over the pixels and overlay a gray pixel over every pixel that has an alpha component.
I hope I could help.
I know this is an old question. But if someone is still searching for a generic touch highlighting solution, here is a little category I have created to address the problem.
https://github.com/mta452/UIView-TouchHighlighting
Usage:
Just import the category in your view controller and add the following line in viewDidLoad.
buttonView.touchHighlightingStyle = MTHighlightingStyleHollowDarkOverlay;
Different Highlighting Styles: