Guard against UIStackView bugs

This commit is contained in:
Justin Mazzocchi 2021-02-01 14:11:53 -08:00
parent 533e86caab
commit 0bb63862d5
No known key found for this signature in database
GPG key ID: E223E6937AAFB01C
6 changed files with 35 additions and 37 deletions

View file

@ -25,4 +25,15 @@ extension UIView {
layer.contentsRect = CGRect(origin: origin, size: Self.defaultContentsRectSize) layer.contentsRect = CGRect(origin: origin, size: Self.defaultContentsRectSize)
} }
// http://www.openradar.me/25087688
var isHidden_stackViewSafe: Bool {
get { isHidden }
set {
if isHidden != newValue {
isHidden = newValue
alpha = isHidden ? 0 : 1
}
}
}
} }

View file

@ -10,13 +10,4 @@ extension View {
Alert(title: Text($0.error.localizedDescription)) Alert(title: Text($0.error.localizedDescription))
} }
} }
@ViewBuilder
func animation(_ animation: Animation?, if condition: Bool) -> some View {
if condition {
self.animation(animation)
} else {
self
}
}
} }

View file

@ -299,16 +299,3 @@ private extension AddIdentityViewController {
show(registrationViewController, sender: self) show(registrationViewController, sender: self)
} }
} }
// http://www.openradar.me/25087688
extension UIView {
var isHidden_stackViewSafe: Bool {
get { isHidden }
set {
if isHidden != newValue {
isHidden = newValue
alpha = isHidden ? 0 : 1
}
}
}
}

View file

@ -96,7 +96,7 @@ final class NewStatusViewController: UIViewController {
statusView.isUserInteractionEnabled = false statusView.isUserInteractionEnabled = false
statusView.bodyView.alpha = 0.5 statusView.bodyView.alpha = 0.5
statusView.buttonsStackView.isHidden = true statusView.buttonsStackView.isHidden_stackViewSafe = true
stackView.addArrangedSubview(statusView) stackView.addArrangedSubview(statusView)
} }
@ -229,10 +229,11 @@ private extension NewStatusViewController {
} }
for compositionView in stackView.arrangedSubviews.compactMap({ $0 as? CompositionView }) { for compositionView in stackView.arrangedSubviews.compactMap({ $0 as? CompositionView }) {
compositionView.removeButton.isHidden = compositionViewModels.count == 1 compositionView.removeButton.isHidden_stackViewSafe = compositionViewModels.count == 1
compositionView.inReplyToView.isHidden = compositionView === stackView.arrangedSubviews.first compositionView.inReplyToView.isHidden_stackViewSafe = compositionView === stackView.arrangedSubviews.first
&& viewModel.inReplyToViewModel == nil && viewModel.inReplyToViewModel == nil
compositionView.hasReplyFollowingView.isHidden = compositionView === stackView.arrangedSubviews.last compositionView.hasReplyFollowingView.isHidden_stackViewSafe =
compositionView === stackView.arrangedSubviews.last
} }
} }

View file

