Skip to content

Commit

Permalink
Unregister notification observers correctly in NoticePresenter (#21000
Browse files Browse the repository at this point in the history
)
  • Loading branch information
mokagio authored Jul 7, 2023
2 parents e280b09 + 48b399c commit 71ac312
Showing 1 changed file with 48 additions and 37 deletions.
85 changes: 48 additions & 37 deletions WordPress/Classes/ViewRelated/System/Notices/NoticePresenter.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import Foundation
import Combine
import UIKit
import UserNotifications
import WordPressFlux
Expand Down Expand Up @@ -59,6 +60,8 @@ class NoticePresenter {
private var currentNoticePresentation: NoticePresentation?
private var currentKeyboardPresentation: KeyboardPresentation = .notPresent

private var notificationObservers = Set<AnyCancellable>()

init(store: NoticeStore = StoreContainer.shared.notice,
animator: NoticeAnimator = NoticeAnimator(duration: Animations.appearanceDuration, springDampening: Animations.appearanceSpringDamping, springVelocity: NoticePresenter.Animations.appearanceSpringVelocity)) {
self.store = store
Expand Down Expand Up @@ -97,54 +100,62 @@ class NoticePresenter {
// MARK: - Events

private func listenToKeyboardEvents() {
NotificationCenter.default.addObserver(forName: UIResponder.keyboardWillShowNotification, object: nil, queue: nil) { [weak self] (notification) in
guard let self = self,
let userInfo = notification.userInfo,
let keyboardFrameValue = userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue,
let durationValue = userInfo[UIResponder.keyboardAnimationDurationUserInfoKey] as? NSNumber else {
return
}

self.currentKeyboardPresentation = .present(height: keyboardFrameValue.cgRectValue.size.height)

guard let currentContainer = self.currentNoticePresentation?.containerView else {
return
}
NotificationCenter.default
.publisher(for: UIResponder.keyboardWillShowNotification)
.sink { [weak self] notification in
guard let self,
let userInfo = notification.userInfo,
let keyboardFrameValue = userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue,
let durationValue = userInfo[UIResponder.keyboardAnimationDurationUserInfoKey] as? NSNumber else {
return
}

UIView.animate(withDuration: durationValue.doubleValue, animations: {
currentContainer.bottomConstraint?.constant = self.onScreenNoticeContainerBottomConstraintConstant
self.view.layoutIfNeeded()
})
}
NotificationCenter.default.addObserver(forName: UIResponder.keyboardWillHideNotification, object: nil, queue: nil) { [weak self] (notification) in
self?.currentKeyboardPresentation = .notPresent
self.currentKeyboardPresentation = .present(height: keyboardFrameValue.cgRectValue.size.height)

guard let self = self,
let currentContainer = self.currentNoticePresentation?.containerView,
let userInfo = notification.userInfo,
let durationValue = userInfo[UIResponder.keyboardAnimationDurationUserInfoKey] as? NSNumber else {
guard let currentContainer = self.currentNoticePresentation?.containerView else {
return
}

UIView.animate(withDuration: durationValue.doubleValue, animations: {
currentContainer.bottomConstraint?.constant = self.onScreenNoticeContainerBottomConstraintConstant
self.view.layoutIfNeeded()
})
}
.store(in: &notificationObservers)

NotificationCenter.default
.publisher(for: UIResponder.keyboardWillHideNotification)
.sink { [weak self] notification in
self?.currentKeyboardPresentation = .notPresent

guard let self,
let currentContainer = self.currentNoticePresentation?.containerView,
let userInfo = notification.userInfo,
let durationValue = userInfo[UIResponder.keyboardAnimationDurationUserInfoKey] as? NSNumber else {
return
}

UIView.animate(withDuration: durationValue.doubleValue, animations: {
currentContainer.bottomConstraint?.constant = self.onScreenNoticeContainerBottomConstraintConstant
self.view.layoutIfNeeded()
})
}
UIView.animate(withDuration: durationValue.doubleValue, animations: {
currentContainer.bottomConstraint?.constant = self.onScreenNoticeContainerBottomConstraintConstant
self.view.layoutIfNeeded()
})
}
.store(in: &notificationObservers)
}

/// Adjust the current Notice so it will always be in the correct y-position after the
/// device is rotated.
private func listenToOrientationChangeEvents() {
let nc = NotificationCenter.default
nc.addObserver(forName: NSNotification.Name.WPTabBarHeightChanged, object: nil, queue: nil) { [weak self] _ in
guard let self = self,
let containerView = self.currentNoticePresentation?.containerView else {
return
}
NotificationCenter.default.publisher(for: .WPTabBarHeightChanged)
.sink { [weak self] _ in
guard let self = self,
let containerView = self.currentNoticePresentation?.containerView else {
return
}

containerView.bottomConstraint?.constant = -self.window.untouchableViewController.offsetOnscreen
}
containerView.bottomConstraint?.constant = -self.window.untouchableViewController.offsetOnscreen
}
.store(in: &notificationObservers)
}

/// Handle all changes in the `NoticeStore`.
Expand Down

0 comments on commit 71ac312

Please sign in to comment.