diff --git a/Shared/PostEditor/PostEditorModel.swift b/Shared/PostEditor/PostEditorModel.swift index ca8959f..84e774c 100644 --- a/Shared/PostEditor/PostEditorModel.swift +++ b/Shared/PostEditor/PostEditorModel.swift @@ -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 { diff --git a/iOS/PostEditor/PostBodyTextView.swift b/iOS/PostEditor/PostBodyTextView.swift index ba7713c..2de4636 100644 --- a/iOS/PostEditor/PostBodyTextView.swift +++ b/iOS/PostEditor/PostBodyTextView.swift @@ -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) -> UITextView { let textView = UITextView(frame: .zero) @@ -40,7 +41,16 @@ struct PostBodyTextView: UIViewRepresentable { } func updateUIView(_ uiView: UITextView, context: UIViewRepresentableContext) { - 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) diff --git a/iOS/PostEditor/PostTextEditingView.swift b/iOS/PostEditor/PostTextEditingView.swift index c24530e..0f85e84 100644 --- a/iOS/PostEditor/PostTextEditingView.swift +++ b/iOS/PostEditor/PostTextEditingView.swift @@ -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)! }) } } diff --git a/iOS/PostEditor/PostTitleTextView.swift b/iOS/PostEditor/PostTitleTextView.swift index c29f843..434722c 100644 --- a/iOS/PostEditor/PostTitleTextView.swift +++ b/iOS/PostEditor/PostTitleTextView.swift @@ -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 }