Skip to content

Commit cc2f757

Browse files
author
Roel Spruit
committed
Merged PR 6923: Fix italic and bold in treatment perspective
Fix italic and bold in treatment perspective Related work items: #58902, #59162
2 parents d23ac69 + 9c3f9af commit cc2f757

12 files changed

+68
-31
lines changed

Sources/ENCore/Resources/DefaultTreatmentPerspective.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@
66
"next_steps_title": "What can you do now?",
77
"next_steps_body": "<ul><li>Stay home up to and including {StayHomeUntilDate} and look out for symptoms related to the coronavirus</li><li>Do you have (mild) symptoms related to the coronavirus? Get tested for coronavirus and stay home up to and including {StayHomeUntilDate}</li><li>Serious symptoms like high fever or difficulty breathing? Or part of a high-risk group and having a fever? Call your doctor</li></ul>\nWere you called by the GGD? Follow the advice given by the GGD, not the advice given by the app.",
88
"stay_home_title": "Stay home up to and including {StayHomeUntilDate}",
9-
"stay_home_body": "<ul><li>Ask someone else to get groceries. Is this impossible and are you free of symptoms? Then it's alright if you quickly go to the shop. Keep a 1,5 metre distance and don't touch anyone.</li><li>You're allowed to enjoy your own yard or balcony.</li><li>Children under the age of 18 are allowed to go to school and/or play sports.</li></ul>",
9+
"stay_home_body": "<ul><li>Ask someone else to get groceries. Is this impossible and are you free of symptoms? Then it's alright if you quickly go to the shop. Keep a 1.5 metre distance and don't touch anyone.</li><li>You're allowed to enjoy your own yard or balcony.</li><li>Children under the age of 18 are allowed to go to school and/or play sports.</li></ul>",
1010
"no_visitors_title": "Don't see visitors",
11-
"no_visitors_body": "Only the people who live with you are allowed to be in the same house as you. Stay away from each other and keep a 1,5 metre distance. That means no cuddling, no kissing and no sex.",
11+
"no_visitors_body": "Only the people who live with you are allowed to be in the same house as you. Stay away from each other and keep a 1.5 metre distance. That means no cuddling, no kissing and no sex.",
1212
"medical_help_title": "Do you need medical help?",
1313
"medical_help_body": "<ul><li>Don't go to see your doctor or go to the hospital, but call your doctor first. Tell them you've been in contact with someone who has coronavirus.</li><li>Your doctor and other medical personnel are allowed to visit you.</li></ul>",
1414
"after_stay_home_title": "After {StayHomeUntilDate}",

