Skip to content

Commit ef47ee4

Browse files
authored
Support header style (#8)
* support header style * Fix header style behaving oddly with string with emoji * Using standard font size * Fix style is not setting when we add typing attributes
1 parent 28580a8 commit ef47ee4

File tree

12 files changed

+248
-158
lines changed

12 files changed

+248
-158
lines changed

RichEditorDemo/RichEditorDemo/ContentView.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ struct ContentView: View {
2828
VStack {
2929
RichEditor(state: _state)
3030
}
31-
.padding()
31+
.padding(10)
3232
.toolbar {
3333
ToolbarItem(placement: .topBarTrailing) {
3434
Button(action: {

RichEditorDemo/RichEditorDemo/Sample_json.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
},
2323
{
2424
"from": 52,
25-
"to": 61,
25+
"to": 59,
2626
"style": "italic"
2727
},
2828
{
@@ -87,7 +87,7 @@
8787
},
8888
{
8989
"from": 237,
90-
"to": 251,
90+
"to": 250,
9191
"style": "h4"
9292
},
9393
{

Sources/RichEditorSwiftUI/Attributes/RichTextAttributeWriter+Style.swift

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
//
77

88
import Foundation
9+
import UIKit
910

1011
public extension NSMutableAttributedString {
1112

@@ -34,19 +35,31 @@ public extension NSMutableAttributedString {
3435
let shouldAdd = newValue && !styles.hasStyle(style)
3536
let shouldRemove = !newValue && styles.hasStyle(style)
3637
guard shouldAdd || shouldRemove || style.isHeaderStyle else { return }
37-
let newFont: FontRepresentable? = FontRepresentable(
38-
descriptor: font.fontDescriptor.byTogglingStyle(style),
39-
size: byTogglingFontSizeFor(style: style, fontSize: font.pointSize, shouldAdd: newValue))
40-
guard let newFont = newFont else { return }
41-
setRichTextFont(newFont, at: range)
38+
var descriptor = font.fontDescriptor
39+
if !style.isDefault && !style.isHeaderStyle {
40+
descriptor = descriptor.byTogglingStyle(style)
41+
}
42+
let newFont: FontRepresentable? = FontRepresentable(
43+
descriptor: descriptor,
44+
size: byTogglingFontSizeFor(style: style, font: font, shouldAdd: newValue))
45+
guard let newFont = newFont else { return }
46+
setRichTextFont(newFont, at: range)
4247
}
4348

44-
private func byTogglingFontSizeFor(style: TextSpanStyle, fontSize: CGFloat, shouldAdd: Bool) -> CGFloat {
45-
guard style.isHeaderStyle else { return fontSize }
49+
/**
50+
This will reset font size befor multiplying new size
51+
*/
52+
private func byTogglingFontSizeFor(style: TextSpanStyle, font: UIFont, shouldAdd: Bool) -> CGFloat {
53+
guard style.isHeaderStyle || style.isDefault else { return font.pointSize }
54+
55+
let cleanFont = style.getFontAfterRemovingStyle(font: font)
56+
// if style.isDefault {
57+
// return cleanFont.pointSize
58+
// }
4659
if shouldAdd {
47-
return fontSize * style.fontSizeMultiplier
60+
return cleanFont.pointSize * style.fontSizeMultiplier
4861
} else {
49-
return fontSize / style.fontSizeMultiplier
62+
return font.pointSize / style.fontSizeMultiplier
5063
}
5164
}
5265
}

Sources/RichEditorSwiftUI/Fonts/FontRepresentable.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,14 @@ import AppKit
2424
*/
2525
public typealias FontRepresentable = NSFont
2626
#endif
27+
28+
public extension FontRepresentable {
29+
30+
/**
31+
The standard font to use for rich text.
32+
33+
You can change this value to affect all types that make
34+
use of the value.
35+
*/
36+
static var standardRichTextFont = systemFont(ofSize: .standardRichTextFontSize)
37+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
//
2+
// StandardFontSizeProvider.swift
3+
//
4+
//
5+
// Created by Divyesh Vekariya on 12/01/24.
6+
//
7+
8+
import Foundation
9+
10+
public protocol StandardFontSizeProvider {}
11+
12+
extension CGFloat: StandardFontSizeProvider {}
13+
14+
extension Double: StandardFontSizeProvider {}
15+
16+
extension RichEditorState: StandardFontSizeProvider {}
17+
18+
#if iOS || macOS || os(tvOS)
19+
extension RichTextEditor: StandardFontSizeProvider {}
20+
21+
extension RichTextView: StandardFontSizeProvider {}
22+
#endif
23+
24+
public extension StandardFontSizeProvider {
25+
26+
/**
27+
The standard font size to use for rich text.
28+
29+
You can change this value to affect all types that make
30+
use of this value.
31+
*/
32+
static var standardRichTextFontSize: CGFloat {
33+
get { StandardFontSizeProviderStorage.standardRichTextFontSize }
34+
set { StandardFontSizeProviderStorage.standardRichTextFontSize = newValue }
35+
}
36+
}
37+
38+
private class StandardFontSizeProviderStorage {
39+
40+
static var standardRichTextFontSize: CGFloat = 16
41+
}

Sources/RichEditorSwiftUI/UI/Editor/RichEditor.swift

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,13 @@ public struct RichEditor: View {
1616

1717
public var body: some View {
1818
VStack(content: {
19-
EditorToolBarView(appliedTools: state.activeStyles,
20-
onToolSelect: state.onToolSelection(_:))
19+
EditorToolBarView(state: state)
2120

2221
TextViewWrapper(state: _state,
23-
typingAttributes: $state.activeAttributes,
2422
attributesToApply: $state.attributesToApply,
2523
isScrollEnabled: true,
2624
fontStyle: state.curretFont,
2725
onTextViewEvent: state.onTextViewEvent(_:))
2826
})
29-
.padding()
3027
}
3128
}

0 commit comments

Comments
 (0)