move behavior
This commit is contained in:
parent
c473177832
commit
d333e449fe
@ -16,10 +16,6 @@ open class Video: View {
|
|||||||
/// Used to track the state and respond..
|
/// Used to track the state and respond..
|
||||||
private var stateKVOToken: NSKeyValueObservation?
|
private var stateKVOToken: NSKeyValueObservation?
|
||||||
|
|
||||||
private weak var pauseBehavior: BlockPageVisibilityBehavior?
|
|
||||||
|
|
||||||
private weak var scrollBehavior: BlockPageScrolledBehavior?
|
|
||||||
|
|
||||||
private var visible = true
|
private var visible = true
|
||||||
|
|
||||||
open override func setupView() {
|
open override func setupView() {
|
||||||
@ -54,9 +50,8 @@ open class Video: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Handle pause behavior
|
// Handle pause behavior
|
||||||
addVisibleBehavoir(to: model, delegateObject: delegateObject)
|
model.addVisibleBehavoir(for: self, delegateObject: delegateObject)
|
||||||
addScrolledBehavoir(to: model, delegateObject: delegateObject)
|
model.addScrollBehavoir(for: self, delegateObject: delegateObject)
|
||||||
// addForegroundCheck()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Listens and responds to video loading state changes.
|
/// Listens and responds to video loading state changes.
|
||||||
@ -102,62 +97,4 @@ open class Video: View {
|
|||||||
deinit {
|
deinit {
|
||||||
removeStateObserver()
|
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -127,6 +127,8 @@ import Foundation
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func removeMemoryWarningListener() {
|
private func removeMemoryWarningListener() {
|
||||||
|
guard let observer = memoryWarningListener else { return }
|
||||||
|
NotificationCenter.default.removeObserver(observer)
|
||||||
memoryWarningListener = nil
|
memoryWarningListener = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -18,6 +18,9 @@ open class VideoModel: MoleculeModelProtocol {
|
|||||||
|
|
||||||
/// Keeps a reference to the video data.
|
/// Keeps a reference to the video data.
|
||||||
public var videoDataManager: VideoDataManager
|
public var videoDataManager: VideoDataManager
|
||||||
|
|
||||||
|
private weak var visibleBehavior: BlockPageVisibilityBehavior?
|
||||||
|
private weak var scrollBehavior: BlockPageScrolledBehavior?
|
||||||
|
|
||||||
private enum CodingKeys: String, CodingKey {
|
private enum CodingKeys: String, CodingKey {
|
||||||
case moleculeName
|
case moleculeName
|
||||||
@ -35,7 +38,6 @@ open class VideoModel: MoleculeModelProtocol {
|
|||||||
required public init(from decoder: Decoder) throws {
|
required public init(from decoder: Decoder) throws {
|
||||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
video = try typeContainer.decode(String.self, forKey:.video)
|
video = try typeContainer.decode(String.self, forKey:.video)
|
||||||
videoDataManager = VideoDataManager(with: video)
|
|
||||||
if let showControls = try typeContainer.decodeIfPresent(Bool.self, forKey: .showControls) {
|
if let showControls = try typeContainer.decodeIfPresent(Bool.self, forKey: .showControls) {
|
||||||
self.showControls = showControls
|
self.showControls = showControls
|
||||||
}
|
}
|
||||||
@ -45,6 +47,7 @@ open class VideoModel: MoleculeModelProtocol {
|
|||||||
if let alwaysReset = try typeContainer.decodeIfPresent(Bool.self, forKey: .alwaysReset) {
|
if let alwaysReset = try typeContainer.decodeIfPresent(Bool.self, forKey: .alwaysReset) {
|
||||||
self.alwaysReset = alwaysReset
|
self.alwaysReset = alwaysReset
|
||||||
}
|
}
|
||||||
|
videoDataManager = VideoDataManager(with: video)
|
||||||
}
|
}
|
||||||
|
|
||||||
open func encode(to encoder: Encoder) throws {
|
open func encode(to encoder: Encoder) throws {
|
||||||
@ -55,4 +58,63 @@ open class VideoModel: MoleculeModelProtocol {
|
|||||||
try container.encode(autoPlay, forKey: .autoPlay)
|
try container.encode(autoPlay, forKey: .autoPlay)
|
||||||
try container.encode(alwaysReset, forKey: .alwaysReset)
|
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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -73,38 +73,3 @@ public class BlockPageScrolledBehavior: PageScrolledBehavior {
|
|||||||
pageScrolledHandler(scrollView)
|
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@ -43,5 +43,13 @@ public protocol PageScrolledBehavior: PageBehaviorProtocol {
|
|||||||
public protocol PageBehaviorsTemplateProtocol {
|
public protocol PageBehaviorsTemplateProtocol {
|
||||||
|
|
||||||
var behaviors: [PageBehaviorProtocol]? { get set }
|
var behaviors: [PageBehaviorProtocol]? { get set }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public extension PageBehaviorsTemplateProtocol {
|
||||||
|
mutating func add(behavior: PageBehaviorProtocol) {
|
||||||
|
var behavoirs = behaviors ?? []
|
||||||
|
behavoirs.append(behavior)
|
||||||
|
self.behaviors = behavoirs
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user