我正在尝试创建一个消息传递应用程序,并且遇到了一个非常奇怪的问题。
之所以在“Thomas”和文本气泡底部之间留出很大空间是因为UILabel
正在创建另一行。目前,我正在使用attributedText
属性设置标签的文本,并以NSMutableParagraphStyle
的line spacing
传递8
。如果我将line spacing
设置为0
,则“Thomas”和文本气泡底部之间的空间将消失,如下所示:
这是奇怪的地方。如果将段落line spacing
设置回8
,并向该行添加了几个字符,则会出现文本气泡,而没有多余的行:
非常感谢所有帮助:)
这是我的代码:
class MessageTableViewCell: UITableViewCell {
var didSetupConstraints = false
var thumbnail = UIImageView.newAutoLayoutView()
let messageTailIcon = UIImageView.newAutoLayoutView()
var messageView = UIView.newAutoLayoutView()
var messageLabel = UILabel.newAutoLayoutView()
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
setupViews()
}
required init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func setupViews() {
thumbnail.image = UIImage(named: "ThomasBaldwin")
thumbnail.layer.cornerRadius = 17.5
thumbnail.clipsToBounds = true
messageTailIcon.image = UIImage(named: "MessageTailIcon")
messageView.backgroundColor = Application.greyColor
messageView.layer.cornerRadius = 10
let paragraphStyle = NSMutableParagraphStyle.new()
paragraphStyle.lineSpacing = 8
messageLabel.numberOfLines = 0
messageLabel.layer.cornerRadius = 10
messageLabel.attributedText = NSMutableAttributedString(
string: "Thomas says hello",
attributes: [
NSFontAttributeName: UIFont(name: "AvenirNextLTPro-Regular", size: 12.5)!,
NSForegroundColorAttributeName: UIColor.colorFromCode(0x262626),
NSBackgroundColorAttributeName: Application.greyColor,
NSKernAttributeName: 0.5,
NSParagraphStyleAttributeName: paragraphStyle
]
)
contentView.addSubview(thumbnail)
contentView.addSubview(messageView)
messageView.addSubview(messageTailIcon)
messageView.addSubview(messageLabel)
updateConstraints()
}
override func updateConstraints() {
if !didSetupConstraints {
thumbnail.autoPinEdgeToSuperviewEdge(.Top, withInset: 15)
thumbnail.autoPinEdgeToSuperviewEdge(.Leading, withInset: 8.5)
thumbnail.autoSetDimensionsToSize(CGSize(width: 35, height: 35))
messageView.autoPinEdgeToSuperviewEdge(.Top, withInset: 17.5)
messageView.autoPinEdge(.Leading, toEdge: .Trailing, ofView: thumbnail, withOffset: 10)
messageView.autoPinEdgeToSuperviewEdge(.Trailing, withInset: 24.5)
messageView.autoPinEdgeToSuperviewEdge(.Bottom)
messageTailIcon.autoPinEdgeToSuperviewEdge(.Top, withInset: 15)
messageTailIcon.autoPinEdgeToSuperviewEdge(.Leading, withInset: -10)
messageTailIcon.autoSetDimensionsToSize(CGSize(width: 18, height: 9))
messageLabel.autoPinEdgesToSuperviewEdgesWithInsets(UIEdgeInsets(top: 8.5, left: 10, bottom: 8.5, right: 5), excludingEdge: .Trailing)
messageLabel.autoPinEdgeToSuperviewEdge(.Trailing, withInset: 0, relation: .GreaterThanOrEqual)
didSetupConstraints = true
}
super.updateConstraints()
}
}
如果您想查看一个演示该问题的示例项目,我已将其推送到github
最佳答案
好的,所以最终锁定并给出简单答案,这仅与您的KERNING属性有关。看这个:
也不要理会红色单元格的大小,在应用程序中不会发生这种情况,这只是我的屏幕截图大小不同的产物,但是请自己尝试一下。注释掉字距调整并重新应用它,您将看到相同的内容
,与“Thomas”进行字距调整
,而不用“Thomas”字距调整
,与“托马斯说你好”的字距调整
,不与“Thomas说你好”字距紧调
我已经做了一切可能的检查代码,使用不同的约束的方法,甚至还使用了NSAttributedString的所有选项,唯一改变这种不良行为的是字距调整属性,它对所有类型的字体都执行了此操作,而不仅仅是Avenir。实际上,在此示例中使用的字体是根本不设置字体的系统字体,但是我现在尝试使用3种字体,效果相同,字距调整似乎已损坏或按预期工作对于Swift和/或ObjC,但我认为这实际上是一个错误。
大多数NSAttributedString选项,如果您想弄乱的东西: var myString1 = NSMutableAttributedString(string:"Thomas asdfadsf asdfasdfasdf asdfasdf asdfasdf \n asdfasdf asdf \n")
let myString1Font1 = UIFont.systemFontOfSize(12.0)
let originalNSString = myString1.string as NSString
let myString1Range1 = originalNSString.rangeOfString(myString1.string)
var myString1ParaStyle1 = NSMutableParagraphStyle()
myString1ParaStyle1.alignment = NSTextAlignment.Natural
myString1ParaStyle1.baseWritingDirection = NSWritingDirection.Natural
myString1ParaStyle1.defaultTabInterval = 0.0
myString1ParaStyle1.firstLineHeadIndent = 0.0
myString1ParaStyle1.headIndent = 0.0
myString1ParaStyle1.hyphenationFactor = 0.0
myString1ParaStyle1.lineBreakMode = NSLineBreakMode.ByWordWrapping
myString1ParaStyle1.lineHeightMultiple = 0.0
myString1ParaStyle1.lineSpacing = 8.0
myString1ParaStyle1.maximumLineHeight = 0.0
myString1ParaStyle1.minimumLineHeight = 0.0
myString1ParaStyle1.paragraphSpacing = 0.0
myString1ParaStyle1.paragraphSpacingBefore = 0.0
myString1ParaStyle1.tailIndent = 0.0
myString1.addAttribute(NSKernAttributeName, value:0.5, range:myString1Range1)
myString1.addAttribute(NSFontAttributeName, value:myString1Font1, range:myString1Range1)
myString1.addAttribute(NSParagraphStyleAttributeName, value:myString1ParaStyle1, range:myString1Range1)
myString1.addAttribute(NSBackgroundColorAttributeName, value:UIColor.redColor(), range:myString1Range1)
myString1.addAttribute(NSForegroundColorAttributeName, value:UIColor.blackColor(), range:myString1Range1)
再说一次,这不是一个约束问题,我错了,这只是一个核心问题,这很糟糕,但这就是生活,也许这需要向雷达报告。
另外,您可以自己尝试一下,但是如果使用0或0.00000或任意多个零值,则使用Kerning都会产生错误的结果,我尝试过此操作,并且使您的标签字段弄乱了,就像字距调整会弄乱字段一样具有较大的值: NSKernAttributeName: 0.00000000000001
按住,我从外观上解决了它,设置该值,只需将其添加到示例项目中设置的段落样式变量中,即可使用字距调整功能,不确定是否适用于所有字体,但是它至少可以修复示例项目:paragraphStyle.lineHeightMultiple = 1.5
这种方法的唯一问题是,它适用于一个单词或一行的行,您必须进行字数调整才能根据出现新行的时间来设置此“lineHeightMultiple”,这很糟糕,但它可以工作,显然,这不是一个很好的方法,但是如果您有1个衬线,则可以使用,如果有更多衬线,则需要进行调整,否则请关闭字距调整,并且在没有此线高倍数的情况下都可以解决。
好像行高在内部改变并将字符推到新行,但是apple并不能自动考虑字符宽度的这种变化。
事实上,我认为您正在寻找的答案根本不是字距,而是跟踪,这会使字母彼此分开。字距调整的问题是,字距调整会紧紧字体的字形并覆盖其某些行为,因此,这可能是一种可反感的效果,就像我们在此处看到的那样。
从苹果公司:
https://developer.apple.com/library/ios/documentation/StringsTextFonts/Conceptual/TextAndWebiPhoneOS/TypoFeatures/TextSystemFeatures.html
如果确实需要字距调整,那么如果字体有任何可用的字体,则可能应该调整连字的字距调整值。
需要考虑的其他事情,这确实可行,但是它也大胆,因此已经不是您上面的样式所能匹配的东西,但是您可以通过以下方式玩弄:let sytemDynamicFontDescriptor = UIFontDescriptor.preferredFontDescriptorWithTextStyle(UIFontTextStyleHeadline)
let size = sytemDynamicFontDescriptor.pointSize
let myString1Font1 = UIFont(descriptor: sytemDynamicFontDescriptor, size:size)
println(sytemDynamicFontDescriptor.fontAttributes())
messageLabel.numberOfLines = 0
messageLabel.layer.cornerRadius = 10
messageLabel.attributedText = NSMutableAttributedString(
string: "Thomas asdfad as ",
// string: "Thomas says hello", // switch back to this to see it display the text properly on one
attributes: [
NSFontAttributeName: myString1Font1,
NSForegroundColorAttributeName: UIColor.blackColor(),
NSBackgroundColorAttributeName: UIColor.redColor(),
NSKernAttributeName: 0.5,
NSParagraphStyleAttributeName: paragraphStyle
]
)