From d333e449fec26df4a1293bbc0cc77b5a37e7d040 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Wed, 10 Feb 2021 12:40:23 -0500 Subject: [PATCH] move behavior --- MVMCoreUI/Atomic/Atoms/Views/Video.swift | 67 +------------------ .../Atomic/Atoms/Views/VideoDataManager.swift | 2 + MVMCoreUI/Atomic/Atoms/Views/VideoModel.swift | 64 +++++++++++++++++- .../Atoms/Views/VideoPauseBehavior.swift | 35 ---------- MVMCoreUI/Behaviors/PageBehavior.swift | 10 ++- 5 files changed, 76 insertions(+), 102 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/Views/Video.swift b/MVMCoreUI/Atomic/Atoms/Views/Video.swift index 044b199d..6e0fffbc 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/Video.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/Video.swift @@ -16,10 +16,6 @@ open class Video: View { /// Used to track the state and respond.. private var stateKVOToken: NSKeyValueObservation? - private weak var pauseBehavior: BlockPageVisibilityBehavior? - - private weak var scrollBehavior: BlockPageScrolledBehavior? - private var visible = true open override func setupView() { @@ -54,9 +50,8 @@ open class Video: View { } // Handle pause behavior - addVisibleBehavoir(to: model, delegateObject: delegateObject) - addScrolledBehavoir(to: model, delegateObject: delegateObject) -// addForegroundCheck() + model.addVisibleBehavoir(for: self, delegateObject: delegateObject) + model.addScrollBehavoir(for: self, delegateObject: delegateObject) } /// Listens and responds to video loading state changes. @@ -102,62 +97,4 @@ open class Video: View { deinit { removeStateObserver() } - - /// Adds a behavoir to pause the video on page hidden behavoir and unpause if necessary on page shown. - open func addVisibleBehavoir(to model: VideoModel, delegateObject: MVMCoreUIDelegateObject?) { - let onShow = { [weak self] in - guard self?.visible == true, - let model = self?.model as? VideoModel, - model.autoPlay else { return } - model.videoDataManager.player?.play() - } - let onHide: () -> Void = { [weak self] in - guard self?.visible == true, - let model = self?.model as? VideoModel else { return } - model.videoDataManager.player?.pause() - } - - if pauseBehavior != nil { - pauseBehavior?.pageShownHandler = onShow - pauseBehavior?.pageHiddenHandler = onHide - } else { - guard let delegate = delegateObject?.moleculeDelegate, - let page = delegate as? PageProtocol, - var pageModel = page.pageModel as? PageBehaviorsTemplateProtocol else { return } - var behavoirs = pageModel.behaviors ?? [] - let pauseBehavior = BlockPageVisibilityBehavior(with: onShow, onPageHiddenHandler: onHide) - behavoirs.append(pauseBehavior) - pageModel.behaviors = behavoirs - self.pauseBehavior = pauseBehavior - } - } - - open func addScrolledBehavoir(to model: VideoModel, delegateObject: MVMCoreUIDelegateObject?) { - - let onScroll = { [weak self] (scrollView: UIScrollView) in - // If visible to not visible, pause video. - // If not visible to visible, unpause if needed, add visible behavior - // visible == -// if !visible { -// pause -// } else { -// let model = self?.model as? VideoModel, -// model.autoPlay else { return } -// model.videoDataManager.player?.play() -// } - } - - if scrollBehavior != nil { - scrollBehavior?.pageScrolledHandler = onScroll - } else { - guard let delegate = delegateObject?.moleculeDelegate, - let page = delegate as? PageProtocol, - var pageModel = page.pageModel as? PageBehaviorsTemplateProtocol else { return } - var behavoirs = pageModel.behaviors ?? [] - let scrollBehavior = BlockPageScrolledBehavior(with: onScroll) - behavoirs.append(scrollBehavior) - pageModel.behaviors = behavoirs - self.scrollBehavior = scrollBehavior - } - } } diff --git a/MVMCoreUI/Atomic/Atoms/Views/VideoDataManager.swift b/MVMCoreUI/Atomic/Atoms/Views/VideoDataManager.swift index 754a6ef2..c616f4b6 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/VideoDataManager.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/VideoDataManager.swift @@ -127,6 +127,8 @@ import Foundation } private func removeMemoryWarningListener() { + guard let observer = memoryWarningListener else { return } + NotificationCenter.default.removeObserver(observer) memoryWarningListener = nil } diff --git a/MVMCoreUI/Atomic/Atoms/Views/VideoModel.swift b/MVMCoreUI/Atomic/Atoms/Views/VideoModel.swift index d335f375..0c1033e8 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/VideoModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/VideoModel.swift @@ -18,6 +18,9 @@ open class VideoModel: MoleculeModelProtocol { /// Keeps a reference to the video data. public var videoDataManager: VideoDataManager + + private weak var visibleBehavior: BlockPageVisibilityBehavior? + private weak var scrollBehavior: BlockPageScrolledBehavior? private enum CodingKeys: String, CodingKey { case moleculeName @@ -35,7 +38,6 @@ open class VideoModel: MoleculeModelProtocol { required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) video = try typeContainer.decode(String.self, forKey:.video) - videoDataManager = VideoDataManager(with: video) if let showControls = try typeContainer.decodeIfPresent(Bool.self, forKey: .showControls) { self.showControls = showControls } @@ -45,6 +47,7 @@ open class VideoModel: MoleculeModelProtocol { if let alwaysReset = try typeContainer.decodeIfPresent(Bool.self, forKey: .alwaysReset) { self.alwaysReset = alwaysReset } + videoDataManager = VideoDataManager(with: video) } open func encode(to encoder: Encoder) throws { @@ -55,4 +58,63 @@ open class VideoModel: MoleculeModelProtocol { try container.encode(autoPlay, forKey: .autoPlay) try container.encode(alwaysReset, forKey: .alwaysReset) } + + // Temporary + func isVisible(view: UIView) -> Bool { + return true + } + + /// Adds a behavoir to pause the video on page hidden behavoir and unpause if necessary on page shown. + open func addVisibleBehavoir(for view: Video, delegateObject: MVMCoreUIDelegateObject?) { + let onShow = { [weak self] in + guard let self = self, + self.isVisible(view: view), + self.autoPlay else { return } + self.videoDataManager.player?.play() + } + let onHide: () -> Void = { [weak self] in + guard let self = self else { return } + self.videoDataManager.player?.pause() + } + + guard visibleBehavior == nil else { + visibleBehavior?.pageShownHandler = onShow + visibleBehavior?.pageHiddenHandler = onHide + return + } + + guard let delegate = delegateObject?.moleculeDelegate, + let page = delegate as? PageProtocol, + var pageModel = page.pageModel as? PageBehaviorsTemplateProtocol else { return } + let pauseBehavior = BlockPageVisibilityBehavior(with: onShow, onPageHiddenHandler: onHide) + pageModel.add(behavior: pauseBehavior) + self.visibleBehavior = pauseBehavior + } + + /// Adds a behavoir to pause the video if scrolled off of the page and unpause if necessary if scrolled on. + open func addScrollBehavoir(for view: Video, delegateObject: MVMCoreUIDelegateObject?) { + + let onScroll = { [weak self] (scrollView: UIScrollView) in + // If visible to not visible, pause video. + // If not visible to visible, unpause if needed, add visible behavior + guard let self = self else { return } + if !self.isVisible(view: view) { + self.videoDataManager.player?.pause() + } else if self.autoPlay { + self.videoDataManager.player?.play() + } + } + + guard scrollBehavior == nil else { + scrollBehavior?.pageScrolledHandler = onScroll + return + } + + guard let delegate = delegateObject?.moleculeDelegate, + let page = delegate as? PageProtocol, + var pageModel = page.pageModel as? PageBehaviorsTemplateProtocol else { return } + let scrollBehavior = BlockPageScrolledBehavior(with: onScroll) + pageModel.add(behavior: scrollBehavior) + self.scrollBehavior = scrollBehavior + } } diff --git a/MVMCoreUI/Atomic/Atoms/Views/VideoPauseBehavior.swift b/MVMCoreUI/Atomic/Atoms/Views/VideoPauseBehavior.swift index 73293a8b..1524381e 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/VideoPauseBehavior.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/VideoPauseBehavior.swift @@ -73,38 +73,3 @@ public class BlockPageScrolledBehavior: PageScrolledBehavior { pageScrolledHandler(scrollView) } } - - -public class VideoPauseBehavior: PageVisibilityBehavior { - - public static var identifier = "videoPause" - - public weak var videoModel: VideoModel? - public init(with videoModel: VideoModel) { - self.videoModel = videoModel - } - - private enum CodingKeys: String, CodingKey { - case behaviorName - } - - //MARK:- PageVisibilityBehavior - - public func onPageShown() { - // TODO: Only do this if attached to a visible view... - if videoModel?.autoPlay == true { - videoModel?.videoDataManager.player?.play() - } - } - - public func onPageHidden() { - videoModel?.videoDataManager.player?.pause() - } - - public required init(from decoder: Decoder) throws {} - - public func encode(to encoder: Encoder) throws { - var container = encoder.container(keyedBy: CodingKeys.self) - try container.encode(behaviorName, forKey: .behaviorName) - } -} diff --git a/MVMCoreUI/Behaviors/PageBehavior.swift b/MVMCoreUI/Behaviors/PageBehavior.swift index ef80349e..59e41031 100644 --- a/MVMCoreUI/Behaviors/PageBehavior.swift +++ b/MVMCoreUI/Behaviors/PageBehavior.swift @@ -43,5 +43,13 @@ public protocol PageScrolledBehavior: PageBehaviorProtocol { public protocol PageBehaviorsTemplateProtocol { var behaviors: [PageBehaviorProtocol]? { get set } - + +} + +public extension PageBehaviorsTemplateProtocol { + mutating func add(behavior: PageBehaviorProtocol) { + var behavoirs = behaviors ?? [] + behavoirs.append(behavior) + self.behaviors = behavoirs + } }