在iOS 7中替换已弃用的sizeWithFont:

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在iOS 7中替换已弃用的sizeWithFont:相关的知识,希望对你有一定的参考价值。

ios 7中,sizeWithFont:现已弃用。我现在如何将UIFont对象传递给替换方法sizeWithAttributes:

答案

使用sizeWithAttributes:代替,现在需要NSDictionary。使用密钥UITextAttributeFont和您的字体对象传递对,如下所示:

CGSize size = [string sizeWithAttributes:
    @{NSFontAttributeName: [UIFont systemFontOfSize:17.0f]}];

// Values are fractional -- you should take the ceilf to get equivalent values
CGSize adjustedSize = CGSizeMake(ceilf(size.width), ceilf(size.height));
另一答案

在@bitsand的基础上,这是我刚刚添加到NSString + Extras类别的新方法:

- (CGRect) boundingRectWithFont:(UIFont *) font constrainedToSize:(CGSize) constraintSize lineBreakMode:(NSLineBreakMode) lineBreakMode;
{
    // set paragraph style
    NSMutableParagraphStyle *style = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
    [style setLineBreakMode:lineBreakMode];

    // make dictionary of attributes with paragraph style
    NSDictionary *sizeAttributes = @{NSFontAttributeName:font, NSParagraphStyleAttributeName: style};

    CGRect frame = [self boundingRectWithSize:constraintSize options:NSStringDrawingUsesLineFragmentOrigin attributes:sizeAttributes context:nil];

    /*
    // OLD
    CGSize stringSize = [self sizeWithFont:font
                              constrainedToSize:constraintSize
                                  lineBreakMode:lineBreakMode];
    // OLD
    */

    return frame;
}

我只是使用结果帧的大小。

另一答案

你仍然可以使用sizeWithFont。但是,在iOS> = 7.0中,如果字符串包含前导空格或尾随空格或结束行 ,则会导致崩溃。

在使用之前修剪文本

label.text = [label.text stringByTrimmingCharactersInSet:
             [NSCharacterSet whitespaceAndNewlineCharacterSet]];

这也适用于sizeWithAttributes[label sizeToFit]

此外,每当你在iOS 7.0设备上有nsstringdrawingtextstorage message sent to deallocated instance它就会处理这个问题。

另一答案

更好地使用自动尺寸(Swift):

  tableView.estimatedRowHeight = 68.0
  tableView.rowHeight = UITableViewAutomaticDimension

注意:1。UITableViewCell原型应该正确设计(对于实例不要忘记设置UILabel.numberOfLines = 0等)2。删除HeightForRowAtIndexPath方法

视频:https://youtu.be/Sz3XfCsSb6k

另一答案
boundingRectWithSize:options:attributes:context:
另一答案

Xamarin中的Accepted answer将是(使用sizeWithAttributes和UITextAttributeFont):

        UIStringAttributes attributes = new UIStringAttributes
        { 
            Font = UIFont.SystemFontOfSize(17) 
        }; 
        var size = text.GetSizeUsingAttributes(attributes);
另一答案
- (CGSize) sizeWithMyFont:(UIFont *)fontToUse
{
    if ([self respondsToSelector:@selector(sizeWithAttributes:)])
    {
        NSDictionary* attribs = @{NSFontAttributeName:fontToUse};
        return ([self sizeWithAttributes:attribs]);
    }
    return ([self sizeWithFont:fontToUse]);
}
另一答案

如果有人需要,这是单调相当的:

/// <summary>
/// Measures the height of the string for the given width.
/// </summary>
/// <param name="text">The text.</param>
/// <param name="font">The font.</param>
/// <param name="width">The width.</param>
/// <param name="padding">The padding.</param>
/// <returns></returns>
public static float MeasureStringHeightForWidth(this string text, UIFont font, float width, float padding = 20)
{
    NSAttributedString attributedString = new NSAttributedString(text, new UIStringAttributes() { Font = font });
    RectangleF rect = attributedString.GetBoundingRect(new SizeF(width, float.MaxValue), NSStringDrawingOptions.UsesLineFragmentOrigin, null);
    return rect.Height + padding;
}

可以像这样使用:

public override float GetHeightForRow(UITableView tableView, NSIndexPath indexPath)
{
    //Elements is a string array
    return Elements[indexPath.Row].MeasureStringHeightForWidth(UIFont.SystemFontOfSize(UIFont.LabelFontSize), tableView.Frame.Size.Width - 15 - 30 - 15);
}
另一答案
CGSize maximumLabelSize = CGSizeMake(label.frame.size.width, FLT_MAX);
CGSize expectedLabelSize = [label sizeThatFits:maximumLabelSize];
float heightUse = expectedLabelSize.height;
另一答案

试试这个语法:

NSAttributedString *attributedText =
    [[NSAttributedString alloc] initWithString:text 
                                    attributes:@{NSFontAttributeName: font}];
另一答案

作为@Ayush回答:

正如您在Apple Developer网站上看到的sizeWithFont一样,不推荐使用sizeWithAttributes

好吧,假设在2019+你可能使用Swift和String而不是Objective-c和NSString,这是正确的方法来获得具有预定义字体的String的大小:

let stringSize = NSString(string: label.text!).size(withAttributes: [.font : UIFont(name: "OpenSans-Regular", size: 15)!])
另一答案

我相信该函数已被弃用,因为NSString+UIKit函数系列(sizewithFont:...等)基于UIStringDrawing库,它不是线程安全的。如果你试图不在主线程上运行它们(就像任何其他UIKit功能一样),你将会得到不可预知的行为。特别是,如果您同时在多个线程上运行该函数,它可能会使您的应用程序崩溃。这就是为什么在iOS 6中,他们为boundingRectWithSize:...引入了NSAttributedString方法。它建立在NSStringDrawing库之上,并且是线程安全的。

如果你看一下新的NSString boundingRectWithSize:...函数,它会以与NSAttributeString相同的方式请求一个属性数组。如果我不得不猜测,iOS 7中的这个新的NSString函数只是iOS 6中NSAttributeString函数的包装器。

在这方面,如果你只支持iOS 6和iOS 7,那么我肯定会将你所有的NSString sizeWithFont:...改为NSAttributeString boundingRectWithSize。如果您碰巧有一个奇怪的多线程角落案例,它会为您省去很多麻烦!这是我如何转换NSString sizeWithFont:constrainedToSize:

过去是什么:

NSString *text = ...;
CGFloat width = ...;
UIFont *font = ...;
CGSize size = [text sizeWithFont:font 
               constrainedToSize:(CGSize){width, CGFLOAT_MAX}];

可以替换为:

NSString *text = ...;
CGFloat width = ...;
UIFont *font = ...;
NSAttributedString *attributedText =
    [[NSAttributedString alloc] initWithString:text 
                                    attributes:@{NSFontAttributeName: font}];
CGRect rect = [attributedText boundingRectWithSize:(CGSize){width, CGFLOAT_MAX}
                                           options:NSStringDrawingUsesLineFragmentOrigin
                                           context:nil];
CGSize size = rect.size;

请注意文档提到:

在iOS 7及更高版本中,此方法返回小数大小(在返回的CGRect的大小组件中);要使用返回的大小来调整视图大小,必须使用ceil函数将其值提升到最接近的更高整数。

因此,要拉出用于调整视图大小的计算高度或宽度,我会使用:

CGFloat height = ceilf(size.height);
CGFloat width  = ceilf(size.width);
另一答案

这些都不适用于ios 7.这就是我最终要做的事情。我把它放在我的自定义单元类中,并在我的heightForCellAtIndexPath方法中调用该方法。

在应用商店中查看应用时,我的单元格与描述单元格类似。

首先在故事板中,将标签设置为'attributedText',将行数设置为0(这将自动调整标签大小(仅限ios 6+))并将其设置为自动换行。

然后我只是在我的自定义Cell Class中添加单元格内容的所有高度。在我的情况下,我在顶部有一个标签,总是说“描述”(_descriptionHeadingLabel),一个较小的标签,其大小可变,包含从单元格顶部到标题的约束的实际描述(_descriptionLabel)

以上是关于在iOS 7中替换已弃用的sizeWithFont:的主要内容,如果未能解决你的问题,请参考以下文章

替换已弃用的 `keypress` DOM 事件

用 .on 替换已弃用的 .live [重复]

如何在 Hibernate 中用 TableGenerator 替换已弃用的 MultipleHiLoPerTableGenerator

尝试替换已弃用的 loadnibnamed:owner

替换已弃用的CdkDropListContainer

jQuery:替换已弃用的“.load()”? [复制]