Basic animation to show/hide 💊 (IOS-234)

This commit is contained in:
Nathan Mattes 2024-04-05 17:06:54 +02:00
parent 6af94352e2
commit 33653911c3
2 changed files with 64 additions and 16 deletions

View File

@ -100,6 +100,9 @@ final class HomeTimelineViewController: UIViewController, NeedsDependency, Media
let refreshControl = RefreshControl() let refreshControl = RefreshControl()
let timelinePill = TimelineStatusPill() let timelinePill = TimelineStatusPill()
var timelinePillCenterXAnchor: NSLayoutConstraint?
var timelinePillVisibleTopAnchor: NSLayoutConstraint?
var timelinePillHiddenTopAnchor: NSLayoutConstraint?
private func generateTimeSelectorMenu() -> UIMenu { private func generateTimeSelectorMenu() -> UIMenu {
@ -299,17 +302,24 @@ extension HomeTimelineViewController {
} }
.store(in: &disposeBag) .store(in: &disposeBag)
// timelinePill.translatesAutoresizingMaskIntoConstraints = false timelinePill.translatesAutoresizingMaskIntoConstraints = false
// view.addSubview(timelinePill) view.addSubview(timelinePill)
//
// // has to up updated and animated let timelinePillCenterXAnchor = timelinePill.centerXAnchor.constraint(equalTo: view.centerXAnchor)
// timelinePill.update(with: .postSent) let timelinePillVisibleTopAnchor = timelinePill.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 8)
// NSLayoutConstraint.activate([ let timelinePillHiddenTopAnchor = view.safeAreaLayoutGuide.topAnchor.constraint(equalTo: timelinePill.bottomAnchor, constant: 8)
// timelinePill.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 8),
// timelinePill.centerXAnchor.constraint(equalTo: view.centerXAnchor), NSLayoutConstraint.activate([
// ]) timelinePillHiddenTopAnchor, timelinePillCenterXAnchor
])
timelinePill.addTarget(self, action: #selector(HomeTimelineViewController.timelinePillPressed(_:)), for: .touchUpInside)
self.timelinePillCenterXAnchor = timelinePillCenterXAnchor
self.timelinePillVisibleTopAnchor = timelinePillVisibleTopAnchor
self.timelinePillHiddenTopAnchor = timelinePillHiddenTopAnchor
} }
override func viewWillAppear(_ animated: Bool) { override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated) super.viewWillAppear(animated)
@ -459,6 +469,42 @@ extension HomeTimelineViewController {
} }
} }
@objc private func timelinePillPressed(_ sender: TimelineStatusPill) {
guard let reason = sender.reason else { return }
switch reason {
case .newPosts:
print("Bring me to the new posts and disappear")
case .postSent:
print("Bring me to my post and disappear")
case .offline:
print("Just disappear")
}
hideTimelinePill()
}
private func showTimelinePill() {
guard let timelinePillHiddenTopAnchor, let timelinePillVisibleTopAnchor else { return }
NSLayoutConstraint.deactivate([timelinePillHiddenTopAnchor])
NSLayoutConstraint.activate([timelinePillVisibleTopAnchor])
UIView.animate(withDuration: 0.4) {
self.view.layoutIfNeeded()
}
}
private func hideTimelinePill() {
guard let timelinePillHiddenTopAnchor, let timelinePillVisibleTopAnchor else { return }
NSLayoutConstraint.deactivate([timelinePillVisibleTopAnchor])
NSLayoutConstraint.activate([timelinePillHiddenTopAnchor])
UIView.animate(withDuration: 0.4, animations: {
self.view.layoutIfNeeded()
})
}
} }
// MARK: - UIScrollViewDelegate // MARK: - UIScrollViewDelegate
extension HomeTimelineViewController { extension HomeTimelineViewController {

View File

@ -5,32 +5,34 @@ import MastodonAsset
class TimelineStatusPill: UIButton { class TimelineStatusPill: UIButton {
func update(with state: State) { var reason: Reason?
func update(with reason: Reason) {
self.reason = reason
var configuration = UIButton.Configuration.filled() var configuration = UIButton.Configuration.filled()
configuration.attributedTitle = AttributedString( configuration.attributedTitle = AttributedString(
state.title, attributes: AttributeContainer( reason.title, attributes: AttributeContainer(
[ [
.font: UIFontMetrics(forTextStyle: .subheadline).scaledFont(for: .systemFont(ofSize: 15, weight: .bold)), .font: UIFontMetrics(forTextStyle: .subheadline).scaledFont(for: .systemFont(ofSize: 15, weight: .bold)),
.foregroundColor: UIColor.white .foregroundColor: UIColor.white
] ]
)) ))
let image = state.image? let image = reason.image?
.withConfiguration(UIImage.SymbolConfiguration(paletteColors: [.white])) .withConfiguration(UIImage.SymbolConfiguration(paletteColors: [.white]))
.withConfiguration(UIImage.SymbolConfiguration(textStyle: .subheadline)) .withConfiguration(UIImage.SymbolConfiguration(textStyle: .subheadline))
.withConfiguration(UIImage.SymbolConfiguration(pointSize: 12, weight: .bold, scale: .medium)) .withConfiguration(UIImage.SymbolConfiguration(pointSize: 12, weight: .bold, scale: .medium))
configuration.image = image configuration.image = image
configuration.imagePadding = 8 configuration.imagePadding = 8
configuration.baseBackgroundColor = state.backgroundColor configuration.baseBackgroundColor = reason.backgroundColor
configuration.cornerStyle = .capsule configuration.cornerStyle = .capsule
self.configuration = configuration self.configuration = configuration
} }
public enum State { public enum Reason {
case newPosts case newPosts
case postSent case postSent
case offline case offline