fix: resolve #83 the text editor input content offset reset after input character issue

This commit is contained in:
CMK 2021-04-14 18:11:59 +08:00
parent 56bd6d0ae8
commit 6c973ed17c
5 changed files with 48 additions and 25 deletions

View File

@ -220,7 +220,7 @@
DB68A05D25E9055900CFDF14 /* Settings.bundle in Resources */ = {isa = PBXBuildFile; fileRef = DB68A05C25E9055900CFDF14 /* Settings.bundle */; };
DB68A06325E905E000CFDF14 /* UIApplication.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB68A06225E905E000CFDF14 /* UIApplication.swift */; };
DB6B35182601FA3400DC1E11 /* MastodonAttachmentService.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB6B35172601FA3400DC1E11 /* MastodonAttachmentService.swift */; };
DB6B351E2601FAEE00DC1E11 /* ComposeStatusAttachmentTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB6B351D2601FAEE00DC1E11 /* ComposeStatusAttachmentTableViewCell.swift */; };
DB6B351E2601FAEE00DC1E11 /* ComposeStatusAttachmentCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB6B351D2601FAEE00DC1E11 /* ComposeStatusAttachmentCollectionViewCell.swift */; };
DB6C8C0F25F0A6AE00AAA452 /* Mastodon+Entity+Error.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB6C8C0E25F0A6AE00AAA452 /* Mastodon+Entity+Error.swift */; };
DB71FD2C25F86A5100512AE1 /* AvatarStackContainerButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB71FD2B25F86A5100512AE1 /* AvatarStackContainerButton.swift */; };
DB71FD3625F8A16C00512AE1 /* APIService+Persist+PersistMemo.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB71FD3525F8A16C00512AE1 /* APIService+Persist+PersistMemo.swift */; };
@ -618,7 +618,7 @@
DB68A05C25E9055900CFDF14 /* Settings.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = Settings.bundle; sourceTree = "<group>"; };
DB68A06225E905E000CFDF14 /* UIApplication.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIApplication.swift; sourceTree = "<group>"; };
DB6B35172601FA3400DC1E11 /* MastodonAttachmentService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MastodonAttachmentService.swift; sourceTree = "<group>"; };
DB6B351D2601FAEE00DC1E11 /* ComposeStatusAttachmentTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposeStatusAttachmentTableViewCell.swift; sourceTree = "<group>"; };
DB6B351D2601FAEE00DC1E11 /* ComposeStatusAttachmentCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposeStatusAttachmentCollectionViewCell.swift; sourceTree = "<group>"; };
DB6C8C0E25F0A6AE00AAA452 /* Mastodon+Entity+Error.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Mastodon+Entity+Error.swift"; sourceTree = "<group>"; };
DB71FD2B25F86A5100512AE1 /* AvatarStackContainerButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AvatarStackContainerButton.swift; sourceTree = "<group>"; };
DB71FD3525F8A16C00512AE1 /* APIService+Persist+PersistMemo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "APIService+Persist+PersistMemo.swift"; sourceTree = "<group>"; };
@ -1458,7 +1458,7 @@
children = (
DB789A2A25F9F7AB0071ACA0 /* ComposeRepliedToStatusContentCollectionViewCell.swift */,
DB789A1B25F9F76A0071ACA0 /* ComposeStatusContentCollectionViewCell.swift */,
DB6B351D2601FAEE00DC1E11 /* ComposeStatusAttachmentTableViewCell.swift */,
DB6B351D2601FAEE00DC1E11 /* ComposeStatusAttachmentCollectionViewCell.swift */,
DB87D4442609BE0500D12C0D /* ComposeStatusPollOptionCollectionViewCell.swift */,
DB87D4502609CF1E00D12C0D /* ComposeStatusPollOptionAppendEntryCollectionViewCell.swift */,
DB2FF50F260B113300ADA9FE /* ComposeStatusPollExpiresOptionCollectionViewCell.swift */,
@ -2296,7 +2296,7 @@
0FAA101C25E10E760017CCDE /* UIFont.swift in Sources */,
2D38F1D525CD465300561493 /* HomeTimelineViewController.swift in Sources */,
DB98338825C945ED00AD9700 /* Assets.swift in Sources */,
DB6B351E2601FAEE00DC1E11 /* ComposeStatusAttachmentTableViewCell.swift in Sources */,
DB6B351E2601FAEE00DC1E11 /* ComposeStatusAttachmentCollectionViewCell.swift in Sources */,
2DA7D04425CA52B200804E11 /* TimelineLoaderTableViewCell.swift in Sources */,
DB87D44B2609C11900D12C0D /* PollOptionView.swift in Sources */,
DBE3CDFB261C6CA500430CC6 /* FavoriteViewModel.swift in Sources */,

View File

