Carmelo Carmelo - 2 months ago 16
Swift Question

UIButton: when isHighlighted = true, I can only call a function by swiping my finger

Need some of your great knowledge :)

I wrote a subclass of UIButton (CustomWideButton.swift) without using a UIButton object. I did it this way because it's more flexible for the types of buttons I need to create.

There is a strange thing and I don't know if it is a normal behaviour.

var isHighlighted is called when tapping the button area which is normal. So if I write something like this:

var isHighlighted {
didSet {
print("I am Highlighted")
animateHighlight()
}
}




I will see in the console "I am highlighted", but it won't call animateHighlight() unless I slightly start swiping my finger on the button. If I do so, then animateHighlight() works.

I posted a sample project on BitBucket so it'll be easier for you to understand the issue I'm facing:
https://bitbucket.org/stephaneDepoilly/stackohighlightedbutton

Direct link for zip: https://bitbucket.org/stephaneDepoilly/stackohighlightedbutton/get/ee4fc398f475.zip

I'm sorry if the custom button code looks overkill, it's because I partially extracted it from my project and we're using MVVM.

Thanks in advance for your help!

Answer Source

Your debugging messages are misleading you. I replaced your print with:

 NSLog("isHighlighted on \(title) set to \(isHighlighted)")

And I added as the first line in animateHighlight():

 NSLog("animateHighlight enter: triggered by isHighlighted on \(title) set to \(isHighlighted)")

And I got:

2017-08-27 21:57:34.870 StackO_HighlightFunctionCall isHighlighted on [...LOGIN...] set to true
2017-08-27 21:57:34.871 StackO_HighlightFunctionCall animateHighlight enter: triggered by isHighlighted on [...LOGIN...] set to true
2017-08-27 21:57:35.000 StackO_HighlightFunctionCall isHighlighted on [...LOGIN...] set to false
2017-08-27 21:57:35.000 StackO_HighlightFunctionCall animateHighlight enter: triggered by isHighlighted on [...LOGIN...] set to false

So:

1) animateHighlight is indeed being called when you tell it to be called. Use the DebuggerForce!

2) isHighlighted state switches very rapidly (0.13 sec) back to false after being set to true. Did you expect that?

3) animateHighlight is buggy and doesn't produce any visible change. If you trace through your code carefully you'll see setupUI() gets called right after updating the label's text. This is because you are calling setupUI() from layoutSubviews(). layoutSubviews gets called all the time during runtime when anything about a view changes that could possibly affect subviews. setupUI should get called only when the view is added to its superview, e.g. at viewDidLoad()

The reason the swipe works is that layoutSubviews() is delayed until you finish swiping, because it's the .touchUpInside event that triggers the tap action, but isHighlighted is triggered by hidden UIButton .touchDownInside handling!