Ran*_*all 97 iphone truncate objective-c uilabel ios
我有一个UILabel
依赖于我的应用程序是否被纵向或横向模式下运行在iPhone或iPad,可以长短不一.当文本太长而无法在一行显示并且它被截断时,我希望用户能够按下它并获得全文的弹出窗口.
如何查看是否UILabel
截断文本?它甚至可能吗?现在我只是根据我所处的模式检查不同长度,但它不能很好地工作.
pro*_*rmr 102
您可以计算字符串的宽度,并查看宽度是否大于label.bounds.size.width
NSString UIKit Additions有几种方法可以用特定字体计算字符串的大小.但是,如果您的标签有minimumFontSize,则允许系统将文本缩小到该大小.您可能想要使用sizeWithFont:minFontSize:actualFontSize:forWidth:lineBreakMode:在这种情况下.
CGSize size = [label.text sizeWithAttributes:@{NSFontAttributeName:label.font}];
if (size.width > label.bounds.size.width) {
...
}
Run Code Online (Sandbox Code Playgroud)
小智 78
Swift(作为扩展) - 适用于多行uilabel:
swift4 :( 略有变化的attributes
param boundingRect
)
extension UILabel {
var isTruncated: Bool {
guard let labelText = text else {
return false
}
let labelTextSize = (labelText as NSString).boundingRect(
with: CGSize(width: frame.size.width, height: .greatestFiniteMagnitude),
options: .usesLineFragmentOrigin,
attributes: [.font: font],
context: nil).size
return labelTextSize.height > bounds.size.height
}
}
Run Code Online (Sandbox Code Playgroud)
swift3:
extension UILabel {
var isTruncated: Bool {
guard let labelText = text else {
return false
}
let labelTextSize = (labelText as NSString).boundingRect(
with: CGSize(width: frame.size.width, height: .greatestFiniteMagnitude),
options: .usesLineFragmentOrigin,
attributes: [NSFontAttributeName: font],
context: nil).size
return labelTextSize.height > bounds.size.height
}
}
Run Code Online (Sandbox Code Playgroud)
swift2:
extension UILabel {
func isTruncated() -> Bool {
if let string = self.text {
let size: CGSize = (string as NSString).boundingRectWithSize(
CGSize(width: self.frame.size.width, height: CGFloat(FLT_MAX)),
options: NSStringDrawingOptions.UsesLineFragmentOrigin,
attributes: [NSFontAttributeName: self.font],
context: nil).size
if (size.height > self.bounds.size.height) {
return true
}
}
return false
}
}
Run Code Online (Sandbox Code Playgroud)
Mar*_*tin 19
编辑:我刚刚看到我的回答被upvoted,但我给出的代码片段已被弃用.
现在最好的方法是(ARC):
NSMutableParagraphStyle *paragraph = [[NSMutableParagraphStyle alloc] init];
paragraph.lineBreakMode = mylabel.lineBreakMode;
NSDictionary *attributes = @{NSFontAttributeName : mylabel.font,
NSParagraphStyleAttributeName : paragraph};
CGSize constrainedSize = CGSizeMake(mylabel.bounds.size.width, NSIntegerMax);
CGRect rect = [mylabel.text boundingRectWithSize:constrainedSize
options:(NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading)
attributes:attributes context:nil];
if (rect.size.height > mylabel.bounds.size.height) {
NSLog(@"TOO MUCH");
}
Run Code Online (Sandbox Code Playgroud)
请注意,计算的大小不是整数值.因此,如果你这样做int height = rect.size.height
,你将失去一些浮点精度,可能会有错误的结果.
旧答案(不建议使用):
如果您的标签是多行的,则可以使用以下代码:
CGSize perfectSize = [mylabel.text sizeWithFont:mylabel.font constrainedToSize:CGSizeMake(mylabel.bounds.size.width, NSIntegerMax) lineBreakMode:mylabel.lineBreakMode];
if (perfectSize.height > mylabel.bounds.size.height) {
NSLog(@"TOO MUCH");
}
Run Code Online (Sandbox Code Playgroud)
Adr*_*ian 19
似乎intrinsicContentSize
可以完成带有attributedText
和设置文本的标签的工作text
。考虑到这一点,我认为我们可以安全地放弃所有边界框簿记并简化如下:
斯威夫特 5.x
extension UILabel {
var isTruncated: Bool {
frame.width < intrinsicContentSize.width
}
var isClipped: Bool {
frame.height < intrinsicContentSize.height
}
}
Run Code Online (Sandbox Code Playgroud)
Don*_*gXu 13
你可以用UILabel制作一个类别
- (BOOL)isTextTruncated
{
CGRect testBounds = self.bounds;
testBounds.size.height = NSIntegerMax;
CGRect limitActual = [self textRectForBounds:[self bounds] limitedToNumberOfLines:self.numberOfLines];
CGRect limitTest = [self textRectForBounds:testBounds limitedToNumberOfLines:self.numberOfLines + 1];
return limitTest.size.height>limitActual.size.height;
}
Run Code Online (Sandbox Code Playgroud)
使用此类别查找是否在iOS 7及更高版本上截断标签.
// UILabel+Truncation.h
@interface UILabel (Truncation)
@property (nonatomic, readonly) BOOL isTruncated;
@end
// UILabel+Truncation.m
@implementation UILabel (Truncation)
- (BOOL)isTruncated
{
CGSize sizeOfText =
[self.text boundingRectWithSize:CGSizeMake(self.bounds.size.width, CGFLOAT_MAX)
options:(NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading)
attributes:@{ NSFontAttributeName : label.font }
context: nil].size;
if (self.frame.size.height < ceilf(sizeOfText.height))
{
return YES;
}
return NO;
}
@end
Run Code Online (Sandbox Code Playgroud)
要添加到iDev的答案,您应该使用intrinsicContentSize
而不是frame
,使其适用于Autolayout
- (BOOL)isTruncated:(UILabel *)label{
CGSize sizeOfText = [label.text boundingRectWithSize: CGSizeMake(label.intrinsicContentSize.width, CGFLOAT_MAX)
options: (NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading)
attributes: [NSDictionary dictionaryWithObject:label.font forKey:NSFontAttributeName] context: nil].size;
if (self.intrinsicContentSize.height < ceilf(sizeOfText.height)) {
return YES;
}
return NO;
}
Run Code Online (Sandbox Code Playgroud)
斯威夫特3
您可以在分配字符串后计算行数,并与标签的最大行数进行比较.
import Foundation
import UIKit
extension UILabel {
func countLabelLines() -> Int {
// Call self.layoutIfNeeded() if your view is uses auto layout
let myText = self.text! as NSString
let attributes = [NSFontAttributeName : self.font]
let labelSize = myText.boundingRect(with: CGSize(width: self.bounds.width, height: CGFloat.greatestFiniteMagnitude), options: NSStringDrawingOptions.usesLineFragmentOrigin, attributes: attributes, context: nil)
return Int(ceil(CGFloat(labelSize.height) / self.font.lineHeight))
}
func isTruncated() -> Bool {
if (self.countLabelLines() > self.numberOfLines) {
return true
}
return false
}
}
Run Code Online (Sandbox Code Playgroud)
就是这个。这与配合使用attributedText
,然后又回到朴素text
,这对于处理多个字体系列,大小甚至NSTextAttachments的我们来说非常有意义。
使用autolayout可以很好地工作,但是显然在检查之前必须定义和设置约束isTruncated
,否则标签本身甚至不知道如何进行布局,因此甚至也无法知道其是否被截断。
它不工作,只是一个普通的来处理这个问题NSString
和sizeThatFits
。我不确定人们是如何取得积极成果的。正如无数次提到的那样,BTW sizeThatFits
根本不是理想的选择,因为它考虑到numberOfLines
了生成的大小,这违背了我们试图做的全部目的,因为无论其是否被截断,它isTruncated
总是会返回false
。
extension UILabel {
var isTruncated: Bool {
layoutIfNeeded()
let rectBounds = CGSize(width: bounds.width, height: .greatestFiniteMagnitude)
var fullTextHeight: CGFloat?
if attributedText != nil {
fullTextHeight = attributedText?.boundingRect(with: rectBounds, options: .usesLineFragmentOrigin, context: nil).size.height
} else {
fullTextHeight = text?.boundingRect(with: rectBounds, options: .usesLineFragmentOrigin, attributes: [NSAttributedString.Key.font: font], context: nil).size.height
}
return (fullTextHeight ?? 0) > bounds.size.height
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
46160 次 |
最近记录: |