diff --git a/Extensions/UIView+Extensions.swift b/Extensions/UIView+Extensions.swift index 6bdcb0b..346afc7 100644 --- a/Extensions/UIView+Extensions.swift +++ b/Extensions/UIView+Extensions.swift @@ -25,4 +25,15 @@ extension UIView { 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 + } + } + } } diff --git a/Extensions/View+Extensions.swift b/Extensions/View+Extensions.swift index ff813f8..2fe3524 100644 --- a/Extensions/View+Extensions.swift +++ b/Extensions/View+Extensions.swift @@ -10,13 +10,4 @@ extension View { Alert(title: Text($0.error.localizedDescription)) } } - - @ViewBuilder - func animation(_ animation: Animation?, if condition: Bool) -> some View { - if condition { - self.animation(animation) - } else { - self - } - } } diff --git a/View Controllers/AddIdentityViewController.swift b/View Controllers/AddIdentityViewController.swift index 0e11ac5..513d249 100644 --- a/View Controllers/AddIdentityViewController.swift +++ b/View Controllers/AddIdentityViewController.swift @@ -299,16 +299,3 @@ private extension AddIdentityViewController { 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 - } - } - } -} diff --git a/View Controllers/NewStatusViewController.swift b/View Controllers/NewStatusViewController.swift index 2208b5e..2dfcf7a 100644 --- a/View Controllers/NewStatusViewController.swift +++ b/View Controllers/NewStatusViewController.swift @@ -96,7 +96,7 @@ final class NewStatusViewController: UIViewController { statusView.isUserInteractionEnabled = false statusView.bodyView.alpha = 0.5 - statusView.buttonsStackView.isHidden = true + statusView.buttonsStackView.isHidden_stackViewSafe = true stackView.addArrangedSubview(statusView) } @@ -229,10 +229,11 @@ private extension NewStatusViewController { } for compositionView in stackView.arrangedSubviews.compactMap({ $0 as? CompositionView }) { - compositionView.removeButton.isHidden = compositionViewModels.count == 1 - compositionView.inReplyToView.isHidden = compositionView === stackView.arrangedSubviews.first + compositionView.removeButton.isHidden_stackViewSafe = compositionViewModels.count == 1 + compositionView.inReplyToView.isHidden_stackViewSafe = compositionView === stackView.arrangedSubviews.first && viewModel.inReplyToViewModel == nil - compositionView.hasReplyFollowingView.isHidden = compositionView === stackView.arrangedSubviews.last + compositionView.hasReplyFollowingView.isHidden_stackViewSafe = + compositionView === stackView.arrangedSubviews.last } } diff --git a/Views/UIKit/CompositionPollView.swift b/Views/UIKit/CompositionPollView.swift index 7a06dd3..686d956 100644 --- a/Views/UIKit/CompositionPollView.swift +++ b/Views/UIKit/CompositionPollView.swift @@ -131,7 +131,7 @@ private extension CompositionPollView { } 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 optionView.textField.isFirstResponder { diff --git a/Views/UIKit/CompositionView.swift b/Views/UIKit/CompositionView.swift index 554b4f8..2de2eb7 100644 --- a/Views/UIKit/CompositionView.swift +++ b/Views/UIKit/CompositionView.swift @@ -123,13 +123,13 @@ private extension CompositionView { textViewPlaceholder.text = NSLocalizedString("compose.prompt", comment: "") stackView.addArrangedSubview(attachmentsView) - attachmentsView.isHidden = true + attachmentsView.isHidden_stackViewSafe = true stackView.addArrangedSubview(attachmentUploadView) - attachmentUploadView.isHidden = true + attachmentUploadView.isHidden_stackViewSafe = true stackView.addArrangedSubview(markAttachmentsSensitiveView) - markAttachmentsSensitiveView.isHidden = true + markAttachmentsSensitiveView.isHidden_stackViewSafe = true stackView.addArrangedSubview(pollView) - pollView.isHidden = true + pollView.isHidden_stackViewSafe = true addSubview(removeButton) removeButton.translatesAutoresizingMaskIntoConstraints = false @@ -162,10 +162,13 @@ private extension CompositionView { constant: -textViewFont.lineHeight / 2) viewModel.$text.map(\.isEmpty) - .sink { [weak self] in self?.textViewPlaceholder.isHidden = !$0 } + .sink { [weak self] in self?.textViewPlaceholder.isHidden_stackViewSafe = !$0 } .store(in: &cancellables) viewModel.$displayContentWarning + .throttle(for: .seconds(TimeInterval.zeroIfReduceMotion(.shortAnimationDuration)), + scheduler: DispatchQueue.main, + latest: true) .sink { [weak self] displayContentWarning in guard let self = self else { return } @@ -178,7 +181,7 @@ private extension CompositionView { } UIView.animate(withDuration: .zeroIfReduceMotion(.shortAnimationDuration)) { - self.spoilerTextField.isHidden = !displayContentWarning + self.spoilerTextField.isHidden_stackViewSafe = !displayContentWarning textViewBaselineConstraint.isActive = !displayContentWarning } } @@ -200,24 +203,29 @@ private extension CompositionView { .store(in: &cancellables) viewModel.$attachmentViewModels - .receive(on: RunLoop.main) + .throttle(for: .seconds(TimeInterval.zeroIfReduceMotion(.shortAnimationDuration)), + scheduler: DispatchQueue.main, + latest: true) .sink { [weak self] attachmentViewModels in UIView.animate(withDuration: .zeroIfReduceMotion(.shortAnimationDuration)) { self?.attachmentsView.viewModel = self?.viewModel - self?.attachmentsView.isHidden = attachmentViewModels.isEmpty - self?.markAttachmentsSensitiveView.isHidden = attachmentViewModels.isEmpty + self?.attachmentsView.isHidden_stackViewSafe = attachmentViewModels.isEmpty + self?.markAttachmentsSensitiveView.isHidden_stackViewSafe = attachmentViewModels.isEmpty } } .store(in: &cancellables) viewModel.$displayPoll + .throttle(for: .seconds(TimeInterval.zeroIfReduceMotion(.shortAnimationDuration)), + scheduler: DispatchQueue.main, + latest: true) .sink { [weak self] displayPoll in if !displayPoll { self?.textView.becomeFirstResponder() } UIView.animate(withDuration: .zeroIfReduceMotion(.shortAnimationDuration)) { - self?.pollView.isHidden = !displayPoll + self?.pollView.isHidden_stackViewSafe = !displayPoll } } .store(in: &cancellables)