将UILabel直接定位在另一个UILabel下方

时间:2013-04-04 09:59:05

标签: ios objective-c nsstring uilabel sizetofit

我添加了NSString根据正在读取的文本自动调整UILabel的大小(我有一个简单的应用程序显示引用,所以有些是几个字,有些是一对句子)。在quote标签下面,我还有一个author标签,(奇怪的是)有标签的作者。

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

enter image description here enter image description here

注意红色和蓝色框之间的差距(我使用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;
}

3 个答案:

答案 0 :(得分:1)

调整大小以适合两个标签后,计算其帧之间的距离并相应地更改它们:

[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时,引号标签框会根据其内容更改其高度。

<强>更新

鉴于评论中最近的发展,我认为你有三种可能性:

  • 调整空格大小,而不是仅调整单词,以便调整字符串 实际上正确地适合框架
  • 以某种方式访问​​UILabel的CTFramesetter以查看实际情况 框架,当所有的说完成时,相当于
  • 制作自己的UIView子类,用于处理其中的Core Text绘图 绘制rect方法(在你的情况下应该很容易),毕竟你 正试图给UILabel一个不适合
  • 的行为

答案 1 :(得分: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];

答案 2 :(得分:0)

我最终使用单个UILabel和CoreText NSAttributedString来解决问题。一种警察,但它的确有效。