UIButton上的iOS NSAttributedString
我使用的是iOS 6 ,所以属性string应该很容易使用,对吧? 那么…不是那么多。
我想做的事:
使用UIButton
的自定义子类(它不会做任何自定义titleLabel
),我想有一个多行,归因的标题是:
- 所有大写(我意识到这不是属性的一部分)在第一行
- 在第一行粘贴
- 在第一行加下划线
- 第二行的“正常”重量
- 第二行没有下划线
- 以两条线为中心
到目前为止,我已经能够获得#1至5(至less,我以为我做了,但是目前的testing正在产生多行文本的错误),但是当我试图做某件事(任何事情!文字要居中,我的应用程序不断崩溃。 当我试图让所有6个项目(通过各种方法)工作,我得到以下崩溃/错误:
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'NSAttributedString invalid for autoresizing, it must have a single spanning paragraph style (or none) with a non-wrapping lineBreakMode.'
根据我所尝试的,似乎我可以有以下选项之一,但不能同时使用这两个选项:
- 多线,居中的标签
- 归属标签
如果必须的话 ,我可以和其中一个人住在一起,但我不能相信我不能有一个相当直接的概念。
有人可以告诉我我错了什么吗?
这是我正在尝试的代码的最后一个迭代:
NSMutableParagraphStyle *style = [[NSParagraphStyle defaultParagraphStyle] mutableCopy]; [style setAlignment:NSTextAlignmentCenter]; [style setLineBreakMode:NSLineBreakByWordWrapping]; UIFont *font1 = [UIFont fontWithName:@"HelveticaNeue-Medium" size:20.0f]; UIFont *font2 = [UIFont fontWithName:@"HelveticaNeue-Light" size:20.0f]; NSDictionary *dict1 = @{NSUnderlineStyleAttributeName:@(NSUnderlineStyleSingle), NSFontAttributeName:font1}; NSDictionary *dict2 = @{NSUnderlineStyleAttributeName:@(NSUnderlineStyleNone), NSFontAttributeName:font2}; NSMutableAttributedString *attString = [[NSMutableAttributedString alloc] init]; [attString appendAttributedString:[[NSAttributedString alloc] initWithString:@"LINE 1\n" attributes:dict1]]; [attString appendAttributedString:[[NSAttributedString alloc] initWithString:@"line 2" attributes:dict2]]; [[self buttonToStyle] setAttributedTitle:attString forState:UIControlStateNormal]; [[[self buttonToStyle] titleLabel] setNumberOfLines:0]; [[[self buttonToStyle] titleLabel] setLineBreakMode:NSLineBreakByWordWrapping];
它看起来像你忘记了在你的代码中使用你设置的“样式”对象..你刚刚实例化它。 你应该修改你的代码如下所示:
NSMutableParagraphStyle *style = [[NSParagraphStyle defaultParagraphStyle] mutableCopy]; [style setAlignment:NSTextAlignmentCenter]; [style setLineBreakMode:NSLineBreakByWordWrapping]; UIFont *font1 = [UIFont fontWithName:@"HelveticaNeue-Medium" size:20.0f]; UIFont *font2 = [UIFont fontWithName:@"HelveticaNeue-Light" size:20.0f]; NSDictionary *dict1 = @{NSUnderlineStyleAttributeName:@(NSUnderlineStyleSingle), NSFontAttributeName:font1, NSParagraphStyleAttributeName:style}; // Added line NSDictionary *dict2 = @{NSUnderlineStyleAttributeName:@(NSUnderlineStyleNone), NSFontAttributeName:font2, NSParagraphStyleAttributeName:style}; // Added line NSMutableAttributedString *attString = [[NSMutableAttributedString alloc] init]; [attString appendAttributedString:[[NSAttributedString alloc] initWithString:@"LINE 1\n" attributes:dict1]]; [attString appendAttributedString:[[NSAttributedString alloc] initWithString:@"line 2" attributes:dict2]]; [self.resolveButton setAttributedTitle:attString forState:UIControlStateNormal]; [[self.resolveButton titleLabel] setNumberOfLines:0]; [[self.resolveButton titleLabel] setLineBreakMode:NSLineBreakByWordWrapping];
请注意,我只添加了定义NSParagraphStyleAttributeName的行。其他一切都是一样的..这就是我得到的button:
这里是在Swift 3.0中
let style = NSMutableParagraphStyle() style.alignment = .center style.lineBreakMode = .byWordWrapping guard let font1 = UIFont(name: "HelveticaNeue-Medium", size: 20), let font2 = UIFont(name: "HelveticaNeue-Light", size: 20) else { return } let dict1:[String:Any] = [ NSUnderlineStyleAttributeName:NSUnderlineStyle.styleSingle.rawValue, NSFontAttributeName:font1, NSParagraphStyleAttributeName:style ] let dict2:[String:Any] = [ NSUnderlineStyleAttributeName:NSUnderlineStyle.styleNone.rawValue, NSFontAttributeName:font2, NSParagraphStyleAttributeName:style ] let attString = NSMutableAttributedString() attString.append(NSAttributedString(string: "LINE 1", attributes: dict1)) attString.append(NSAttributedString(string: "line 2", attributes: dict2)) button.setAttributedTitle(attString, for: .normal) button.titleLabel?.numberOfLines = 0 button.titleLabel?.lineBreakMode = .byWordWrapping
使用Swift 4,您可以使用下面的UIButton
子类实现来解决您的问题:
import UIKit class CustomButton: UIButton { required init(title: String, subtitle: String) { super.init(frame: CGRect.zero) let style = NSMutableParagraphStyle() style.alignment = NSTextAlignment.center style.lineBreakMode = NSLineBreakMode.byWordWrapping let titleAttributes: [NSAttributedStringKey : Any] = [ NSAttributedStringKey.underlineStyle : NSUnderlineStyle.styleSingle.rawValue, NSAttributedStringKey.font : UIFont.preferredFont(forTextStyle: UIFontTextStyle.largeTitle), NSAttributedStringKey.paragraphStyle : style ] let subtitleAttributes = [ NSAttributedStringKey.font : UIFont.preferredFont(forTextStyle: UIFontTextStyle.body), NSAttributedStringKey.paragraphStyle : style ] let attributedString = NSMutableAttributedString(string: title, attributes: titleAttributes) attributedString.append(NSAttributedString(string: "\n")) attributedString.append(NSAttributedString(string: subtitle, attributes: subtitleAttributes)) setAttributedTitle(attributedString, for: UIControlState.normal) titleLabel?.numberOfLines = 0 titleLabel?.lineBreakMode = NSLineBreakMode.byWordWrapping } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } }
用法:
import UIKit class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() let button = CustomButton(title: "Title", subtitle: "Subtitle") button.translatesAutoresizingMaskIntoConstraints = false view.addSubview(button) let horizontalConstraint = button.centerXAnchor.constraint(equalTo: view.centerXAnchor) let verticalConstraint = button.centerYAnchor.constraint(equalTo: view.centerYAnchor) NSLayoutConstraint.activate([horizontalConstraint, verticalConstraint]) } }
作为替代scheme,如果您确实需要system
types的button,则可以使用以下代码:
import UIKit extension UIButton { static func customSystemButton(title: String, subtitle: String) -> UIButton { let style = NSMutableParagraphStyle() style.alignment = NSTextAlignment.center style.lineBreakMode = NSLineBreakMode.byWordWrapping let titleAttributes: [NSAttributedStringKey : Any] = [ NSAttributedStringKey.underlineStyle : NSUnderlineStyle.styleSingle.rawValue, NSAttributedStringKey.font : UIFont.preferredFont(forTextStyle: UIFontTextStyle.largeTitle), NSAttributedStringKey.paragraphStyle : style ] let subtitleAttributes = [ NSAttributedStringKey.font : UIFont.preferredFont(forTextStyle: UIFontTextStyle.body), NSAttributedStringKey.paragraphStyle : style ] let attributedString = NSMutableAttributedString(string: title, attributes: titleAttributes) attributedString.append(NSAttributedString(string: "\n")) attributedString.append(NSAttributedString(string: subtitle, attributes: subtitleAttributes)) let button = UIButton(type: UIButtonType.system) button.setAttributedTitle(attributedString, for: UIControlState.normal) button.titleLabel?.numberOfLines = 0 button.titleLabel?.lineBreakMode = NSLineBreakMode.byWordWrapping return button } }
用法:
import UIKit class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() let button = UIButton.customSystemButton(title: "Title", subtitle: "Subtitle") button.translatesAutoresizingMaskIntoConstraints = false view.addSubview(button) let horizontalConstraint = button.centerXAnchor.constraint(equalTo: view.centerXAnchor) let verticalConstraint = button.centerYAnchor.constraint(equalTo: view.centerYAnchor) NSLayoutConstraint.activate([horizontalConstraint, verticalConstraint]) } }
下面的两个屏幕截图显示了UIButton
子类(左侧)和system
typesbutton(右侧)的结果显示: