Как устранить лишние разрывы строк из NSAttributedString (преобразованные из HTML) в объекте iOS UILabel? - PullRequest
0 голосов
/ 13 ноября 2018

У меня есть несколько ячеек табличного представления, которые должны отображать некоторые простые HTML с нашего сервера. Я преобразую HTML в NSAttributedString, чтобы он мог отображаться в объектах UILabel в ячейках. Но когда табличное представление рисует ячейки, объекты UILabel, кажется, имеют некоторые разрывы строк, добавленные в их конец. Обратите внимание на дополнительное место здесь:

enter image description here

(Кстати, рис предоставляет две ячейки таблицы, потому что я пробовал две разные формы HTML, и в в обоих случаях, кажется, вставлены разрывы строк) Я подумал, что, возможно, это из-за моего макета, что, возможно, UILabel был вынужден компоновкой макета и не может самостоятельно изменять размеры / уменьшать размер в зависимости от назначенного ему текста. Но когда я добавляю к той же метке простую строку NSAttributedString, созданную следующим образом:

 sRet = [[NSAttributedString alloc] initWithString:@"[Dummy text string 111]"];

(желтый) UILabel действительно сжимается в ответ примерно так:

enter image description here

в значительной степени демонстрирует, что мой макет позволяет UILabel свободно изменять размер в соответствии с назначенным ему текстом.

Ниже приведен HTML-код, назначаемый меткам и полученным значениям NSAttributedString, когда я регистрирую их в консоли. Они соответствуют тому, что вы видите на желтых объектах UILabel на первом изображении выше. Вот HTML, преобразуемый в приписанную строку и присвоенный:

<h2>Student did poorly</h2>

<p><span style="font-family:comic sans ms,cursive;"><span style="font-size:14px;">Student did ok</span></span></p>

А вот соответствующие приписанные строки:

Student did poorly
{
    NSColor = "kCGColorSpaceModelRGB 0 0 0 1 ";
    NSFont = "<UICTFont: 0x7fce3f8798e0> font-family: \"TimesNewRomanPS-BoldMT\"; font-weight: bold; font-style: normal; font-size: 18.00pt";
    NSKern = 0;
    NSParagraphStyle = "Alignment 4, LineSpacing 0, ParagraphSpacing 0, ParagraphSpacingBefore 0, HeadIndent 0, TailIndent 0, FirstLineHeadIndent 0, LineHeight 22/0, LineHeightMultiple 0, LineBreakMode 0, Tabs (\n), DefaultTabInterval 36, Blocks (null), Lists (null), BaseWritingDirection 0, HyphenationFactor 0, TighteningForTruncation NO, HeaderLevel 2";
    NSStrokeColor = "kCGColorSpaceModelRGB 0 0 0 1 ";
    NSStrokeWidth = 0;
}

Student did ok{
    NSColor = "kCGColorSpaceModelRGB 0 0 0 1 ";
    NSFont = "<UICTFont: 0x7fce3d5a96c0> font-family: \"Snell Roundhand\"; font-weight: normal; font-style: normal; font-size: 14.00pt";
    NSKern = 0;
    NSParagraphStyle = "Alignment 4, LineSpacing 0, ParagraphSpacing 0, ParagraphSpacingBefore 0, HeadIndent 0, TailIndent 0, FirstLineHeadIndent 0, LineHeight 19/0, LineHeightMultiple 0, LineBreakMode 0, Tabs (\n), DefaultTabInterval 36, Blocks (\n), Lists (\n), BaseWritingDirection 0, HyphenationFactor 0, TighteningForTruncation NO, HeaderLevel 0";
    NSStrokeColor = "kCGColorSpaceModelRGB 0 0 0 1 ";
    NSStrokeWidth = 0;
}
{
    NSColor = "kCGColorSpaceModelRGB 0 0 0 1 ";
    NSFont = "<UICTFont: 0x7fce3d7959e0> font-family: \"Times New Roman\"; font-weight: normal; font-style: normal; font-size: 12.00pt";
    NSKern = 0;
    NSParagraphStyle = "Alignment 4, LineSpacing 0, ParagraphSpacing 0, ParagraphSpacingBefore 0, HeadIndent 0, TailIndent 0, FirstLineHeadIndent 0, LineHeight 15/0, LineHeightMultiple 0, LineBreakMode 0, Tabs (\n), DefaultTabInterval 36, Blocks (\n), Lists (\n), BaseWritingDirection 0, HyphenationFactor 0, TighteningForTruncation NO, HeaderLevel 0";
    NSStrokeColor = "kCGColorSpaceModelRGB 0 0 0 1 ";
    NSStrokeWidth = 0;
}

Ни в html, ни в приписанных строках я не вижу причины, по которой объекты UILabel имеют такое дополнительное вертикальное пространство. Кстати, пара объектов UILabel в каждой ячейке (желтая и белая) содержатся в UIStackView, поэтому, возможно, это может как-то причинить вред. Но только четыре ограничения: конечный, ведущий, нижний и верхний, и, как упомянуто выше, размер метки можно корректно изменить, поэтому эти ограничения, похоже, не способствуют этому.

1 Ответ

0 голосов
/ 26 ноября 2018

Я столкнулся с той же проблемой, когда нужно было удалить ненужные символы новой строки, добавленные моими тегами <p>, и я не смог что-то изменить на стороне сервера.Итак, я пришел первым с этим решением:

Swift

while !attributedString.string.isEmpty //Validates if the attributed string has at least one character
    && CharacterSet.newlines.contains(attributedString.string.unicodeScalars.last!) //Compares if the last unicode character of the attributed string is inside the `CharacterSet` of newlines
    {
    attributedString.deleteCharacters(in: NSRange(location: attributedString.length - 1, length: 1)) //Deletes the last character of the attributed string
}

Obj-C (не тестировался)

while ([attributedString.string length] > 0
    && [[attributedString.string substringFromIndex:[attributedString.string length] - 1] rangeOfCharacterFromSet:NSCharacterSet.newlineCharacterSet].location != NSNotFound)
    {
    [attributedString deleteCharactersInRange:NSMakeRange([attributedString length] - 1, 1)];
}

(я выполняю этот код сразу после преобразования html-кода в приписанную строку.)


Но по ответам я вижу, что теги <h#> также добавляют новые строки,Так что для расширенного решения может быть что-то вроде создания приписанной строки для каждой пары тегов;примените их фильтр выше;и после этого объедините их в одну атрибутивную строку или отобразите их в разных метках.


Edit

Я использую расширение String для преобразованияHTML-код для NSMutableAttributedString:

extension String {

    /// Returns a new attributed string loading any HTML tags that the receiver contains.
    ///
    /// If the HTML code is malformed or can not format it, this method returns the receiver but as a `NSMutableAttributedString`. If the formated resulting string contains one or more newlines at the end, they are removed.
    func htmlFormat() -> NSMutableAttributedString {
        var attributedString = NSMutableAttributedString(string: self, attributes: [.font : UIFont.preferredFont(forTextStyle: .body)])

        if let data = data(using: .utf8),
            let formatedString = try? NSMutableAttributedString(data: data,
                                                                options: [.documentType: NSAttributedString.DocumentType.html,
                                                                          .characterEncoding: String.Encoding.utf8.rawValue],
                                                                documentAttributes: nil) {
            attributedString = formatedString
        }

        while !attributedString.string.isEmpty
        && CharacterSet.newlines.contains(attributedString.string.unicodeScalars.last!) {
            attributedString.deleteCharacters(in: NSRange(location: attributedString.length - 1, length: 1))
        }

        return attributedString
    }

}
...