Use PostBodyTitleView and PostBodyTextView for post editor

This commit is contained in:
Angelo Stavrow 2020-10-27 16:02:28 -04:00
parent 86cf0e976d
commit 3becfcbf73
No known key found for this signature in database
GPG Key ID: 1A49C7064E060EEE
4 changed files with 74 additions and 29 deletions

View File

@ -3,8 +3,8 @@ import CoreData
enum PostAppearance: String {
case sans = "OpenSans-Regular"
case mono = "Hack"
case serif = "Lora"
case mono = "Hack-Regular"
case serif = "Lora-Regular"
}
struct PostEditorModel {

View File

@ -24,6 +24,7 @@ struct PostBodyTextView: UIViewRepresentable {
@Binding var text: String
@Binding var textStyle: UIFont
@Binding var isFirstResponder: Bool
var lineSpacing: CGFloat
func makeUIView(context: UIViewRepresentableContext<PostBodyTextView>) -> UITextView {
let textView = UITextView(frame: .zero)
@ -40,7 +41,16 @@ struct PostBodyTextView: UIViewRepresentable {
}
func updateUIView(_ uiView: UITextView, context: UIViewRepresentableContext<PostBodyTextView>) {
uiView.text = text
let attributedString = NSMutableAttributedString(string: text)
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.lineSpacing = lineSpacing
attributedString.addAttribute(
NSAttributedString.Key.paragraphStyle,
value: paragraphStyle,
range: NSMakeRange(0, attributedString.length) // swiftlint:disable:this legacy_constructor
)
uiView.attributedText = attributedString
let font = textStyle
let fontMetrics = UIFontMetrics(forTextStyle: .largeTitle)
uiView.font = fontMetrics.scaledFont(for: font)

View File

@ -6,6 +6,11 @@ struct PostTextEditingView: View {
@Binding var updatingTitleFromServer: Bool
@Binding var updatingBodyFromServer: Bool
@State private var appearance: PostAppearance = .serif
@State private var titleTextStyle: UIFont = UIFont(name: "Lora-Regular", size: 26)!
@State private var titleTextHeight: CGFloat = 50
@State private var titleIsFirstResponder: Bool = true
@State private var bodyTextStyle: UIFont = UIFont(name: "Lora-Regular", size: 17)!
@State private var bodyIsFirstResponder: Bool = false
private let bodyLineSpacingMultiplier: CGFloat = 0.5
init(
@ -19,41 +24,69 @@ struct PostTextEditingView: View {
UITextView.appearance().backgroundColor = .clear
}
var titleFieldHeight: CGFloat {
let minHeight: CGFloat = 50
if titleTextHeight < minHeight {
return minHeight
}
return titleTextHeight
}
var body: some View {
VStack {
TextField("Title (optional)", text: $post.title)
.font(.custom(appearance.rawValue, size: 26, relativeTo: .largeTitle))
.padding(.horizontal, 4)
.onChange(of: post.title) { _ in
if post.status == PostStatus.published.rawValue && !updatingTitleFromServer {
post.status = PostStatus.edited.rawValue
}
}
ZStack(alignment: .topLeading) {
if post.body.count == 0 {
Text("Write…")
.font(.custom(appearance.rawValue, size: 17, relativeTo: .body))
if post.title.count == 0 {
Text("Title (optional)")
.font(Font(titleTextStyle))
.foregroundColor(Color(UIColor.placeholderText))
.padding(.horizontal, 4)
.padding(.vertical, 8)
}
TextEditor(text: $post.body)
.font(.custom(appearance.rawValue, size: 17, relativeTo: .body))
.lineSpacing(
17 * (
horizontalSizeClass == .compact ? bodyLineSpacingMultiplier / 2 : bodyLineSpacingMultiplier
)
)
.onChange(of: post.body) { _ in
if post.status == PostStatus.published.rawValue && !updatingBodyFromServer {
post.status = PostStatus.edited.rawValue
}
if updatingBodyFromServer {
updatingBodyFromServer = false
}
PostTitleTextView(
text: $post.title,
textStyle: $titleTextStyle,
height: $titleTextHeight,
isFirstResponder: $titleIsFirstResponder
)
.frame(height: titleFieldHeight)
.onChange(of: post.title) { _ in
if post.status == PostStatus.published.rawValue && !updatingTitleFromServer {
post.status = PostStatus.edited.rawValue
}
if updatingTitleFromServer {
updatingTitleFromServer = false
}
}
}
ZStack(alignment: .topLeading) {
if post.body.count == 0 {
Text("Write…")
.font(Font(bodyTextStyle))
.foregroundColor(Color(UIColor.placeholderText))
.padding(.horizontal, 4)
.padding(.vertical, 8)
}
PostBodyTextView(
text: $post.body,
textStyle: $bodyTextStyle,
isFirstResponder: $bodyIsFirstResponder,
lineSpacing: 17 * (
horizontalSizeClass == .compact ? bodyLineSpacingMultiplier / 2 : bodyLineSpacingMultiplier
)
)
.onChange(of: post.body) { _ in
if post.status == PostStatus.published.rawValue && !updatingBodyFromServer {
post.status = PostStatus.edited.rawValue
}
if updatingBodyFromServer {
updatingBodyFromServer = false
}
}
}
}
.onChange(of: titleIsFirstResponder, perform: { _ in
self.bodyIsFirstResponder.toggle()
})
.onAppear(perform: {
switch post.appearance {
case "sans":
@ -63,6 +96,8 @@ struct PostTextEditingView: View {
default:
self.appearance = .serif
}
self.titleTextStyle = UIFont(name: appearance.rawValue, size: 26)!
self.bodyTextStyle = UIFont(name: appearance.rawValue, size: 17)!
})
}
}

View File

@ -24,7 +24,7 @@ class Coordinator: NSObject, UITextViewDelegate, NSLayoutManagerDelegate {
}
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
if (text == "\n") {
if text == "\n" {
self.isFirstResponder.toggle()
return false
}