@ -131,7 +131,7 @@ private extension CompositionPollView {
} }
for (index, optionView) in self.pollOptionViews.enumerated() { for (index, optionView) in self.pollOptionViews.enumerated() {
optionView.removeButton.isHidden = index < CompositionViewModel.minPollOptionCount optionView.removeButton.isHidden_stackViewSafe = index < CompositionViewModel.minPollOptionCount
if !$0.contains(where: { $0 === optionView.option }) { if !$0.contains(where: { $0 === optionView.option }) {
if optionView.textField.isFirstResponder { if optionView.textField.isFirstResponder {

View file

@ -123,13 +123,13 @@ private extension CompositionView {
textViewPlaceholder.text = NSLocalizedString("compose.prompt", comment: "") textViewPlaceholder.text = NSLocalizedString("compose.prompt", comment: "")
stackView.addArrangedSubview(attachmentsView) stackView.addArrangedSubview(attachmentsView)
attachmentsView.isHidden = true attachmentsView.isHidden_stackViewSafe = true
stackView.addArrangedSubview(attachmentUploadView) stackView.addArrangedSubview(attachmentUploadView)
attachmentUploadView.isHidden = true attachmentUploadView.isHidden_stackViewSafe = true
stackView.addArrangedSubview(markAttachmentsSensitiveView) stackView.addArrangedSubview(markAttachmentsSensitiveView)
markAttachmentsSensitiveView.isHidden = true markAttachmentsSensitiveView.isHidden_stackViewSafe = true
stackView.addArrangedSubview(pollView) stackView.addArrangedSubview(pollView)
pollView.isHidden = true pollView.isHidden_stackViewSafe = true
addSubview(removeButton) addSubview(removeButton)
removeButton.translatesAutoresizingMaskIntoConstraints = false removeButton.translatesAutoresizingMaskIntoConstraints = false
@ -162,10 +162,13 @@ private extension CompositionView {
constant: -textViewFont.lineHeight / 2) constant: -textViewFont.lineHeight / 2)
viewModel.$text.map(\.isEmpty) viewModel.$text.map(\.isEmpty)
.sink { [weak self] in self?.textViewPlaceholder.isHidden = !$0 } .sink { [weak self] in self?.textViewPlaceholder.isHidden_stackViewSafe = !$0 }
.store(in: &cancellables) .store(in: &cancellables)
viewModel.$displayContentWarning viewModel.$displayContentWarning
.throttle(for: .seconds(TimeInterval.zeroIfReduceMotion(.shortAnimationDuration)),
scheduler: DispatchQueue.main,
latest: true)
.sink { [weak self] displayContentWarning in .sink { [weak self] displayContentWarning in
guard let self = self else { return } guard let self = self else { return }
@ -178,7 +181,7 @@ private extension CompositionView {
} }
UIView.animate(withDuration: .zeroIfReduceMotion(.shortAnimationDuration)) { UIView.animate(withDuration: .zeroIfReduceMotion(.shortAnimationDuration)) {
self.spoilerTextField.isHidden = !displayContentWarning self.spoilerTextField.isHidden_stackViewSafe = !displayContentWarning
textViewBaselineConstraint.isActive = !displayContentWarning textViewBaselineConstraint.isActive = !displayContentWarning
} }
} }
@ -200,24 +203,29 @@ private extension CompositionView {
.store(in: &cancellables) .store(in: &cancellables)
viewModel.$attachmentViewModels viewModel.$attachmentViewModels
.receive(on: RunLoop.main) .throttle(for: .seconds(TimeInterval.zeroIfReduceMotion(.shortAnimationDuration)),
scheduler: DispatchQueue.main,
latest: true)
.sink { [weak self] attachmentViewModels in .sink { [weak self] attachmentViewModels in
UIView.animate(withDuration: .zeroIfReduceMotion(.shortAnimationDuration)) { UIView.animate(withDuration: .zeroIfReduceMotion(.shortAnimationDuration)) {
self?.attachmentsView.viewModel = self?.viewModel self?.attachmentsView.viewModel = self?.viewModel
self?.attachmentsView.isHidden = attachmentViewModels.isEmpty self?.attachmentsView.isHidden_stackViewSafe = attachmentViewModels.isEmpty
self?.markAttachmentsSensitiveView.isHidden = attachmentViewModels.isEmpty self?.markAttachmentsSensitiveView.isHidden_stackViewSafe = attachmentViewModels.isEmpty
} }
} }
.store(in: &cancellables) .store(in: &cancellables)
viewModel.$displayPoll viewModel.$displayPoll
.throttle(for: .seconds(TimeInterval.zeroIfReduceMotion(.shortAnimationDuration)),
scheduler: DispatchQueue.main,
latest: true)
.sink { [weak self] displayPoll in .sink { [weak self] displayPoll in
if !displayPoll { if !displayPoll {
self?.textView.becomeFirstResponder() self?.textView.becomeFirstResponder()
} }
UIView.animate(withDuration: .zeroIfReduceMotion(.shortAnimationDuration)) { UIView.animate(withDuration: .zeroIfReduceMotion(.shortAnimationDuration)) {
self?.pollView.isHidden = !displayPoll self?.pollView.isHidden_stackViewSafe = !displayPoll
} }
} }
.store(in: &cancellables) .store(in: &cancellables)