mirror of
https://github.com/writeas/writefreely-swiftui-multiplatform.git
synced 2024-11-15 01:11:02 +00:00
Embed text editor fields into ScrollView (#227)
* Embed text editor fields into ScrollView * Bump version/build number and update change log * Fix truncated post badges on status change When going from a shorter label (e.g., ‘LOCAL’) to a longer one (e.g., ‘PUBLISHED’), the SwiftUI render loop would not expand the size of the post badge to fit the extra characters, so on change it would be truncated (e.g., read ‘PUBL…’). This change fixes the bug.
This commit is contained in:
parent
884da073e9
commit
4a3874abcd
@ -21,7 +21,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- [Mac] New drafts are created in the currently-selected blog, rather than being created in Drafts (or "Anonymous" for Write.as accounts).
|
- [Mac] New drafts are created in the currently-selected blog, rather than being created in Drafts (or "Anonymous" for Write.as accounts).
|
||||||
- [Mac] Updated the URL and minimum version of the WriteFreely Swift package.
|
- [Mac] Updated the URL and minimum version of the WriteFreely Swift package.
|
||||||
- [Mac] Upgraded the Sparkle package to v2.
|
- [Mac] Upgraded the Sparkle package to v2.
|
||||||
- [Mac] The app now prompts you to reach out to our user forums if it detects a crash
|
- [Mac] The app now prompts you to reach out to our user forums if it detects a crash.
|
||||||
|
- [iOS] The post editor now scrolls in its entirety, including the title field.
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@ struct PostStatusBadgeView: View {
|
|||||||
.padding(EdgeInsets(top: 2.5, leading: 7.5, bottom: 2.5, trailing: 7.5))
|
.padding(EdgeInsets(top: 2.5, leading: 7.5, bottom: 2.5, trailing: 7.5))
|
||||||
.background(badgeColor)
|
.background(badgeColor)
|
||||||
.clipShape(RoundedRectangle(cornerRadius: 5.0, style: .circular))
|
.clipShape(RoundedRectangle(cornerRadius: 5.0, style: .circular))
|
||||||
|
.frame(width: .infinity)
|
||||||
}
|
}
|
||||||
|
|
||||||
func setupBadgeProperties(for status: PostStatus) -> (String, Color) {
|
func setupBadgeProperties(for status: PostStatus) -> (String, Color) {
|
||||||
|
@ -1054,7 +1054,7 @@
|
|||||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
|
||||||
CODE_SIGN_ENTITLEMENTS = "ActionExtension-iOS/ActionExtension-iOS.entitlements";
|
CODE_SIGN_ENTITLEMENTS = "ActionExtension-iOS/ActionExtension-iOS.entitlements";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 676;
|
CURRENT_PROJECT_VERSION = 679;
|
||||||
DEVELOPMENT_TEAM = TPPAB4YBA6;
|
DEVELOPMENT_TEAM = TPPAB4YBA6;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
INFOPLIST_FILE = "ActionExtension-iOS/Info.plist";
|
INFOPLIST_FILE = "ActionExtension-iOS/Info.plist";
|
||||||
@ -1066,7 +1066,7 @@
|
|||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
"@executable_path/../../Frameworks",
|
"@executable_path/../../Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.0.11;
|
MARKETING_VERSION = 1.0.12;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = "com.abunchtell.WriteFreely-MultiPlatform.ActionExtension-iOS";
|
PRODUCT_BUNDLE_IDENTIFIER = "com.abunchtell.WriteFreely-MultiPlatform.ActionExtension-iOS";
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SDKROOT = iphoneos;
|
SDKROOT = iphoneos;
|
||||||
@ -1085,7 +1085,7 @@
|
|||||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
|
||||||
CODE_SIGN_ENTITLEMENTS = "ActionExtension-iOS/ActionExtension-iOS.entitlements";
|
CODE_SIGN_ENTITLEMENTS = "ActionExtension-iOS/ActionExtension-iOS.entitlements";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 676;
|
CURRENT_PROJECT_VERSION = 679;
|
||||||
DEVELOPMENT_TEAM = TPPAB4YBA6;
|
DEVELOPMENT_TEAM = TPPAB4YBA6;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
INFOPLIST_FILE = "ActionExtension-iOS/Info.plist";
|
INFOPLIST_FILE = "ActionExtension-iOS/Info.plist";
|
||||||
@ -1097,7 +1097,7 @@
|
|||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
"@executable_path/../../Frameworks",
|
"@executable_path/../../Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.0.11;
|
MARKETING_VERSION = 1.0.12;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = "com.abunchtell.WriteFreely-MultiPlatform.ActionExtension-iOS";
|
PRODUCT_BUNDLE_IDENTIFIER = "com.abunchtell.WriteFreely-MultiPlatform.ActionExtension-iOS";
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SDKROOT = iphoneos;
|
SDKROOT = iphoneos;
|
||||||
@ -1228,7 +1228,7 @@
|
|||||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||||
CODE_SIGN_ENTITLEMENTS = "WriteFreely-MultiPlatform (iOS).entitlements";
|
CODE_SIGN_ENTITLEMENTS = "WriteFreely-MultiPlatform (iOS).entitlements";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 676;
|
CURRENT_PROJECT_VERSION = 679;
|
||||||
DEVELOPMENT_TEAM = TPPAB4YBA6;
|
DEVELOPMENT_TEAM = TPPAB4YBA6;
|
||||||
ENABLE_PREVIEWS = YES;
|
ENABLE_PREVIEWS = YES;
|
||||||
INFOPLIST_FILE = iOS/Info.plist;
|
INFOPLIST_FILE = iOS/Info.plist;
|
||||||
@ -1237,7 +1237,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.0.11;
|
MARKETING_VERSION = 1.0.12;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = "com.abunchtell.WriteFreely-MultiPlatform";
|
PRODUCT_BUNDLE_IDENTIFIER = "com.abunchtell.WriteFreely-MultiPlatform";
|
||||||
PRODUCT_NAME = "WriteFreely-MultiPlatform";
|
PRODUCT_NAME = "WriteFreely-MultiPlatform";
|
||||||
SDKROOT = iphoneos;
|
SDKROOT = iphoneos;
|
||||||
@ -1254,7 +1254,7 @@
|
|||||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||||
CODE_SIGN_ENTITLEMENTS = "WriteFreely-MultiPlatform (iOS).entitlements";
|
CODE_SIGN_ENTITLEMENTS = "WriteFreely-MultiPlatform (iOS).entitlements";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 676;
|
CURRENT_PROJECT_VERSION = 679;
|
||||||
DEVELOPMENT_TEAM = TPPAB4YBA6;
|
DEVELOPMENT_TEAM = TPPAB4YBA6;
|
||||||
ENABLE_PREVIEWS = YES;
|
ENABLE_PREVIEWS = YES;
|
||||||
INFOPLIST_FILE = iOS/Info.plist;
|
INFOPLIST_FILE = iOS/Info.plist;
|
||||||
@ -1263,7 +1263,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.0.11;
|
MARKETING_VERSION = 1.0.12;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = "com.abunchtell.WriteFreely-MultiPlatform";
|
PRODUCT_BUNDLE_IDENTIFIER = "com.abunchtell.WriteFreely-MultiPlatform";
|
||||||
PRODUCT_NAME = "WriteFreely-MultiPlatform";
|
PRODUCT_NAME = "WriteFreely-MultiPlatform";
|
||||||
SDKROOT = iphoneos;
|
SDKROOT = iphoneos;
|
||||||
|
@ -21,6 +21,20 @@ class PostBodyCoordinator: NSObject, UITextViewDelegate, NSLayoutManagerDelegate
|
|||||||
_text = text
|
_text = text
|
||||||
_isFirstResponder = isFirstResponder
|
_isFirstResponder = isFirstResponder
|
||||||
self.lineSpacingMultiplier = lineSpacingMultiplier
|
self.lineSpacingMultiplier = lineSpacingMultiplier
|
||||||
|
|
||||||
|
super.init()
|
||||||
|
|
||||||
|
updateSize()
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateSize() {
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
guard let view = self.textView else { return }
|
||||||
|
let size = view.sizeThatFits(view.bounds.size)
|
||||||
|
if self.postBodyTextView.height != size.height {
|
||||||
|
self.postBodyTextView.height = size.height
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func textViewDidChange(_ textView: UITextView) {
|
func textViewDidChange(_ textView: UITextView) {
|
||||||
@ -34,6 +48,14 @@ class PostBodyCoordinator: NSObject, UITextViewDelegate, NSLayoutManagerDelegate
|
|||||||
self.didBecomeFirstResponder = false
|
self.didBecomeFirstResponder = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func layoutManager(
|
||||||
|
_ layoutManager: NSLayoutManager,
|
||||||
|
didCompleteLayoutFor textContainer: NSTextContainer?,
|
||||||
|
atEnd layoutFinishedFlag: Bool
|
||||||
|
) {
|
||||||
|
updateSize()
|
||||||
|
}
|
||||||
|
|
||||||
func layoutManager(
|
func layoutManager(
|
||||||
_ layoutManager: NSLayoutManager,
|
_ layoutManager: NSLayoutManager,
|
||||||
lineSpacingAfterGlyphAt glyphIndex: Int,
|
lineSpacingAfterGlyphAt glyphIndex: Int,
|
||||||
@ -59,6 +81,7 @@ class PostBodyCoordinator: NSObject, UITextViewDelegate, NSLayoutManagerDelegate
|
|||||||
struct PostBodyTextView: UIViewRepresentable {
|
struct PostBodyTextView: UIViewRepresentable {
|
||||||
@Binding var text: String
|
@Binding var text: String
|
||||||
@Binding var textStyle: UIFont
|
@Binding var textStyle: UIFont
|
||||||
|
@Binding var height: CGFloat
|
||||||
@Binding var isFirstResponder: Bool
|
@Binding var isFirstResponder: Bool
|
||||||
@State var lineSpacing: CGFloat
|
@State var lineSpacing: CGFloat
|
||||||
|
|
||||||
|
@ -8,10 +8,12 @@ struct PostTextEditingView: View {
|
|||||||
@State private var appearance: PostAppearance = .serif
|
@State private var appearance: PostAppearance = .serif
|
||||||
@State private var titleTextStyle: UIFont = UIFont(name: "Lora-Regular", size: 26)!
|
@State private var titleTextStyle: UIFont = UIFont(name: "Lora-Regular", size: 26)!
|
||||||
@State private var titleTextHeight: CGFloat = 50
|
@State private var titleTextHeight: CGFloat = 50
|
||||||
|
@State private var bodyTextHeight: CGFloat = 50
|
||||||
@State private var titleIsFirstResponder: Bool = true
|
@State private var titleIsFirstResponder: Bool = true
|
||||||
@State private var bodyTextStyle: UIFont = UIFont(name: "Lora-Regular", size: 17)!
|
@State private var bodyTextStyle: UIFont = UIFont(name: "Lora-Regular", size: 17)!
|
||||||
@State private var bodyIsFirstResponder: Bool = false
|
@State private var bodyIsFirstResponder: Bool = false
|
||||||
private let lineSpacingMultiplier: CGFloat = 0.5
|
private let lineSpacingMultiplier: CGFloat = 0.5
|
||||||
|
private let textEditorHeight: CGFloat = 50
|
||||||
|
|
||||||
init(
|
init(
|
||||||
post: ObservedObject<WFAPost>,
|
post: ObservedObject<WFAPost>,
|
||||||
@ -25,15 +27,22 @@ struct PostTextEditingView: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var titleFieldHeight: CGFloat {
|
var titleFieldHeight: CGFloat {
|
||||||
let minHeight: CGFloat = 50
|
let minHeight: CGFloat = textEditorHeight
|
||||||
if titleTextHeight < minHeight {
|
if titleTextHeight < minHeight {
|
||||||
return minHeight
|
return minHeight
|
||||||
}
|
}
|
||||||
return titleTextHeight
|
return titleTextHeight
|
||||||
}
|
}
|
||||||
|
var bodyFieldHeight: CGFloat {
|
||||||
|
let minHeight: CGFloat = textEditorHeight
|
||||||
|
if bodyTextHeight < minHeight {
|
||||||
|
return minHeight
|
||||||
|
}
|
||||||
|
return bodyTextHeight
|
||||||
|
}
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
VStack {
|
ScrollView(.vertical) {
|
||||||
ZStack(alignment: .topLeading) {
|
ZStack(alignment: .topLeading) {
|
||||||
if post.title.count == 0 {
|
if post.title.count == 0 {
|
||||||
Text("Title (optional)")
|
Text("Title (optional)")
|
||||||
@ -74,9 +83,11 @@ struct PostTextEditingView: View {
|
|||||||
PostBodyTextView(
|
PostBodyTextView(
|
||||||
text: $post.body,
|
text: $post.body,
|
||||||
textStyle: $bodyTextStyle,
|
textStyle: $bodyTextStyle,
|
||||||
|
height: $bodyTextHeight,
|
||||||
isFirstResponder: $bodyIsFirstResponder,
|
isFirstResponder: $bodyIsFirstResponder,
|
||||||
lineSpacing: horizontalSizeClass == .compact ? lineSpacingMultiplier / 2 : lineSpacingMultiplier
|
lineSpacing: horizontalSizeClass == .compact ? lineSpacingMultiplier / 2 : lineSpacingMultiplier
|
||||||
)
|
)
|
||||||
|
.frame(height: bodyFieldHeight)
|
||||||
.accessibilityLabel(Text("Body"))
|
.accessibilityLabel(Text("Body"))
|
||||||
.accessibilityHint(Text("Add or edit the body of your post"))
|
.accessibilityHint(Text("Add or edit the body of your post"))
|
||||||
.onChange(of: post.body) { _ in
|
.onChange(of: post.body) { _ in
|
||||||
|
Loading…
Reference in New Issue
Block a user