4

我有一个附加功能,NSString它会根据正在读入的文本自动调整 a的大小UILabel(我有一个简单的应用程序显示引文,所以有些是几个词,有些是几个句子)。在该标签下方quote,我还有一个author标签,其中(奇怪的是)其中包含引用的作者。

我试图将该author标签直接放置在标签下方quote(如,它的y坐标将是quote标签的y坐标加上quote标签的height。我看到的是两个标签之间放置了一些空间,这取决于报价的长度, 改变大小。较小的引号有更多的空间,而较长的引号有更少的空间。这是我所看到的快速图表:

在此处输入图像描述 在此处输入图像描述

请注意红色和蓝色框之间的差距(我已经使用它设置,layer.borderColor/borderWidth以便我可以在应用程序中看到它们),报价越短越大。

如果有人可以筛选下面的代码并帮助我指出导致差异的确切原因,我将不胜感激。据我所知,author标签应始终比quote标签y + height值低 35 像素。

只是为了确认:一切都在 Interface Builder 中正确连接,等等。引用的内容很好,其他一切正常,所以它已经连接,这不是问题。

澄清一下,我的问题是:为什么标签之间的间隙会根据引用的长度而变化,我怎样才能正确获得稳定的、可设置的 35 像素间隙?

这是我用来定位标签的代码:

// Fill and format Quote Details
_quoteLabel.text = [NSString stringWithFormat:@"\"%@\"", _selectedQuote.quote];
_authorLabel.text = _selectedQuote.author;
[_quoteLabel setFont: [UIFont fontWithName: kScriptFont size: 28.0f]];
[_authorLabel setFont: [UIFont fontWithName: kScriptFontAuthor size: 30.0f]];

// Automatically resize the label, then center it again.
[_quoteLabel sizeToFitMultipleLines];
[_quoteLabel setFrame: CGRectMake(11, 11, 298, _quoteLabel.frame.size.height)];

// Position the author label below the quote label, however high it is.
[_authorLabel setFrame: CGRectMake(11, 11 + _quoteLabel.frame.size.height + 35, _authorLabel.frame.size.width, _authorLabel.frame.size.height)];

这是我的自定义方法sizeToFitMultipleLines

- (void) sizeToFitMultipleLines
{
    if (self.adjustsFontSizeToFitWidth) {
        CGFloat adjustedFontSize = [self.text fontSizeWithFont: self.font constrainedToSize: self.frame.size minimumFontSize: self.minimumScaleFactor];
        self.font = [self.font fontWithSize: adjustedFontSize];
    }
    [self sizeToFit];
}

这是我的fontSizeWithFont:constrainedToSize:minimumFontSize:方法:

- (CGFloat) fontSizeWithFont: (UIFont *) font constrainedToSize: (CGSize) size minimumFontSize: (CGFloat) minimumFontSize
{
    CGFloat fontSize = [font pointSize];
    CGFloat height = [self sizeWithFont: font constrainedToSize: CGSizeMake(size.width, FLT_MAX) lineBreakMode: NSLineBreakByWordWrapping].height;
    UIFont *newFont = font;

    // Reduce font size while too large, break if no height (empty string)
    while (height > size.height && height != 0 && fontSize > minimumFontSize) {
        fontSize--;
        newFont = [UIFont fontWithName: font.fontName size: fontSize];
        height = [self sizeWithFont: newFont constrainedToSize: CGSizeMake(size.width, FLT_MAX) lineBreakMode: NSLineBreakByWordWrapping].height;
    };

    // Loop through words in string and resize to fit
    for (NSString *word in [self componentsSeparatedByCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]]) {
        CGFloat width = [word sizeWithFont: newFont].width;
        while (width > size.width && width != 0 && fontSize > minimumFontSize) {
            fontSize--;
            newFont = [UIFont fontWithName: font.fontName size: fontSize];
            width = [word sizeWithFont: newFont].width;
        }
    }
    return fontSize;
}
4

3 回答 3

1

在调用 size 以适应两个标签后,计算它们的框架之间的距离并相应地更改它们:

[quoteLabel sizeToFit];
[authorLabel sizeToFit];

float distance = authorLabel.frame.origin.y - quoteLabel.frame.size.height;
float difference = distance - 35;

authorLabel.frame = CGRectMake(authorLabel.frame.origin.x,(authorLabel.frame.origin.y - difference),authorLabel.frame.size.width,authorLabel.frame.size.height);

间隙发生变化的原因是报价标签框架在调用 sizeToFit 时根据其内容改变其高度。

更新

鉴于评论的最新发展,我认为您有 3 种可能性:

  • 调整空格而不是单词的大小,以便字符串实际上正确地适合框架
  • 以某种方式访问​​ UILabel 的 CTFramesetter 以查看实际框架,当一切都说完之后,相当于
  • 创建自己的 UIView 子类,在其 draw rect 方法中处理核心文本绘图(在你的情况下应该很容易),因为毕竟你试图给 UILabel 一个它不适合的行为
于 2013-04-04T13:42:19.017 回答
1

它可能正在移动到您想要的位置,但随后自动布局约束或弹簧/支柱正在移动它。

编辑:
我的第一个想法(我排除了,因为你说单词周围的框是标签框。在后来的评论中,你说这不是实际的屏幕截图,而只是它的表示,所以它仍然可以是正确的)是你做错了:

[_quoteLabel sizeToFitMultipleLines];
[_quoteLabel setFrame: CGRectMake(11, 11, 298, _quoteLabel.frame.size.height)];

在第一行中,您正在调整文本的大小以适应标签的当前宽度,然后在第二行中转身并更改标签的宽度。所以最有可能发生的事情是您正在调整标签的宽度以使其变高。然后,您使标签比以前更宽,文本扩展以适应更宽的标签,在实际文本下方留下一个空白区域,尽管框架没有改变。这使得标签之间的空间正好为您想要的 35,但是顶部标签的文本并没有一直到其框架的底部,因此空白空间比您想要的要多。基本上,你有这个:

*************
* text text *
* text text *
*           *
*           *
*           *
*************

*************
* text text *
*************

如果是这种情况,那么您可以通过首先设置宽度来修复它,如下所示:

// You could put anything for the 200 height since you will be changing it in the next line anyway.
[_quoteLabel setFrame: CGRectMake(11, 11, 298, 200];  
[_quoteLabel sizeToFitMultipleLines];
于 2013-04-04T13:54:04.717 回答
0

我最终通过使用单个UILabel, 和 CoreText 和NSAttributedString. 有点逃避,但它有效。

于 2013-04-05T10:29:08.190 回答