问题
Let me start off by saying I am aware that this is a frequently asked question, I just can't seem to find someone with the same scenario/problem as me.
I am writing a music application, and I came up with a UI that I liked. It required a button with special functionality (past what can be achieved by the Custom Button type) so I decided to make a UIButton subclass. I used the following code in my subclass:
required init(coder aDecoder: NSCoder) {
self.activeState = false
self.activeAccidental = UIImageView()
super.init(coder: aDecoder)
self.layer.borderColor = UIColor(white:221/255, alpha: 1.0).CGColor
self.layer.borderWidth = 2.0
self.backgroundColor = UIColor.blackColor()
self.setTitleColor(UIColor.whiteColor(), forState: .Normal)
self.setTitle("Hello", forState: .Normal)
}
override func layoutSubviews() {
println(self.frame.origin.x)
self.activeAccidental = UIImageView(frame: CGRectMake(self.bounds.origin.x, self.bounds.origin.y, 20, 20))
self.activeAccidental.image = UIImage(named: "BMICalcIcon.png")
self.addSubview(activeAccidental)
}
However, when I add a button to my storyboard (and enter the custom class name in the field) my title, regardless if set in the initializer as shown, or in the attributes inspector in the storyboard, is not visible. This is my first major project in swift, so I am not sure entirely what the problem is.
Code when ImageView moved to initWithCoder
required init(coder aDecoder: NSCoder) {
self.activeState = false
self.activeAccidental = UIImageView()
super.init(coder: aDecoder)
self.activeAccidental = UIImageView(frame: CGRectMake(self.bounds.origin.x, self.bounds.origin.y, 20, 20))
self.activeAccidental.image = UIImage(named: "BMICalcIcon.png")
self.layer.borderColor = UIColor(white:221/255, alpha: 1.0).CGColor
self.layer.borderWidth = 2.0
self.backgroundColor = UIColor.blackColor()
self.setTitleColor(UIColor.whiteColor(), forState: .Normal)
self.setTitle("Hello", forState: .Normal)
self.addSubview(activeAccidental)
}
回答1:
I'm not sure why, but the problem is putting the code for adding the image view in layoutSubviews -- that's not a good place anyway, since it can be called multiple times, which will cause you to add multiple image views. If you move that code into your initWithCoder method, it will work properly. Here's the test class I made,
import UIKit
class RDButton: UIButton {
var activeState: Bool
var activeAccidental: UIImageView
required init(coder aDecoder: NSCoder) {
self.activeState = false
self.activeAccidental = UIImageView()
super.init(coder: aDecoder)
self.activeAccidental = UIImageView(frame: CGRectMake(self.bounds.origin.x, self.bounds.origin.y, 20, 20))
self.activeAccidental.image = UIImage(named: "img.jpg")
self.layer.borderColor = UIColor(white:221/255, alpha: 1.0).CGColor
self.layer.borderWidth = 2.0
self.backgroundColor = UIColor.blackColor()
self.setTitleColor(UIColor.whiteColor(), forState: .Normal)
self.setTitle("Hello", forState: .Normal)
self.addSubview(activeAccidental)
}
}
回答2:
Maybe add [super layoutSubviews];
I had the same problem because I forgot to add this piece of line. After that you can add the code you want.
回答3:
This also happens when the current view controller (containing the custom button) was started with performSegue(withIdentifier:sender:) from a queue other than the main. To fix this, just call the method within main thread. For example:
class MyViewController: ViewController {
...
func doTask() {
let myTask = MyTask()
myTask.perform( {
Dispatch.main.async {
self.performSegue(withIdentifier: "second", sender: nil)
}
})
}
}
来源:https://stackoverflow.com/questions/26857994/custom-uibutton-subclass-not-displaying-title