@ -92,7 +92,12 @@ extension ComposeStatusSection {
.receive(on: DispatchQueue.main)
.sink { text in
// self size input cell
// needs restore content offset to resolve issue #83
let oldContentOffset = collectionView.contentOffset
collectionView.collectionViewLayout.invalidateLayout()
collectionView.layoutIfNeeded()
collectionView.contentOffset = oldContentOffset
// bind input data
attribute.composeContent.value = text
}
@ -187,6 +192,7 @@ extension ComposeStatusSection {
case .pollOption(let attribute):
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: String(describing: ComposeStatusPollOptionCollectionViewCell.self), for: indexPath) as! ComposeStatusPollOptionCollectionViewCell
cell.pollOptionView.optionTextField.text = attribute.option.value
cell.pollOptionView.optionTextField.placeholder = L10n.Scene.Compose.Poll.optionNumber(indexPath.item + 1)
cell.pollOption
.receive(on: DispatchQueue.main)
.assign(to: \.value, on: attribute.option)

View File

@ -1,5 +1,5 @@
//
// ComposeStatusAttachmentTableViewCell.swift
// ComposeStatusAttachmentCollectionViewCell.swift
// Mastodon
//
// Created by MainasuK Cirno on 2021-3-17.

View File

@ -91,7 +91,7 @@ extension ComposeStatusContentCollectionViewCell {
statusContentWarningEditorView.containerView.isHidden = true
}
}
// MARK: - TextEditorViewChangeObserver

View File

@ -68,18 +68,7 @@ final class ComposeViewController: UIViewController, NeedsDependency {
let composeToolbarView = ComposeToolbarView()
var composeToolbarViewBottomLayoutConstraint: NSLayoutConstraint!
let composeToolbarBackgroundView: UIView = {
let backgroundView = UIView()
// set keyboard background to make the keyboard blurred color fixed
backgroundView.backgroundColor = UIColor(dynamicProvider: { traitCollection -> UIColor in
// avoid elevated color
switch traitCollection.userInterfaceStyle {
case .light: return .white
default: return .black
}
})
return backgroundView
}()
let composeToolbarBackgroundView = UIView()
private(set) lazy var imagePicker: PHPickerViewController = {
var configuration = PHPickerConfiguration()
@ -202,14 +191,27 @@ extension ComposeViewController {
)
.sink(receiveValue: { [weak self] isShow, state, endFrame, isCustomEmojiComposing in
guard let self = self else { return }
let extraMargin: CGFloat = {
if self.view.safeAreaInsets.bottom == .zero {
// needs extra margin for zero inset device to workaround UIKit issue
return self.composeToolbarView.frame.height
} else {
// default some magic 16 extra margin
return 16
}
}()
// update keyboard background color
guard isShow, state == .dock else {
self.collectionView.contentInset.bottom = self.view.safeAreaInsets.bottom
self.collectionView.verticalScrollIndicatorInsets.bottom = self.view.safeAreaInsets.bottom
self.collectionView.contentInset.bottom = self.view.safeAreaInsets.bottom + extraMargin
self.collectionView.verticalScrollIndicatorInsets.bottom = self.view.safeAreaInsets.bottom + extraMargin
UIView.animate(withDuration: 0.3) {
self.composeToolbarViewBottomLayoutConstraint.constant = self.view.safeAreaInsets.bottom
self.view.layoutIfNeeded()
}
self.updateKeyboardBackground(isKeyboardDisplay: isShow)
return
}
// isShow AND dock state
@ -218,22 +220,23 @@ extension ComposeViewController {
let contentFrame = self.view.convert(self.collectionView.frame, to: nil)
let padding = contentFrame.maxY - endFrame.minY
guard padding > 0 else {
self.collectionView.contentInset.bottom = self.view.safeAreaInsets.bottom
self.collectionView.verticalScrollIndicatorInsets.bottom = self.view.safeAreaInsets.bottom
self.collectionView.contentInset.bottom = self.view.safeAreaInsets.bottom + extraMargin
self.collectionView.verticalScrollIndicatorInsets.bottom = self.view.safeAreaInsets.bottom + extraMargin
UIView.animate(withDuration: 0.3) {
self.composeToolbarViewBottomLayoutConstraint.constant = self.view.safeAreaInsets.bottom
self.view.layoutIfNeeded()
}
self.updateKeyboardBackground(isKeyboardDisplay: false)
return
}
// add 16pt margin
self.collectionView.contentInset.bottom = padding + 16
self.collectionView.verticalScrollIndicatorInsets.bottom = padding + 16
self.collectionView.contentInset.bottom = padding + extraMargin
self.collectionView.verticalScrollIndicatorInsets.bottom = padding + extraMargin
UIView.animate(withDuration: 0.3) {
self.composeToolbarViewBottomLayoutConstraint.constant = padding
self.view.layoutIfNeeded()
}
self.updateKeyboardBackground(isKeyboardDisplay: isShow)
})
.store(in: &disposeBag)
@ -473,6 +476,20 @@ extension ComposeViewController {
imagePicker.delegate = self
return imagePicker
}
private func updateKeyboardBackground(isKeyboardDisplay: Bool) {
guard isKeyboardDisplay else {
composeToolbarBackgroundView.backgroundColor = Asset.Scene.Compose.toolbarBackground.color
return
}
composeToolbarBackgroundView.backgroundColor = UIColor(dynamicProvider: { traitCollection -> UIColor in
// avoid elevated color
switch traitCollection.userInterfaceStyle {
case .light: return .white
default: return .black
}
})
}
}