How to eliminate superfluous line breaks from NSAttributedString (converted from HTML) in iOS UILabel object?
I have some table view cells that need to display some simple html from our server. Am converting the html into an NSAttributedString so that it can be displayed in UILabel objects on the cells. But when the table view draws the cells the UILabel objects seem to have some line breaks added to the end of them. Notice extra space here:
(Btw, the pic provides two tableview cells because I tried two different forms of html and in both cases there seem to be inserted line breaks)
I thought perhaps it was due to my layout, that maybe the UILabel was being forced into its height by the layout and not free to resize/shrink itself based upon the text it is assigned. But when I supply to the same label a simple NSAttributedString created this way:
sRet = [[NSAttributedString alloc] initWithString:@"[Dummy text string 111]"];
the (yellow) UILabel indeed shrinks in response like so:
pretty much demonstrating that my layout is allowing the UILabel to freely resize according to the text assigned to it.
Below is the html being assigned to the labels and the resulting NSAttributedString values when I log them to the console. These correspond to what you see in the yellow UILabel objects in the first image above. Here is the html being converted to an attributed string and assigned:
<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>
And here are the corresponding attributed strings:
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;
In neither the html nor the attributed strings do I see reason for the UILabel objects having that extra vertical space. Fwiw, the pair of UILabel object on each cell (the yellow and the white) are contained within a UIStackView, so perhaps it could somehow be doing the mischief. But only four constraints, trailing, leading, bottom and top, and as mentioned above the label is able to be resized fine so these constraints don't seem to be contributing to this.
html ios uilabel nsattributedstring uistackview
add a comment |
I have some table view cells that need to display some simple html from our server. Am converting the html into an NSAttributedString so that it can be displayed in UILabel objects on the cells. But when the table view draws the cells the UILabel objects seem to have some line breaks added to the end of them. Notice extra space here:
(Btw, the pic provides two tableview cells because I tried two different forms of html and in both cases there seem to be inserted line breaks)
I thought perhaps it was due to my layout, that maybe the UILabel was being forced into its height by the layout and not free to resize/shrink itself based upon the text it is assigned. But when I supply to the same label a simple NSAttributedString created this way:
sRet = [[NSAttributedString alloc] initWithString:@"[Dummy text string 111]"];
the (yellow) UILabel indeed shrinks in response like so:
pretty much demonstrating that my layout is allowing the UILabel to freely resize according to the text assigned to it.
Below is the html being assigned to the labels and the resulting NSAttributedString values when I log them to the console. These correspond to what you see in the yellow UILabel objects in the first image above. Here is the html being converted to an attributed string and assigned:
<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>
And here are the corresponding attributed strings:
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;
In neither the html nor the attributed strings do I see reason for the UILabel objects having that extra vertical space. Fwiw, the pair of UILabel object on each cell (the yellow and the white) are contained within a UIStackView, so perhaps it could somehow be doing the mischief. But only four constraints, trailing, leading, bottom and top, and as mentioned above the label is able to be resized fine so these constraints don't seem to be contributing to this.
html ios uilabel nsattributedstring uistackview
Try removing the paragraph tags<p>
– Brandon
Nov 13 '18 at 2:13
@Brandon I'll try that, and considered it earlier, but notice that there are no <p> tags in the first instance, the <h2>Student did poorly</h2> one. It exhibits the same behavior as the one and I have to handle that kind of html.
– Alyoshak
Nov 13 '18 at 2:27
@Brandon Removing the <p> tags definitely allowed the label to shrink as needed. Thanks. Any ideas on why the <h2> tags are causing line breaks after the end of the text, and what to do about it? One thing that's unclear is why that one attributed string has two sections rather than one (two fonts rather than one).
– Alyoshak
Nov 13 '18 at 15:19
add a comment |
I have some table view cells that need to display some simple html from our server. Am converting the html into an NSAttributedString so that it can be displayed in UILabel objects on the cells. But when the table view draws the cells the UILabel objects seem to have some line breaks added to the end of them. Notice extra space here:
(Btw, the pic provides two tableview cells because I tried two different forms of html and in both cases there seem to be inserted line breaks)
I thought perhaps it was due to my layout, that maybe the UILabel was being forced into its height by the layout and not free to resize/shrink itself based upon the text it is assigned. But when I supply to the same label a simple NSAttributedString created this way:
sRet = [[NSAttributedString alloc] initWithString:@"[Dummy text string 111]"];
the (yellow) UILabel indeed shrinks in response like so:
pretty much demonstrating that my layout is allowing the UILabel to freely resize according to the text assigned to it.
Below is the html being assigned to the labels and the resulting NSAttributedString values when I log them to the console. These correspond to what you see in the yellow UILabel objects in the first image above. Here is the html being converted to an attributed string and assigned:
<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>
And here are the corresponding attributed strings:
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;
In neither the html nor the attributed strings do I see reason for the UILabel objects having that extra vertical space. Fwiw, the pair of UILabel object on each cell (the yellow and the white) are contained within a UIStackView, so perhaps it could somehow be doing the mischief. But only four constraints, trailing, leading, bottom and top, and as mentioned above the label is able to be resized fine so these constraints don't seem to be contributing to this.
html ios uilabel nsattributedstring uistackview
I have some table view cells that need to display some simple html from our server. Am converting the html into an NSAttributedString so that it can be displayed in UILabel objects on the cells. But when the table view draws the cells the UILabel objects seem to have some line breaks added to the end of them. Notice extra space here:
(Btw, the pic provides two tableview cells because I tried two different forms of html and in both cases there seem to be inserted line breaks)
I thought perhaps it was due to my layout, that maybe the UILabel was being forced into its height by the layout and not free to resize/shrink itself based upon the text it is assigned. But when I supply to the same label a simple NSAttributedString created this way:
sRet = [[NSAttributedString alloc] initWithString:@"[Dummy text string 111]"];
the (yellow) UILabel indeed shrinks in response like so:
pretty much demonstrating that my layout is allowing the UILabel to freely resize according to the text assigned to it.
Below is the html being assigned to the labels and the resulting NSAttributedString values when I log them to the console. These correspond to what you see in the yellow UILabel objects in the first image above. Here is the html being converted to an attributed string and assigned:
<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>
And here are the corresponding attributed strings:
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;
In neither the html nor the attributed strings do I see reason for the UILabel objects having that extra vertical space. Fwiw, the pair of UILabel object on each cell (the yellow and the white) are contained within a UIStackView, so perhaps it could somehow be doing the mischief. But only four constraints, trailing, leading, bottom and top, and as mentioned above the label is able to be resized fine so these constraints don't seem to be contributing to this.
html ios uilabel nsattributedstring uistackview
html ios uilabel nsattributedstring uistackview
edited Nov 20 '18 at 20:59
asked Nov 13 '18 at 2:04
Alyoshak
1,13662250
1,13662250
Try removing the paragraph tags<p>
– Brandon
Nov 13 '18 at 2:13
@Brandon I'll try that, and considered it earlier, but notice that there are no <p> tags in the first instance, the <h2>Student did poorly</h2> one. It exhibits the same behavior as the one and I have to handle that kind of html.
– Alyoshak
Nov 13 '18 at 2:27
@Brandon Removing the <p> tags definitely allowed the label to shrink as needed. Thanks. Any ideas on why the <h2> tags are causing line breaks after the end of the text, and what to do about it? One thing that's unclear is why that one attributed string has two sections rather than one (two fonts rather than one).
– Alyoshak
Nov 13 '18 at 15:19
add a comment |
Try removing the paragraph tags<p>
– Brandon
Nov 13 '18 at 2:13
@Brandon I'll try that, and considered it earlier, but notice that there are no <p> tags in the first instance, the <h2>Student did poorly</h2> one. It exhibits the same behavior as the one and I have to handle that kind of html.
– Alyoshak
Nov 13 '18 at 2:27
@Brandon Removing the <p> tags definitely allowed the label to shrink as needed. Thanks. Any ideas on why the <h2> tags are causing line breaks after the end of the text, and what to do about it? One thing that's unclear is why that one attributed string has two sections rather than one (two fonts rather than one).
– Alyoshak
Nov 13 '18 at 15:19
Try removing the paragraph tags
<p>
– Brandon
Nov 13 '18 at 2:13
Try removing the paragraph tags
<p>
– Brandon
Nov 13 '18 at 2:13
@Brandon I'll try that, and considered it earlier, but notice that there are no <p> tags in the first instance, the <h2>Student did poorly</h2> one. It exhibits the same behavior as the one and I have to handle that kind of html.
– Alyoshak
Nov 13 '18 at 2:27
@Brandon I'll try that, and considered it earlier, but notice that there are no <p> tags in the first instance, the <h2>Student did poorly</h2> one. It exhibits the same behavior as the one and I have to handle that kind of html.
– Alyoshak
Nov 13 '18 at 2:27
@Brandon Removing the <p> tags definitely allowed the label to shrink as needed. Thanks. Any ideas on why the <h2> tags are causing line breaks after the end of the text, and what to do about it? One thing that's unclear is why that one attributed string has two sections rather than one (two fonts rather than one).
– Alyoshak
Nov 13 '18 at 15:19
@Brandon Removing the <p> tags definitely allowed the label to shrink as needed. Thanks. Any ideas on why the <h2> tags are causing line breaks after the end of the text, and what to do about it? One thing that's unclear is why that one attributed string has two sections rather than one (two fonts rather than one).
– Alyoshak
Nov 13 '18 at 15:19
add a comment |
1 Answer
1
active
oldest
votes
I faced the same problem where needed to delete the unwanted newlines added by my <p>
tags and was not able to change things on server side. So I came first with this solution:
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 (not tested)
while ([attributedString.string length] > 0
&& [[attributedString.string substringFromIndex:[attributedString.string length] - 1] rangeOfCharacterFromSet:NSCharacterSet.newlineCharacterSet].location != NSNotFound)
[attributedString deleteCharactersInRange:NSMakeRange([attributedString length] - 1, 1)];
(I execute this code right after converting the html code into an attributed string.)
But I can see by the answers that also the <h#>
tags adds newlines. So for a extended solution could be something like make an attributed string for every pair of tags; apply them the filter above; and after that, join them in one attributed string or display them in different labels.
Edit
I use an extension of String
to convert the HTML code to an 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
There are no extra newline characters at the end of the attributed string, so the deleteCharacters call you suggest will only delete a character that needs to remain. The extra space must be resulting somehow from the actual attributed string formatting itself.
– Alyoshak
Nov 26 '18 at 20:54
When XCode prints the description of an attributed string with no newlines, then the{
brace is printed in the same line, but if it has one then the brace is printed in the next line. I mention this to visually check if it has a newline even if it is not marked as "n". And maybe you are correct about that the problem is the attributed string format itself, but I can not figure out where exactly, so at least this solution works fine for me. Maybe you can try it with anif
instead of awhile
in order to only delete one newline.
– Ángel Téllez
Nov 26 '18 at 21:41
Are you sure this worked for you? deleteCharactersInRange only compiles successfully for an NSMutableString (not an NSAttributedString or an NSString). I can't get your code to run so far.
– Alyoshak
Nov 26 '18 at 22:20
1
I have confirmed this works as intended. To see the newline more clearly, doprint(label.text)
after setting the attributed string to the label.
– allenh
Nov 27 '18 at 13:28
1
I can confim that the <h2> adds a little padding above itself, making it looking not centered. I do not know if this is intended or a little bug from Apple(?). But at least, I am able to erase the newlines at the end, too. I update my answer, including my convertion from the html to an attributed string. And if I can solve the problem of the space above the tag, I will also upload it.
– Ángel Téllez
Nov 27 '18 at 18:13
|
show 3 more comments
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53272720%2fhow-to-eliminate-superfluous-line-breaks-from-nsattributedstring-converted-from%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
I faced the same problem where needed to delete the unwanted newlines added by my <p>
tags and was not able to change things on server side. So I came first with this solution:
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 (not tested)
while ([attributedString.string length] > 0
&& [[attributedString.string substringFromIndex:[attributedString.string length] - 1] rangeOfCharacterFromSet:NSCharacterSet.newlineCharacterSet].location != NSNotFound)
[attributedString deleteCharactersInRange:NSMakeRange([attributedString length] - 1, 1)];
(I execute this code right after converting the html code into an attributed string.)
But I can see by the answers that also the <h#>
tags adds newlines. So for a extended solution could be something like make an attributed string for every pair of tags; apply them the filter above; and after that, join them in one attributed string or display them in different labels.
Edit
I use an extension of String
to convert the HTML code to an 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
There are no extra newline characters at the end of the attributed string, so the deleteCharacters call you suggest will only delete a character that needs to remain. The extra space must be resulting somehow from the actual attributed string formatting itself.
– Alyoshak
Nov 26 '18 at 20:54
When XCode prints the description of an attributed string with no newlines, then the{
brace is printed in the same line, but if it has one then the brace is printed in the next line. I mention this to visually check if it has a newline even if it is not marked as "n". And maybe you are correct about that the problem is the attributed string format itself, but I can not figure out where exactly, so at least this solution works fine for me. Maybe you can try it with anif
instead of awhile
in order to only delete one newline.
– Ángel Téllez
Nov 26 '18 at 21:41
Are you sure this worked for you? deleteCharactersInRange only compiles successfully for an NSMutableString (not an NSAttributedString or an NSString). I can't get your code to run so far.
– Alyoshak
Nov 26 '18 at 22:20
1
I have confirmed this works as intended. To see the newline more clearly, doprint(label.text)
after setting the attributed string to the label.
– allenh
Nov 27 '18 at 13:28
1
I can confim that the <h2> adds a little padding above itself, making it looking not centered. I do not know if this is intended or a little bug from Apple(?). But at least, I am able to erase the newlines at the end, too. I update my answer, including my convertion from the html to an attributed string. And if I can solve the problem of the space above the tag, I will also upload it.
– Ángel Téllez
Nov 27 '18 at 18:13
|
show 3 more comments
I faced the same problem where needed to delete the unwanted newlines added by my <p>
tags and was not able to change things on server side. So I came first with this solution:
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 (not tested)
while ([attributedString.string length] > 0
&& [[attributedString.string substringFromIndex:[attributedString.string length] - 1] rangeOfCharacterFromSet:NSCharacterSet.newlineCharacterSet].location != NSNotFound)
[attributedString deleteCharactersInRange:NSMakeRange([attributedString length] - 1, 1)];
(I execute this code right after converting the html code into an attributed string.)
But I can see by the answers that also the <h#>
tags adds newlines. So for a extended solution could be something like make an attributed string for every pair of tags; apply them the filter above; and after that, join them in one attributed string or display them in different labels.
Edit
I use an extension of String
to convert the HTML code to an 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
There are no extra newline characters at the end of the attributed string, so the deleteCharacters call you suggest will only delete a character that needs to remain. The extra space must be resulting somehow from the actual attributed string formatting itself.
– Alyoshak
Nov 26 '18 at 20:54
When XCode prints the description of an attributed string with no newlines, then the{
brace is printed in the same line, but if it has one then the brace is printed in the next line. I mention this to visually check if it has a newline even if it is not marked as "n". And maybe you are correct about that the problem is the attributed string format itself, but I can not figure out where exactly, so at least this solution works fine for me. Maybe you can try it with anif
instead of awhile
in order to only delete one newline.
– Ángel Téllez
Nov 26 '18 at 21:41
Are you sure this worked for you? deleteCharactersInRange only compiles successfully for an NSMutableString (not an NSAttributedString or an NSString). I can't get your code to run so far.
– Alyoshak
Nov 26 '18 at 22:20
1
I have confirmed this works as intended. To see the newline more clearly, doprint(label.text)
after setting the attributed string to the label.
– allenh
Nov 27 '18 at 13:28
1
I can confim that the <h2> adds a little padding above itself, making it looking not centered. I do not know if this is intended or a little bug from Apple(?). But at least, I am able to erase the newlines at the end, too. I update my answer, including my convertion from the html to an attributed string. And if I can solve the problem of the space above the tag, I will also upload it.
– Ángel Téllez
Nov 27 '18 at 18:13
|
show 3 more comments
I faced the same problem where needed to delete the unwanted newlines added by my <p>
tags and was not able to change things on server side. So I came first with this solution:
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 (not tested)
while ([attributedString.string length] > 0
&& [[attributedString.string substringFromIndex:[attributedString.string length] - 1] rangeOfCharacterFromSet:NSCharacterSet.newlineCharacterSet].location != NSNotFound)
[attributedString deleteCharactersInRange:NSMakeRange([attributedString length] - 1, 1)];
(I execute this code right after converting the html code into an attributed string.)
But I can see by the answers that also the <h#>
tags adds newlines. So for a extended solution could be something like make an attributed string for every pair of tags; apply them the filter above; and after that, join them in one attributed string or display them in different labels.
Edit
I use an extension of String
to convert the HTML code to an 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
I faced the same problem where needed to delete the unwanted newlines added by my <p>
tags and was not able to change things on server side. So I came first with this solution:
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 (not tested)
while ([attributedString.string length] > 0
&& [[attributedString.string substringFromIndex:[attributedString.string length] - 1] rangeOfCharacterFromSet:NSCharacterSet.newlineCharacterSet].location != NSNotFound)
[attributedString deleteCharactersInRange:NSMakeRange([attributedString length] - 1, 1)];
(I execute this code right after converting the html code into an attributed string.)
But I can see by the answers that also the <h#>
tags adds newlines. So for a extended solution could be something like make an attributed string for every pair of tags; apply them the filter above; and after that, join them in one attributed string or display them in different labels.
Edit
I use an extension of String
to convert the HTML code to an 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
edited Nov 27 '18 at 18:37
answered Nov 26 '18 at 19:13
Ángel Téllez
4536
4536
There are no extra newline characters at the end of the attributed string, so the deleteCharacters call you suggest will only delete a character that needs to remain. The extra space must be resulting somehow from the actual attributed string formatting itself.
– Alyoshak
Nov 26 '18 at 20:54
When XCode prints the description of an attributed string with no newlines, then the{
brace is printed in the same line, but if it has one then the brace is printed in the next line. I mention this to visually check if it has a newline even if it is not marked as "n". And maybe you are correct about that the problem is the attributed string format itself, but I can not figure out where exactly, so at least this solution works fine for me. Maybe you can try it with anif
instead of awhile
in order to only delete one newline.
– Ángel Téllez
Nov 26 '18 at 21:41
Are you sure this worked for you? deleteCharactersInRange only compiles successfully for an NSMutableString (not an NSAttributedString or an NSString). I can't get your code to run so far.
– Alyoshak
Nov 26 '18 at 22:20
1
I have confirmed this works as intended. To see the newline more clearly, doprint(label.text)
after setting the attributed string to the label.
– allenh
Nov 27 '18 at 13:28
1
I can confim that the <h2> adds a little padding above itself, making it looking not centered. I do not know if this is intended or a little bug from Apple(?). But at least, I am able to erase the newlines at the end, too. I update my answer, including my convertion from the html to an attributed string. And if I can solve the problem of the space above the tag, I will also upload it.
– Ángel Téllez
Nov 27 '18 at 18:13
|
show 3 more comments
There are no extra newline characters at the end of the attributed string, so the deleteCharacters call you suggest will only delete a character that needs to remain. The extra space must be resulting somehow from the actual attributed string formatting itself.
– Alyoshak
Nov 26 '18 at 20:54
When XCode prints the description of an attributed string with no newlines, then the{
brace is printed in the same line, but if it has one then the brace is printed in the next line. I mention this to visually check if it has a newline even if it is not marked as "n". And maybe you are correct about that the problem is the attributed string format itself, but I can not figure out where exactly, so at least this solution works fine for me. Maybe you can try it with anif
instead of awhile
in order to only delete one newline.
– Ángel Téllez
Nov 26 '18 at 21:41
Are you sure this worked for you? deleteCharactersInRange only compiles successfully for an NSMutableString (not an NSAttributedString or an NSString). I can't get your code to run so far.
– Alyoshak
Nov 26 '18 at 22:20
1
I have confirmed this works as intended. To see the newline more clearly, doprint(label.text)
after setting the attributed string to the label.
– allenh
Nov 27 '18 at 13:28
1
I can confim that the <h2> adds a little padding above itself, making it looking not centered. I do not know if this is intended or a little bug from Apple(?). But at least, I am able to erase the newlines at the end, too. I update my answer, including my convertion from the html to an attributed string. And if I can solve the problem of the space above the tag, I will also upload it.
– Ángel Téllez
Nov 27 '18 at 18:13
There are no extra newline characters at the end of the attributed string, so the deleteCharacters call you suggest will only delete a character that needs to remain. The extra space must be resulting somehow from the actual attributed string formatting itself.
– Alyoshak
Nov 26 '18 at 20:54
There are no extra newline characters at the end of the attributed string, so the deleteCharacters call you suggest will only delete a character that needs to remain. The extra space must be resulting somehow from the actual attributed string formatting itself.
– Alyoshak
Nov 26 '18 at 20:54
When XCode prints the description of an attributed string with no newlines, then the
{
brace is printed in the same line, but if it has one then the brace is printed in the next line. I mention this to visually check if it has a newline even if it is not marked as "n". And maybe you are correct about that the problem is the attributed string format itself, but I can not figure out where exactly, so at least this solution works fine for me. Maybe you can try it with an if
instead of a while
in order to only delete one newline.– Ángel Téllez
Nov 26 '18 at 21:41
When XCode prints the description of an attributed string with no newlines, then the
{
brace is printed in the same line, but if it has one then the brace is printed in the next line. I mention this to visually check if it has a newline even if it is not marked as "n". And maybe you are correct about that the problem is the attributed string format itself, but I can not figure out where exactly, so at least this solution works fine for me. Maybe you can try it with an if
instead of a while
in order to only delete one newline.– Ángel Téllez
Nov 26 '18 at 21:41
Are you sure this worked for you? deleteCharactersInRange only compiles successfully for an NSMutableString (not an NSAttributedString or an NSString). I can't get your code to run so far.
– Alyoshak
Nov 26 '18 at 22:20
Are you sure this worked for you? deleteCharactersInRange only compiles successfully for an NSMutableString (not an NSAttributedString or an NSString). I can't get your code to run so far.
– Alyoshak
Nov 26 '18 at 22:20
1
1
I have confirmed this works as intended. To see the newline more clearly, do
print(label.text)
after setting the attributed string to the label.– allenh
Nov 27 '18 at 13:28
I have confirmed this works as intended. To see the newline more clearly, do
print(label.text)
after setting the attributed string to the label.– allenh
Nov 27 '18 at 13:28
1
1
I can confim that the <h2> adds a little padding above itself, making it looking not centered. I do not know if this is intended or a little bug from Apple(?). But at least, I am able to erase the newlines at the end, too. I update my answer, including my convertion from the html to an attributed string. And if I can solve the problem of the space above the tag, I will also upload it.
– Ángel Téllez
Nov 27 '18 at 18:13
I can confim that the <h2> adds a little padding above itself, making it looking not centered. I do not know if this is intended or a little bug from Apple(?). But at least, I am able to erase the newlines at the end, too. I update my answer, including my convertion from the html to an attributed string. And if I can solve the problem of the space above the tag, I will also upload it.
– Ángel Téllez
Nov 27 '18 at 18:13
|
show 3 more comments
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53272720%2fhow-to-eliminate-superfluous-line-breaks-from-nsattributedstring-converted-from%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Try removing the paragraph tags
<p>
– Brandon
Nov 13 '18 at 2:13
@Brandon I'll try that, and considered it earlier, but notice that there are no <p> tags in the first instance, the <h2>Student did poorly</h2> one. It exhibits the same behavior as the one and I have to handle that kind of html.
– Alyoshak
Nov 13 '18 at 2:27
@Brandon Removing the <p> tags definitely allowed the label to shrink as needed. Thanks. Any ideas on why the <h2> tags are causing line breaks after the end of the text, and what to do about it? One thing that's unclear is why that one attributed string has two sections rather than one (two fonts rather than one).
– Alyoshak
Nov 13 '18 at 15:19