我正在尝试创建一个消息传递应用程序,但遇到了一个非常奇怪的问题。
“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 says hello”的字距调整
没有“Thomas says hello”的字距调整
我已尽一切可能检查代码,使用不同的约束,我什至尝试了 NSAttributedString 的所有选项,唯一改变这种不良行为的是 kerning 属性,它对所有人都这样做字体类型,而不仅仅是 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)
同样,这不是约束问题,我错了,这只是 KERNING 问题,这很糟糕,但这就是生活,也许这需要向 RADAR 报告。
此外,您可以自己尝试这个,除了 0 或 0.00000 或任意数量的零之外的任何东西都会在字距调整时产生错误的结果,我试过这个并且它会像字距调整一样打乱您的标签字段用更大的值向上字段:
NSKernAttributeName: 0.00000000000001
等等,我解决了它,从它的样子,设置这个值,只需将它添加到您在示例项目中设置的 paragraphStyle 变量,它与字距调整一起使用,不确定这是否适用于所有人字体,但它至少修复了您的示例项目:
paragraphStyle.lineHeightMultiple = 1.5
此方法的唯一问题是它适用于只有一个单词或一行的行,您必须根据新行出现的时间来调整字数来设置此“lineHeightMultiple”,这很糟糕,但是显然,这不是一个很好的使用方法,但如果你有 1 个衬里字符串,它就可以工作,如果你有更多,则需要调整,否则只需关闭字距调整,它会在没有这个行高倍数的情况下解决。
就好像行高在内部发生变化并将字符推到一个新行,但 apple 不会自动考虑字符宽度的这种变化。
事实上,我认为您正在寻找的答案根本不是字距调整,而是字距调整,字距调整会使字母彼此分开。字距调整的问题是字距调整会影响字体的字形并覆盖它们的某些行为,因此它可能会像我们在这里看到的那样产生明显的效果。
来自苹果:
preferredFontForTextStyle:, the specific font returned includes traits which vary according to user preferences and context, including tracking (letter-spacing) adjustments, in addition to being tuned for the use specified by the particular text style constant. The fonts returned using text style constants are meant to be used for all text in an app other than text in user interface elements, such as buttons, bars, and labels. Naturally, you need to choose text styles that look right in your app. It’s also important to observe the UIContentSizeCategoryDidChangeNotification so that you can re–lay out the text when the user changes the content size category. When your app receives that notification, it should send the invalidateIntrinsicContentSize message to views positioned by Auto Layout or send setNeedsLayout to user interface elements positioned manually. And it should invalidate preferred fonts or font descriptors and acquire new ones as needed.
如果您确实需要字距调整,那么您可能应该调整连字的字距调整值(如果字体有任何可用的)。
其他需要考虑的事情,这确实有效,但它也是粗体,所以它已经不符合你上面的风格,但它是你可以玩弄的东西:
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
]
)
关于ios - 具有段落样式行间距的 UILabel,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32216700/
我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..
我有一大串格式化数据(例如JSON),我想使用Psychinruby同时保留格式转储到YAML。基本上,我希望JSON使用literalstyle出现在YAML中:---json:|{"page":1,"results":["item","another"],"total_pages":0}但是,当我使用YAML.dump时,它不使用文字样式。我得到这样的东西:---json:!"{\n\"page\":1,\n\"results\":[\n\"item\",\"another\"\n],\n\"total_pages\":0\n}\n"我如何告诉Psych以想要的样式转储标量?解
我正在为一个项目制作一个简单的shell,我希望像在Bash中一样解析参数字符串。foobar"helloworld"fooz应该变成:["foo","bar","helloworld","fooz"]等等。到目前为止,我一直在使用CSV::parse_line,将列分隔符设置为""和.compact输出。问题是我现在必须选择是要支持单引号还是双引号。CSV不支持超过一个分隔符。Python有一个名为shlex的模块:>>>shlex.split("Test'helloworld'foo")['Test','helloworld','foo']>>>shlex.split('Test"
这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下
我正在尝试解析一个文本文件,该文件每行包含可变数量的单词和数字,如下所示:foo4.500bar3.001.33foobar如何读取由空格而不是换行符分隔的文件?有什么方法可以设置File("file.txt").foreach方法以使用空格而不是换行符作为分隔符? 最佳答案 接受的答案将slurp文件,这可能是大文本文件的问题。更好的解决方案是IO.foreach.它是惯用的,将按字符流式传输文件:File.foreach(filename,""){|string|putsstring}包含“thisisanexample”结果的
我正在使用Rails3.1并在一个论坛上工作。我有一个名为Topic的模型,每个模型都有许多Post。当用户创建新主题时,他们也应该创建第一个Post。但是,我不确定如何以相同的形式执行此操作。这是我的代码:classTopic:destroyaccepts_nested_attributes_for:postsvalidates_presence_of:titleendclassPost...但这似乎不起作用。有什么想法吗?谢谢! 最佳答案 @Pablo的回答似乎有你需要的一切。但更具体地说...首先改变你View中的这一行对此#
我有带有Logo图像的公司模型has_attached_file:logo我用他们的Logo创建了许多公司。现在,我需要添加新样式has_attached_file:logo,:styles=>{:small=>"30x15>",:medium=>"155x85>"}我是否应该重新上传所有旧数据以重新生成新样式?我不这么认为……或者有什么rake任务可以重新生成样式吗? 最佳答案 参见Thumbnail-Generation.如果rake任务不适合你,你应该能够在控制台中使用一个片段来调用重新处理!关于相关公司
1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里
我从用户Hirolau那里找到了这段代码:defsum_to_n?(a,n)a.combination(2).find{|x,y|x+y==n}enda=[1,2,3,4,5]sum_to_n?(a,9)#=>[4,5]sum_to_n?(a,11)#=>nil我如何知道何时可以将两个参数发送到预定义方法(如find)?我不清楚,因为有时它不起作用。这是重新定义的东西吗? 最佳答案 如果您查看Enumerable#find的文档,您会发现它只接受一个block参数。您可以将它发送两次的原因是因为Ruby可以方便地让您根据它的“并行赋
RSpec似乎按顺序匹配方法接收的消息。我不确定如何使以下代码工作:allow(a).toreceive(:f)expect(a).toreceive(:f).with(2)a.f(1)a.f(2)a.f(3)我问的原因是a.f的一些调用是由我的代码的上层控制的,所以我不能对这些方法调用添加期望。 最佳答案 RSpecspy是测试这种情况的一种方式。要监视一个方法,用allowstub,除了方法名称之外没有任何约束,调用该方法,然后expect确切的方法调用。例如:allow(a).toreceive(:f)a.f(2)a.f(1)