【问题标题】:Different width of the first line of the label iOS标签iOS首行宽度不同
【发布时间】:2015-11-10 01:20:03
【问题描述】:

我想将标签第一行的宽度设置为小于其余行的宽度。

如图所示 - 由于日期的原因,它需要更短。 我该怎么做?

【问题讨论】:

  • 您可以使用 NSMutableAttributedString 设置不同的字体大小。
  • 似乎人们可能会误会您的意思。您是在寻找“不同的字体大小”还是“不同的行长”?
  • @ULazdins 不同的行长

标签: ios objective-c autolayout label width


【解决方案1】:

为此,您必须使用 NSAttributedString。

NSMutableAttributedString *myAttributedString = [[NSMutableAttributedString alloc] initWithString:@"This is my text bla bla bla bla bla!"];
[myAttributedString addAttribute:NSFontAttributeName
          value:[UIFont systemFontOfSize:14.0]
          range:NSMakeRange(startingpoint, length)];

这是一种您可以指定第一行(静态长度假设为 20 个字符)为 14 号字体大小,其余为更大大小的方法。

模拟类似的函数来为字符串的其余部分创建另一个属性字符串。 现在合并这 2 个属性字符串以形成一个属性字符串。和写 myLabel.attributedText = myTotalAttributedText

或者你可以通过这个核心文本教程,通过它你可以获得同样想要的效果Link

【讨论】:

  • 好吧,OP 不想在同一文本中包含(较小的)时间刺,而只是排除这个区域。
  • 是的,我回答了,请记住,属性测试第一部分没有日期,第二部分也是如此..
【解决方案2】:

假设您的目标是 iOS7 或更高版本,您可以使用 TextKit 引入的非常方便的排除路径。

NSTextContainer(可通过UITextViewtextContainer 属性访问)提供了一个exclusionPaths 属性,您可以将其设置为一个或多个UIBezierPaths,代表文本应该在其中流动的区域。

因此,首先您需要确定您不想在其中看到任何文本的矩形(在您的情况下,我猜是时间标签 + 一些填充)。注意,我们在文本视图的坐标系中需要这个矩形,所以你可能需要转换,例如:

CGRect timeLabelRect = [self.timeLabel convertRect:self.timeLabel.bounds toView:self.textView];
CGRect exclusionRect = CGRectInset(timeLabelRect, -10.f, -10.f); // add padding

一旦我们有了这个矩形,只需从它创建一个路径并将其设置为文本视图的文本容器上的(唯一)排除路径:

UIBezierPath *path = [UIBezierPath bezierPathWithRect:exclusionRect];
self.textView.textContainer.exclusionPaths = @[path];

就是这样!


Swift 中的完整示例(因为我从 Playground 复制/粘贴了它):

// just a plain container view
var container = UIView(frame: CGRect(x: 0, y: 0, width: 300, height: 400))

// the text view
var textView = UITextView(frame: CGRect(x: 0, y: 100, width: 300, height: 300))
textView.text = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet."
container.addSubview(textView)

// a box (representing the time label in your case)
var blueBox = UIView(frame: CGRect(x: 250, y: 100, width: 50, height: 50))
blueBox.backgroundColor = .blueColor()
container.addSubview(blueBox)

此时它看起来像这样:

现在,让我们简单地添加排除路径:

// configure exclusion path
let blueBoxRect = textView.convertRect(blueBox.bounds, fromView: blueBox)
let path = UIBezierPath(rect: blueBoxRect)
textView.textContainer.exclusionPaths = [path]

添加排除路径后是这样的:

【讨论】:

  • 我刚刚用示例代码更新了答案,包括 Swift 中的完整工作示例(从操场复制/粘贴)
  • 啊,我可能需要指出,UILabel 上没有所有好的 TextKit 内容。但是,您应该能够通过将editableselectable 设置为NO 来交替使用UITextView 进行纯显示。
【解决方案3】:
UILabel *labelDate = [[UILabel alloc]initWithFrame:CGRectMake(_textView1.frame.size.width-100, 0, 100, 30)];
labelDate.text = @"4:32 PM";
[_textView1 addSubview:labelDate];//just added a sample label

将'\n'放在第一行的代码

int firstlineWidth = _textView1.frame.size.width - labelDate.frame.size.width;
int eachCharWidthSum = 0;
NSMutableString *stringToShow = [[NSMutableString alloc]init];
stringToShow = [_textView1.text mutableCopy];
int previousSpaceCharIndex = 0;
int initialPreviousSpaceCharIndex = 0;
BOOL isNeedNextSpace = NO;
for (int i =0; i<_textView1.text.length; i++)
{
   unichar charf = [_textView1.text characterAtIndex:i];
    NSString *eachString = [NSString stringWithFormat:@"%c",charf];
    CGSize stringSize = [eachString sizeWithFont:_textView1.font];
    eachCharWidthSum += stringSize.width;
    if ([eachString isEqualToString:@" "])
    {
        previousSpaceCharIndex = i;
    }
    int differance =  i - previousSpaceCharIndex;
    if (firstlineWidth<eachCharWidthSum&&differance<10)
    {
        [stringToShow insertString:@"\n" atIndex:previousSpaceCharIndex];
        break;
    }
    else if (firstlineWidth<eachCharWidthSum&&differance>10&&isNeedNextSpace==NO)
    {
        isNeedNextSpace = YES;
        initialPreviousSpaceCharIndex = previousSpaceCharIndex;
    }
    else if (isNeedNextSpace&&initialPreviousSpaceCharIndex!=previousSpaceCharIndex)
    {
        /*
         found new space char
         */
        [stringToShow insertString:@"\n" atIndex:previousSpaceCharIndex];
        break;
    }
}
_textView1.text = stringToShow;

【讨论】:

  • 这会增加每个单独字符的长度,并且不考虑任何间距/字距调整。最好测试整个子字符串到当前位置的长度。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-04-02
  • 1970-01-01
  • 2014-11-04
  • 1970-01-01
  • 2012-05-12
  • 1970-01-01
  • 2012-06-04
相关资源
最近更新 更多