fix: compose scene layout issue when presenting reply post
This commit is contained in:
parent
e3c6aaf64e
commit
f7aa5c123d
@ -81,10 +81,10 @@ extension ComposeStatusSection {
|
|||||||
managedObjectContext.perform {
|
managedObjectContext.perform {
|
||||||
guard let replyToStatusObjectID = replyToStatusObjectID,
|
guard let replyToStatusObjectID = replyToStatusObjectID,
|
||||||
let replyTo = managedObjectContext.object(with: replyToStatusObjectID) as? Status else {
|
let replyTo = managedObjectContext.object(with: replyToStatusObjectID) as? Status else {
|
||||||
cell.statusView.headerContainerStackView.isHidden = true
|
cell.statusView.headerContainerView.isHidden = true
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
cell.statusView.headerContainerStackView.isHidden = false
|
cell.statusView.headerContainerView.isHidden = false
|
||||||
cell.statusView.headerIconLabel.attributedText = StatusView.iconAttributedString(image: StatusView.replyIconImage)
|
cell.statusView.headerIconLabel.attributedText = StatusView.iconAttributedString(image: StatusView.replyIconImage)
|
||||||
cell.statusView.headerInfoLabel.text = L10n.Scene.Compose.replyingToUser(replyTo.author.displayNameWithFallback)
|
cell.statusView.headerInfoLabel.text = L10n.Scene.Compose.replyingToUser(replyTo.author.displayNameWithFallback)
|
||||||
}
|
}
|
||||||
|
@ -525,7 +525,7 @@ extension StatusSection {
|
|||||||
status: Status
|
status: Status
|
||||||
) {
|
) {
|
||||||
if status.reblog != nil {
|
if status.reblog != nil {
|
||||||
cell.statusView.headerContainerStackView.isHidden = false
|
cell.statusView.headerContainerView.isHidden = false
|
||||||
cell.statusView.headerIconLabel.attributedText = StatusView.iconAttributedString(image: StatusView.reblogIconImage)
|
cell.statusView.headerIconLabel.attributedText = StatusView.iconAttributedString(image: StatusView.reblogIconImage)
|
||||||
cell.statusView.headerInfoLabel.text = {
|
cell.statusView.headerInfoLabel.text = {
|
||||||
let author = status.author
|
let author = status.author
|
||||||
@ -533,7 +533,7 @@ extension StatusSection {
|
|||||||
return L10n.Common.Controls.Status.userReblogged(name)
|
return L10n.Common.Controls.Status.userReblogged(name)
|
||||||
}()
|
}()
|
||||||
} else if status.inReplyToID != nil {
|
} else if status.inReplyToID != nil {
|
||||||
cell.statusView.headerContainerStackView.isHidden = false
|
cell.statusView.headerContainerView.isHidden = false
|
||||||
cell.statusView.headerIconLabel.attributedText = StatusView.iconAttributedString(image: StatusView.replyIconImage)
|
cell.statusView.headerIconLabel.attributedText = StatusView.iconAttributedString(image: StatusView.replyIconImage)
|
||||||
cell.statusView.headerInfoLabel.text = {
|
cell.statusView.headerInfoLabel.text = {
|
||||||
guard let replyTo = status.replyTo else {
|
guard let replyTo = status.replyTo else {
|
||||||
@ -544,7 +544,7 @@ extension StatusSection {
|
|||||||
return L10n.Common.Controls.Status.userRepliedTo(name)
|
return L10n.Common.Controls.Status.userRepliedTo(name)
|
||||||
}()
|
}()
|
||||||
} else {
|
} else {
|
||||||
cell.statusView.headerContainerStackView.isHidden = true
|
cell.statusView.headerContainerView.isHidden = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,4 +12,9 @@ extension NSLayoutConstraint {
|
|||||||
self.priority = priority
|
self.priority = priority
|
||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func identifier(_ identifier: String?) -> Self {
|
||||||
|
self.identifier = identifier
|
||||||
|
return self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -45,16 +45,16 @@ extension ComposeRepliedToStatusContentCollectionViewCell {
|
|||||||
private func _init() {
|
private func _init() {
|
||||||
backgroundColor = .clear
|
backgroundColor = .clear
|
||||||
|
|
||||||
|
statusView.actionToolbarContainer.isHidden = true
|
||||||
|
|
||||||
statusView.translatesAutoresizingMaskIntoConstraints = false
|
statusView.translatesAutoresizingMaskIntoConstraints = false
|
||||||
contentView.addSubview(statusView)
|
contentView.addSubview(statusView)
|
||||||
NSLayoutConstraint.activate([
|
NSLayoutConstraint.activate([
|
||||||
statusView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 20),
|
statusView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 20).identifier("statusView.top to ComposeRepliedToStatusContentCollectionViewCell.contentView.top"),
|
||||||
statusView.leadingAnchor.constraint(equalTo: contentView.readableContentGuide.leadingAnchor),
|
statusView.leadingAnchor.constraint(equalTo: contentView.readableContentGuide.leadingAnchor),
|
||||||
contentView.readableContentGuide.trailingAnchor.constraint(equalTo: statusView.trailingAnchor),
|
contentView.readableContentGuide.trailingAnchor.constraint(equalTo: statusView.trailingAnchor),
|
||||||
contentView.bottomAnchor.constraint(equalTo: statusView.bottomAnchor, constant: 10),
|
contentView.bottomAnchor.constraint(equalTo: statusView.bottomAnchor, constant: 10).identifier("ComposeRepliedToStatusContentCollectionViewCell.contentView.bottom to statusView.bottom"),
|
||||||
])
|
])
|
||||||
|
|
||||||
statusView.actionToolbarContainer.isHidden = true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -182,7 +182,7 @@ extension ComposeViewController {
|
|||||||
)
|
)
|
||||||
|
|
||||||
// respond scrollView overlap change
|
// respond scrollView overlap change
|
||||||
view.layoutIfNeeded()
|
//view.layoutIfNeeded()
|
||||||
// update layout when keyboard show/dismiss
|
// update layout when keyboard show/dismiss
|
||||||
Publishers.CombineLatest4(
|
Publishers.CombineLatest4(
|
||||||
KeyboardResponderService.shared.isShow.eraseToAnyPublisher(),
|
KeyboardResponderService.shared.isShow.eraseToAnyPublisher(),
|
||||||
@ -210,8 +210,10 @@ extension ComposeViewController {
|
|||||||
self.collectionView.verticalScrollIndicatorInsets.bottom = self.view.safeAreaInsets.bottom + extraMargin
|
self.collectionView.verticalScrollIndicatorInsets.bottom = self.view.safeAreaInsets.bottom + extraMargin
|
||||||
UIView.animate(withDuration: 0.3) {
|
UIView.animate(withDuration: 0.3) {
|
||||||
self.composeToolbarViewBottomLayoutConstraint.constant = self.view.safeAreaInsets.bottom
|
self.composeToolbarViewBottomLayoutConstraint.constant = self.view.safeAreaInsets.bottom
|
||||||
|
if self.view.window != nil {
|
||||||
self.view.layoutIfNeeded()
|
self.view.layoutIfNeeded()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
self.updateKeyboardBackground(isKeyboardDisplay: isShow)
|
self.updateKeyboardBackground(isKeyboardDisplay: isShow)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
// Created by xiaojian sun on 2021/3/10.
|
// Created by xiaojian sun on 2021/3/10.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
import os.log
|
||||||
import AVKit
|
import AVKit
|
||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
@ -93,6 +94,7 @@ extension PlayerContainerView {
|
|||||||
// MARK: - ContentWarningOverlayViewDelegate
|
// MARK: - ContentWarningOverlayViewDelegate
|
||||||
extension PlayerContainerView: ContentWarningOverlayViewDelegate {
|
extension PlayerContainerView: ContentWarningOverlayViewDelegate {
|
||||||
func contentWarningOverlayViewDidPressed(_ contentWarningOverlayView: ContentWarningOverlayView) {
|
func contentWarningOverlayViewDidPressed(_ contentWarningOverlayView: ContentWarningOverlayView) {
|
||||||
|
os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function)
|
||||||
delegate?.playerContainerView(self, contentWarningOverlayViewDidPressed: contentWarningOverlayView)
|
delegate?.playerContainerView(self, contentWarningOverlayViewDidPressed: contentWarningOverlayView)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,16 @@ final class StatusView: UIView {
|
|||||||
static let avatarImageCornerRadius: CGFloat = 4
|
static let avatarImageCornerRadius: CGFloat = 4
|
||||||
static let avatarToLabelSpacing: CGFloat = 5
|
static let avatarToLabelSpacing: CGFloat = 5
|
||||||
static let contentWarningBlurRadius: CGFloat = 12
|
static let contentWarningBlurRadius: CGFloat = 12
|
||||||
|
static let containerStackViewSpacing: CGFloat = 10
|
||||||
|
|
||||||
|
weak var delegate: StatusViewDelegate?
|
||||||
|
private var needsDrawContentOverlay = false
|
||||||
|
var pollTableViewDataSource: UITableViewDiffableDataSource<PollSection, PollItem>?
|
||||||
|
var pollTableViewHeightLaoutConstraint: NSLayoutConstraint!
|
||||||
|
|
||||||
|
let containerStackView = UIStackView()
|
||||||
|
let headerContainerView = UIView()
|
||||||
|
let authorContainerView = UIView()
|
||||||
|
|
||||||
static let reblogIconImage: UIImage = {
|
static let reblogIconImage: UIImage = {
|
||||||
let font = UIFont.systemFont(ofSize: 13, weight: .medium)
|
let font = UIFont.systemFont(ofSize: 13, weight: .medium)
|
||||||
@ -53,13 +63,6 @@ final class StatusView: UIView {
|
|||||||
return attributedString
|
return attributedString
|
||||||
}
|
}
|
||||||
|
|
||||||
weak var delegate: StatusViewDelegate?
|
|
||||||
private var needsDrawContentOverlay = false
|
|
||||||
var pollTableViewDataSource: UITableViewDiffableDataSource<PollSection, PollItem>?
|
|
||||||
var pollTableViewHeightLaoutConstraint: NSLayoutConstraint!
|
|
||||||
|
|
||||||
let headerContainerStackView = UIStackView()
|
|
||||||
|
|
||||||
let headerIconLabel: UILabel = {
|
let headerIconLabel: UILabel = {
|
||||||
let label = UILabel()
|
let label = UILabel()
|
||||||
label.attributedText = StatusView.iconAttributedString(image: StatusView.reblogIconImage)
|
label.attributedText = StatusView.iconAttributedString(image: StatusView.reblogIconImage)
|
||||||
@ -221,9 +224,9 @@ extension StatusView {
|
|||||||
|
|
||||||
func _init() {
|
func _init() {
|
||||||
// container: [reblog | author | status | action toolbar]
|
// container: [reblog | author | status | action toolbar]
|
||||||
let containerStackView = UIStackView()
|
// note: do not set spacing for nested stackView to avoid SDK layout conflict issue
|
||||||
containerStackView.axis = .vertical
|
containerStackView.axis = .vertical
|
||||||
containerStackView.spacing = 10
|
// containerStackView.spacing = 10
|
||||||
containerStackView.translatesAutoresizingMaskIntoConstraints = false
|
containerStackView.translatesAutoresizingMaskIntoConstraints = false
|
||||||
addSubview(containerStackView)
|
addSubview(containerStackView)
|
||||||
NSLayoutConstraint.activate([
|
NSLayoutConstraint.activate([
|
||||||
@ -232,17 +235,27 @@ extension StatusView {
|
|||||||
trailingAnchor.constraint(equalTo: containerStackView.trailingAnchor),
|
trailingAnchor.constraint(equalTo: containerStackView.trailingAnchor),
|
||||||
bottomAnchor.constraint(equalTo: containerStackView.bottomAnchor),
|
bottomAnchor.constraint(equalTo: containerStackView.bottomAnchor),
|
||||||
])
|
])
|
||||||
|
containerStackView.setContentHuggingPriority(.required - 1, for: .vertical)
|
||||||
|
|
||||||
// header container: [icon | info]
|
// header container: [icon | info]
|
||||||
containerStackView.addArrangedSubview(headerContainerStackView)
|
let headerContainerStackView = UIStackView()
|
||||||
headerContainerStackView.spacing = 4
|
headerContainerStackView.axis = .horizontal
|
||||||
headerContainerStackView.addArrangedSubview(headerIconLabel)
|
headerContainerStackView.addArrangedSubview(headerIconLabel)
|
||||||
headerContainerStackView.addArrangedSubview(headerInfoLabel)
|
headerContainerStackView.addArrangedSubview(headerInfoLabel)
|
||||||
headerIconLabel.setContentHuggingPriority(.defaultHigh, for: .horizontal)
|
headerIconLabel.setContentHuggingPriority(.defaultHigh, for: .horizontal)
|
||||||
|
|
||||||
|
headerContainerStackView.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
headerContainerView.addSubview(headerContainerStackView)
|
||||||
|
NSLayoutConstraint.activate([
|
||||||
|
headerContainerStackView.topAnchor.constraint(equalTo: headerContainerView.topAnchor),
|
||||||
|
headerContainerStackView.leadingAnchor.constraint(equalTo: headerContainerView.leadingAnchor),
|
||||||
|
headerContainerStackView.trailingAnchor.constraint(equalTo: headerContainerView.trailingAnchor),
|
||||||
|
headerContainerView.bottomAnchor.constraint(equalTo: headerContainerStackView.bottomAnchor, constant: StatusView.containerStackViewSpacing).priority(.defaultHigh),
|
||||||
|
])
|
||||||
|
containerStackView.addArrangedSubview(headerContainerView)
|
||||||
|
|
||||||
// author container: [avatar | author meta container | reveal button]
|
// author container: [avatar | author meta container | reveal button]
|
||||||
let authorContainerStackView = UIStackView()
|
let authorContainerStackView = UIStackView()
|
||||||
containerStackView.addArrangedSubview(authorContainerStackView)
|
|
||||||
authorContainerStackView.axis = .horizontal
|
authorContainerStackView.axis = .horizontal
|
||||||
authorContainerStackView.spacing = StatusView.avatarToLabelSpacing
|
authorContainerStackView.spacing = StatusView.avatarToLabelSpacing
|
||||||
authorContainerStackView.distribution = .fill
|
authorContainerStackView.distribution = .fill
|
||||||
@ -306,6 +319,16 @@ extension StatusView {
|
|||||||
authorContainerStackView.addArrangedSubview(revealContentWarningButton)
|
authorContainerStackView.addArrangedSubview(revealContentWarningButton)
|
||||||
revealContentWarningButton.setContentHuggingPriority(.required - 2, for: .horizontal)
|
revealContentWarningButton.setContentHuggingPriority(.required - 2, for: .horizontal)
|
||||||
|
|
||||||
|
authorContainerStackView.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
authorContainerView.addSubview(authorContainerStackView)
|
||||||
|
NSLayoutConstraint.activate([
|
||||||
|
authorContainerStackView.topAnchor.constraint(equalTo: authorContainerView.topAnchor),
|
||||||
|
authorContainerStackView.leadingAnchor.constraint(equalTo: authorContainerView.leadingAnchor),
|
||||||
|
authorContainerStackView.trailingAnchor.constraint(equalTo: authorContainerView.trailingAnchor),
|
||||||
|
authorContainerView.bottomAnchor.constraint(equalTo: authorContainerStackView.bottomAnchor, constant: StatusView.containerStackViewSpacing).priority(.defaultHigh),
|
||||||
|
])
|
||||||
|
containerStackView.addArrangedSubview(authorContainerView)
|
||||||
|
|
||||||
// status container: [status | image / video | audio | poll | poll status] (overlay with content warning)
|
// status container: [status | image / video | audio | poll | poll status] (overlay with content warning)
|
||||||
containerStackView.addArrangedSubview(statusContainerStackView)
|
containerStackView.addArrangedSubview(statusContainerStackView)
|
||||||
statusContainerStackView.axis = .vertical
|
statusContainerStackView.axis = .vertical
|
||||||
@ -370,7 +393,7 @@ extension StatusView {
|
|||||||
containerStackView.addArrangedSubview(actionToolbarContainer)
|
containerStackView.addArrangedSubview(actionToolbarContainer)
|
||||||
actionToolbarContainer.setContentCompressionResistancePriority(.defaultLow, for: .vertical)
|
actionToolbarContainer.setContentCompressionResistancePriority(.defaultLow, for: .vertical)
|
||||||
|
|
||||||
headerContainerStackView.isHidden = true
|
headerContainerView.isHidden = true
|
||||||
statusMosaicImageViewContainer.isHidden = true
|
statusMosaicImageViewContainer.isHidden = true
|
||||||
pollTableView.isHidden = true
|
pollTableView.isHidden = true
|
||||||
pollStatusStackView.isHidden = true
|
pollStatusStackView.isHidden = true
|
||||||
@ -543,7 +566,7 @@ struct StatusView_Previews: PreviewProvider {
|
|||||||
.previewDisplayName("Normal")
|
.previewDisplayName("Normal")
|
||||||
UIViewPreview(width: 375) {
|
UIViewPreview(width: 375) {
|
||||||
let statusView = StatusView()
|
let statusView = StatusView()
|
||||||
statusView.headerContainerStackView.isHidden = false
|
statusView.headerContainerView.isHidden = false
|
||||||
statusView.avatarButton.isHidden = true
|
statusView.avatarButton.isHidden = true
|
||||||
statusView.avatarStackedContainerButton.isHidden = false
|
statusView.avatarStackedContainerButton.isHidden = false
|
||||||
statusView.avatarStackedContainerButton.topLeadingAvatarStackedImageView.configure(
|
statusView.avatarStackedContainerButton.topLeadingAvatarStackedImageView.configure(
|
||||||
@ -570,7 +593,7 @@ struct StatusView_Previews: PreviewProvider {
|
|||||||
placeholderImage: avatarFlora
|
placeholderImage: avatarFlora
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
statusView.headerContainerStackView.isHidden = false
|
statusView.headerContainerView.isHidden = false
|
||||||
let images = MosaicImageView_Previews.images
|
let images = MosaicImageView_Previews.images
|
||||||
let mosaics = statusView.statusMosaicImageViewContainer.setupImageViews(count: 4, maxHeight: 162)
|
let mosaics = statusView.statusMosaicImageViewContainer.setupImageViews(count: 4, maxHeight: 162)
|
||||||
for (i, mosaic) in mosaics.enumerated() {
|
for (i, mosaic) in mosaics.enumerated() {
|
||||||
@ -591,7 +614,7 @@ struct StatusView_Previews: PreviewProvider {
|
|||||||
placeholderImage: avatarFlora
|
placeholderImage: avatarFlora
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
statusView.headerContainerStackView.isHidden = false
|
statusView.headerContainerView.isHidden = false
|
||||||
statusView.setNeedsLayout()
|
statusView.setNeedsLayout()
|
||||||
statusView.layoutIfNeeded()
|
statusView.layoutIfNeeded()
|
||||||
statusView.updateContentWarningDisplay(isHidden: false, animated: false)
|
statusView.updateContentWarningDisplay(isHidden: false, animated: false)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user