如何通过代码修改UIButton子类KeyButton的富文本颜色?
Great question—keeping styling logic encapsulated in your custom button subclass is a smart call for maintainability. Let’s break down a few practical ways to adjust the attributed text color directly within your KeyButton class, instead of handling it in your view controller.
Context from Your Code
First, here’s the view controller code you’re currently using to set up superscript text on your KeyButton:
func superScriptText(text: String, button: KeyButton, fontSize: Int) { let font:UIFont? = UIFont.systemFont(ofSize: 22, weight: UIFont.Weight.light) let fontSuper:UIFont? = UIFont(name: "Helvetica", size:CGFloat(fontSize)) let attString:NSMutableAttributedString = NSMutableAttributedString(string: text, attributes: [.font:font!]) attString.setAttributes([.font:fontSuper!,.baselineOffset:15], range: NSRange(location:1,length:1)) button.setAttributedTitle(attString, for: .normal) }
Solution Options
Option 1: Add a Reusable Color Update Method to KeyButton
Create a dedicated method in KeyButton that lets you update the attributed text color (either for the entire string or specific ranges). This keeps styling logic tied to the button where it belongs.
Add this to your KeyButton class:
class KeyButton: UIButton { // Your existing style setup code here (e.g., background, corner radius, etc.) func updateAttributedTextColor(_ color: UIColor, for state: UIControl.State = .normal) { guard let currentAttributedTitle = attributedTitle(for: state) else { return } // Make a mutable copy of the existing attributed string to modify let mutableAttString = NSMutableAttributedString(attributedString: currentAttributedTitle) // Apply color to the entire text mutableAttString.addAttribute( .foregroundColor, value: color, range: NSRange(location: 0, length: mutableAttString.length) ) // Optional: Target only the superscript part (like your range at location 1) // if mutableAttString.length > 1 { // mutableAttString.addAttribute( // .foregroundColor, // value: .gray, // range: NSRange(location: 1, length: 1) // ) // } setAttributedTitle(mutableAttString, for: state) } }
Then use it in your view controller after setting the initial superscript text:
superScriptText(text: "X²", button: myKeyButton, fontSize: 12) myKeyButton.updateAttributedTextColor(.blue) // Set your desired color here
Option 2: Override setAttributedTitle to Auto-Apply a Default Color
If you want your KeyButton to always apply a specific color to its attributed text (without extra method calls), override the setAttributedTitle(_:for:) method. This ensures every time the attributed title is set, your color is automatically applied.
Here’s how to implement it:
class KeyButton: UIButton { // Make this configurable if you want—even add @IBInspectable to set it in Interface Builder var defaultAttributedTextColor: UIColor = .black override func setAttributedTitle(_ title: NSAttributedString?, for state: UIControl.State) { guard let originalTitle = title else { super.setAttributedTitle(title, for: state) return } let mutableTitle = NSMutableAttributedString(attributedString: originalTitle) // Apply default color to the entire string mutableTitle.addAttribute( .foregroundColor, value: defaultAttributedTextColor, range: NSRange(location: 0, length: mutableTitle.length) ) // Optional: Set a different color for the superscript range // if mutableTitle.length > 1 { // mutableTitle.addAttribute( // .foregroundColor, // value: .darkGray, // range: NSRange(location: 1, length: 1) // ) // } super.setAttributedTitle(mutableTitle, for: state) } }
Now whenever you call button.setAttributedTitle(...) (like in your superScriptText function), the KeyButton will automatically apply your defaultAttributedTextColor to the text.
Option 3: Move Entire Attributed Text Logic into KeyButton
For full encapsulation, move the entire superscript text creation into KeyButton. This way, your view controller doesn’t need to handle any attributed string setup at all.
Add this to your KeyButton class:
class KeyButton: UIButton { func setSuperScriptText( _ text: String, superScriptFontSize: Int, mainTextColor: UIColor = .black, superScriptColor: UIColor? = nil ) { let mainFont = UIFont.systemFont(ofSize: 22, weight: .light) let superScriptFont = UIFont(name: "Helvetica", size: CGFloat(superScriptFontSize)) ?? mainFont // Create base attributed string with main font and color let mutableAttString = NSMutableAttributedString( string: text, attributes: [ .font: mainFont, .foregroundColor: mainTextColor ] ) // Apply superscript style and color (use main color if no superscript color is provided) let finalSuperScriptColor = superScriptColor ?? mainTextColor mutableAttString.setAttributes([ .font: superScriptFont, .baselineOffset: 15, .foregroundColor: finalSuperScriptColor ], range: NSRange(location: 1, length: 1)) setAttributedTitle(mutableAttString, for: .normal) } }
Then in your view controller, simply call:
myKeyButton.setSuperScriptText("X²", superScriptFontSize: 12, mainTextColor: .blue, superScriptColor: .gray)
内容的提问来源于stack exchange,提问作者Maihan Nijat