Sources/ENCoreTests/App/Features/Notifications/Message/MessageViewControllerTests.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,10 +104,10 @@ final class MessageViewControllerTests: TestCase {
104104
private lazy var fakeMessageWithListAndText: LocalizedTreatmentPerspective = {
105105
LocalizedTreatmentPerspective(paragraphs: [
106106
.init(title: "Paragraph Title",
107-
body: .htmlWithBulletList(text: "<b>Intro text</b>.\\n\\n<i>Second intro</i>.\\n\\n<ul><li>List Item 1</li><li>List Item 2</li></ul>\\nText below list", font: self.theme.fonts.body, textColor: self.theme.colors.gray, theme: self.theme, textAlignment: .left),
107+
body: .htmlWithBulletList(text: "<b>Intro text</b>.\\n\\n<i>Second intro</i> and the text continue until it wraps around just check long lines.<ul><li>List Item 1 <b>bold</b></li><li>List Item 2 <i>italic</i></li></ul>\\nText below list", font: self.theme.fonts.body, textColor: self.theme.colors.gray, theme: self.theme, textAlignment: .left),
108108
type: .paragraph),
109109
.init(title: "Paragraph Title",
110-
body: .htmlWithBulletList(text: "<b>Intro text</b>.\\n\\n<i>Second intro</i>.\\n\\n<ul><li>List Item 1</li><li>List Item 2</li></ul>\\nText below list", font: self.theme.fonts.body, textColor: self.theme.colors.gray, theme: self.theme, textAlignment: .left),
110+
body: .htmlWithBulletList(text: "<b>Intro text</b>.\\n\\n<i>Second intro</i>.\n\n<ul><li>List Item 1</li><li>List Item 2</li></ul>\\nText below list", font: self.theme.fonts.body, textColor: self.theme.colors.gray, theme: self.theme, textAlignment: .left),
111111
type: .paragraph)
112112
], quarantineDays: 10)
113113
}()

Sources/ENFoundation/Extensions/NSAttributedString+Extension.swift

Lines changed: 64 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -55,30 +55,7 @@ public extension NSAttributedString {
5555

5656
let fullRange = NSRange(location: 0, length: attributedTitle.length)
5757
attributedTitle.addAttributes(attributes, range: fullRange)
58-
59-
let boldFontDescriptor = font.fontDescriptor.withSymbolicTraits(.traitBold)
60-
let boldFont = boldFontDescriptor.map { UIFont(descriptor: $0, size: font.pointSize) }
61-
62-
let italicFontDescriptor = font.fontDescriptor.withSymbolicTraits(.traitItalic)
63-
let italicFont = italicFontDescriptor.map { UIFont(descriptor: $0, size: font.pointSize) }
64-
65-
// replace default font with desired font - maintain bold style if possible
66-
attributedTitle.enumerateAttribute(.font, in: fullRange, options: []) { value, range, finished in
67-
guard let currentFont = value as? UIFont else { return }
68-
69-
var newFont = font
70-
71-
if let italicFont = italicFont, currentFont.fontDescriptor.symbolicTraits.contains(.traitItalic) {
72-
newFont = italicFont
73-
}
74-
75-
if let boldFont = boldFont, currentFont.fontDescriptor.symbolicTraits.contains(.traitBold) {
76-
newFont = boldFont
77-
}
78-
79-
attributedTitle.removeAttribute(.font, range: range)
80-
attributedTitle.addAttribute(.font, value: newFont, range: range)
81-
}
58+
attributedTitle.replaceBoldAndItalicAttributes(font: font)
8259

8360
return attributedTitle
8461
}
@@ -109,10 +86,12 @@ public extension NSAttributedString {
10986
.components(separatedBy: "\n")
11087
.filter { $0.hasPrefix(bullet) }
11188
.forEach { line in
112-
if let lineRange = textToFormat.string.range(of: line) {
113-
let attributedLine = makeBullet(line.replacingOccurrences(of: bullet, with: ""), theme: theme, font: font, textAlignment: textAlignment)
114-
textToFormat.replaceCharacters(in: NSRange(lineRange, in: line), with: attributedLine)
89+
guard let lineRange = textToFormat.string.range(of: line) else {
90+
return
11591
}
92+
let attributedLine = NSMutableAttributedString(attributedString: textToFormat.attributedSubstring(from: NSRange(lineRange, in: line)))
93+
attributedLine.reformatBulletPoint(font: font, theme: theme, textAlignment: textAlignment)
94+
textToFormat.replaceCharacters(in: NSRange(lineRange, in: line), with: attributedLine)
11695
}
11796

11897
return textToFormat.attributedStringByTrimmingCharacterSet(charSet: .whitespacesAndNewlines)
@@ -210,4 +189,62 @@ extension NSMutableAttributedString {
210189
range = (string as NSString).rangeOfCharacter(from: charSet, options: .backwards)
211190
}
212191
}
192+
193+
func replaceBoldAndItalicAttributes(font: UIFont) {
194+
195+
let fullRange = NSRange(location: 0, length: length)
196+
197+
let boldFontDescriptor = font.fontDescriptor.withSymbolicTraits(.traitBold)
198+
let boldFont = boldFontDescriptor.map { UIFont(descriptor: $0, size: font.pointSize) }
199+
200+
let italicFontDescriptor = font.fontDescriptor.withSymbolicTraits(.traitItalic)
201+
let italicFont = italicFontDescriptor.map { UIFont(descriptor: $0, size: font.pointSize) }
202+
203+
// replace default font with desired font - maintain bold style if possible
204+
self.enumerateAttribute(.font, in: fullRange, options: []) { value, range, finished in
205+
guard let currentFont = value as? UIFont else { return }
206+
207+
var newFont = font
208+
209+
if let italicFont = italicFont, currentFont.fontDescriptor.symbolicTraits.contains(.traitItalic) {
210+
newFont = italicFont
211+
}
212+
213+
if let boldFont = boldFont, currentFont.fontDescriptor.symbolicTraits.contains(.traitBold) {
214+
newFont = boldFont
215+
}
216+
217+
self.removeAttribute(.font, range: range)
218+
self.addAttribute(.font, value: newFont, range: range)
219+
}
220+
}
221+
222+
func reformatBulletPoint(font: UIFont, theme: Theme, textAlignment: NSTextAlignment) {
223+
224+
let bullet = "\t\t"
225+
226+
if let bulletRange = self.string.range(of: bullet) {
227+
228+
let bulletFont = font.withSize(10)
229+
let bulletAttributes: [NSAttributedString.Key: Any] = [
230+
.font: bulletFont,
231+
.foregroundColor: theme.colors.primary,
232+
.baselineOffset: (font.xHeight - bulletFont.xHeight) / 2
233+
]
234+
let newBullet = NSMutableAttributedString(string: "\u{25CF}\t", attributes: bulletAttributes)
235+
self.replaceCharacters(in: NSRange(bulletRange, in: self.string), with: newBullet)
236+
}
237+
238+
let paragraphStyle = NSMutableParagraphStyle()
239+
let nonOptions = [NSTextTab.OptionKey: Any]()
240+
paragraphStyle.tabStops = [
241+
NSTextTab(textAlignment: textAlignment, location: 16, options: nonOptions)
242+
]
243+
paragraphStyle.defaultTabInterval = 16
244+
paragraphStyle.headIndent = 16
245+
paragraphStyle.alignment = textAlignment
246+
paragraphStyle.paragraphSpacing = 5
247+
248+
self.addAttributes([NSAttributedString.Key.paragraphStyle: paragraphStyle], range: NSMakeRange(0, self.length))
249+
}
213250
}

0 commit comments

Comments
 (0)