fix: resolve #83 the text editor input content offset reset after input character issue
This commit is contained in:
parent
56bd6d0ae8
commit
6c973ed17c
|
@ -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 */,
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// ComposeStatusAttachmentTableViewCell.swift
|
||||
// ComposeStatusAttachmentCollectionViewCell.swift
|
||||
// Mastodon
|
||||
//
|
||||
// Created by MainasuK Cirno on 2021-3-17.
|
|
@ -91,7 +91,7 @@ extension ComposeStatusContentCollectionViewCell {
|
|||
|
||||
statusContentWarningEditorView.containerView.isHidden = true
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// MARK: - TextEditorViewChangeObserver
|
||||
|
|
|
@ -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
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue