I first declare the button
let balloon = UIButton()
A background image then gets added to the balloon
balloon.setBackgroundImage(UIImage(named:"balloon.jpg"), for: .normal)
An image view of the points get added to the balloon as a subview
subView = UIImageView(image: UIImage(named: "1") )
subView.frame = CGRect(x: 0, y: 0, width: 30, height: 30)
subView.contentMode = UIView.ContentMode.scaleAspectFit
subView.center = CGPoint(x: balloon.frame.width/2, y: balloon.frame.height/2)
balloon.addSubview(subView)
I then use the addTarget function for the balloon
balloon.addTarget(self, action: #selector(pop), for: .touchUpInside)
After pop gets called (when the user taps on the balloon), the balloon now contains 2 subviews - At index 0 of balloon.subviews, there is a UIImageView that is essentially the picture of the balloon with the same dimensions as the balloon button - And the subs view that I added (aka the points)
here is how I found this problem in my addTarget function (pop):
@objc func pop(_ balloon: UIButton){
print("4.This is the balloon after calling pop \(balloon)")
print("5. This is the subview of the balloon after calling pop \(balloon.subviews)")
Ive added print statements in my function that verifies that the balloons are the same in both the pop func and my balloon creation func
I have already looked at the documentation for both UIButton and addTarget and neither of them have specified why the background image of the button gets created as a subview of the button when the selector func gets called
There shouldn't be that extra UIImageView in my UIButton since I never added that
What you're seeing has nothing to do with your
selector
/@objc func
...Many UIKit classes do a lot of "under-the-hood" work.
In the case of
UIButton
, subviews are only added as-needed.For example, if this is all the code you execute:
The resulting button has Zero subviews.
If we do this:
The resulting button now has 1 subviews.
The resulting button now has 2 subviews.
The resulting button now has 3 subviews.
And now we have 4 subviews.
Apple strongly discourages messing with the internals of
UIButton
. You might be better off creating a view subclass that contains a button and any additional subviews, rather than your current approach.Worth Noting
viewDidLoad()
, those subviews will not be created untilviewDidLayoutSubviews
... or even until the button is actually rendered.Here is a quick example to demonstrate some of the resulting subview counts:
That code will create 5 buttons, with each successive button getting another subview - title, image, backgroundImage, addSubview - and the "Info Label" at the bottom will show the subviews count at each stage (as is often the case,
didLayoutSubviews()
is called more than once):