Skip to content

Commit 35039f0

Browse files
author
JmoVxia
committed
优化转场动画,解决转场过程中的闪烁
1 parent 5c55872 commit 35039f0

File tree

5 files changed

+65
-83
lines changed

5 files changed

+65
-83
lines changed

CLPlayer.podspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
Pod::Spec.new do |s|
22

33
s.name = 'CLPlayer'
4-
s.version = '2.0.5'
4+
s.version = '2.0.6'
55
s.summary = 'Swift版自定义AVPlayer'
66
s.description = <<-DESC
77
CLPlayer是基于系统AVPlayer封装的视频播放器.

CLPlayer/CLFullScreenController/CLAnimationTransitioning.swift

Lines changed: 44 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@ import SnapKit
99
import UIKit
1010

1111
extension CLAnimationTransitioning {
12-
enum CLAnimationType {
12+
enum AnimationType {
1313
case present
1414
case dismiss
1515
}
1616

17-
enum CLAnimationOrientation {
17+
enum AnimationOrientation {
1818
case left
1919
case right
2020
case fullRight
@@ -30,24 +30,27 @@ class CLAnimationTransitioning: NSObject {
3030
}
3131
}()
3232

33-
private weak var player: CLPlayerView?
33+
private weak var playerView: CLPlayerView?
3434

35-
private weak var parentView: UIStackView?
35+
private weak var parentStackView: UIStackView?
3636

37-
private var centerInParent: CGPoint = .zero
37+
private var initialCenter: CGPoint = .zero
3838

39-
private var originSize: CGSize = .zero
39+
private var finalCenter: CGPoint = .zero
4040

41-
private var orientation: CLAnimationOrientation = .left
41+
private var initialBounds: CGRect = .zero
4242

43-
var animationType: CLAnimationType = .present
43+
private var animationOrientation: AnimationOrientation = .left
4444

45-
init(playView: CLPlayerView, orientation: CLAnimationOrientation) {
46-
player = playView
47-
self.orientation = orientation
48-
parentView = playView.superview as? UIStackView
49-
centerInParent = playView.center
50-
originSize = playView.frame.size
45+
var animationType: AnimationType = .present
46+
47+
init(playerView: CLPlayerView, animationOrientation: AnimationOrientation) {
48+
self.playerView = playerView
49+
self.animationOrientation = animationOrientation
50+
parentStackView = playerView.superview as? UIStackView
51+
initialBounds = playerView.bounds
52+
initialCenter = playerView.center
53+
finalCenter = playerView.convert(initialCenter, to: nil)
5154
}
5255
}
5356

@@ -57,97 +60,59 @@ extension CLAnimationTransitioning: UIViewControllerAnimatedTransitioning {
5760
}
5861

5962
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
60-
guard let playView = player else { return }
63+
guard let playerView = playerView else { return }
64+
6165
if animationType == .present {
6266
guard let toView = transitionContext.view(forKey: .to) else { return }
63-
guard let fromController = transitionContext.viewController(forKey: .from) else { return }
64-
65-
let fromCenter = transitionContext.containerView.convert(playView.center, from: playView.superview)
66-
let fromSize = transitionContext.containerView.convert(playView.frame, from: nil).size
67+
guard let toController = transitionContext.viewController(forKey: .to) as? CLFullScreenController else { return }
6768

69+
let startCenter = transitionContext.containerView.convert(initialCenter, from: playerView)
6870
transitionContext.containerView.addSubview(toView)
69-
toView.addSubview(playView)
70-
71-
if orientation == .left,
72-
!(fromController.shouldAutorotate && fromController.supportedInterfaceOrientations.contains(.landscapeLeft))
73-
{
74-
toView.transform = .init(rotationAngle: -Double.pi * 0.5)
75-
} else if orientation == .right,
76-
!(fromController.shouldAutorotate && fromController.supportedInterfaceOrientations.contains(.landscapeRight))
77-
{
78-
toView.transform = .init(rotationAngle: Double.pi * 0.5)
79-
} else if orientation == .fullRight {
80-
toView.transform = .init(rotationAngle: -Double.pi * 0.5)
81-
}
82-
83-
toView.snp.remakeConstraints { make in
84-
make.center.equalTo(fromCenter)
85-
make.size.equalTo(fromSize)
86-
}
87-
playView.snp.remakeConstraints { make in
88-
make.edges.equalToSuperview()
89-
}
90-
transitionContext.containerView.setNeedsLayout()
91-
transitionContext.containerView.layoutIfNeeded()
71+
toController.mainStackView.addArrangedSubview(playerView)
72+
toView.bounds = initialBounds
73+
toView.center = startCenter
74+
toView.transform = .init(rotationAngle: toController.isKind(of: CLFullScreenLeftController.self) ? Double.pi * 0.5 : Double.pi * -0.5)
9275

93-
toView.snp.updateConstraints { make in
94-
make.center.equalTo(transitionContext.containerView.center)
95-
make.size.equalTo(transitionContext.containerView.bounds.size)
96-
}
9776
if #available(iOS 11.0, *) {
98-
playView.contentView.animationLayout(safeAreaInsets: keyWindow?.safeAreaInsets ?? .zero, to: .fullScreen)
77+
playerView.contentView.animationLayout(safeAreaInsets: keyWindow?.safeAreaInsets ?? .zero, to: .fullScreen)
9978
} else {
100-
playView.contentView.animationLayout(safeAreaInsets: .zero, to: .fullScreen)
79+
playerView.contentView.animationLayout(safeAreaInsets: .zero, to: .fullScreen)
10180
}
10281
UIView.animate(withDuration: transitionDuration(using: transitionContext), delay: 0, options: .layoutSubviews, animations: {
10382
toView.transform = .identity
104-
transitionContext.containerView.setNeedsLayout()
105-
transitionContext.containerView.layoutIfNeeded()
106-
playView.contentView.setNeedsLayout()
107-
playView.contentView.layoutIfNeeded()
83+
toView.bounds = transitionContext.containerView.bounds
84+
toView.center = transitionContext.containerView.center
85+
playerView.contentView.setNeedsLayout()
86+
playerView.contentView.layoutIfNeeded()
10887
}) { _ in
88+
toView.transform = .identity
89+
toView.bounds = transitionContext.containerView.bounds
90+
toView.center = transitionContext.containerView.center
10991
transitionContext.completeTransition(true)
11092
UIViewController.attemptRotationToDeviceOrientation()
11193
}
11294
} else {
113-
guard let parentView = parentView else { return }
95+
guard let parentStackView = parentStackView else { return }
11496
guard let fromView = transitionContext.view(forKey: .from) else { return }
11597
guard let toView = transitionContext.view(forKey: .to) else { return }
11698

117-
toView.frame = transitionContext.containerView.bounds
118-
119-
let fromCenter = CGPoint(x: toView.frame.width * 0.5, y: toView.frame.height * 0.5)
120-
let fromSize = transitionContext.containerView.convert(playView.frame, from: nil).size
121-
12299
transitionContext.containerView.addSubview(toView)
123100
transitionContext.containerView.addSubview(fromView)
101+
toView.frame = transitionContext.containerView.bounds
124102

125-
fromView.snp.remakeConstraints { make in
126-
make.center.equalTo(fromCenter)
127-
make.size.equalTo(fromSize)
128-
}
129-
130-
transitionContext.containerView.setNeedsLayout()
131-
transitionContext.containerView.layoutIfNeeded()
132-
133-
let center = transitionContext.containerView.convert(centerInParent, from: parentView)
134-
fromView.snp.updateConstraints { make in
135-
make.center.equalTo(center)
136-
make.size.equalTo(originSize)
137-
}
138-
139-
playView.contentView.animationLayout(safeAreaInsets: .zero, to: .small)
140-
103+
playerView.contentView.animationLayout(safeAreaInsets: .zero, to: .small)
141104
UIView.animate(withDuration: transitionDuration(using: transitionContext), delay: 0.0, options: .layoutSubviews, animations: {
142105
fromView.transform = .identity
143-
transitionContext.containerView.setNeedsLayout()
144-
transitionContext.containerView.layoutIfNeeded()
145-
playView.contentView.setNeedsLayout()
146-
playView.contentView.layoutIfNeeded()
106+
fromView.center = self.finalCenter
107+
fromView.bounds = self.initialBounds
108+
playerView.contentView.setNeedsLayout()
109+
playerView.contentView.layoutIfNeeded()
147110
}) { _ in
148111
fromView.transform = .identity
112+
fromView.center = self.finalCenter
113+
fromView.bounds = self.initialBounds
114+
parentStackView.addArrangedSubview(playerView)
149115
fromView.removeFromSuperview()
150-
parentView.addArrangedSubview(playView)
151116
transitionContext.completeTransition(true)
152117
UIViewController.attemptRotationToDeviceOrientation()
153118
}

CLPlayer/CLFullScreenController/CLFullScreenController.swift

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,19 @@ class CLFullScreenController: UIViewController {
2020
}
2121

2222
deinit {}
23+
24+
private(set) lazy var mainStackView: UIStackView = {
25+
let view = UIStackView()
26+
view.isUserInteractionEnabled = true
27+
view.axis = .horizontal
28+
view.distribution = .fill
29+
view.alignment = .fill
30+
view.insetsLayoutMarginsFromSafeArea = false
31+
view.isLayoutMarginsRelativeArrangement = true
32+
view.layoutMargins = .zero
33+
view.spacing = 0
34+
return view
35+
}()
2336
}
2437

2538
// MARK: - JmoVxia---生命周期
@@ -56,6 +69,10 @@ extension CLFullScreenController {
5669
private extension CLFullScreenController {
5770
func initUI() {
5871
view.backgroundColor = .black
72+
view.addSubview(mainStackView)
73+
mainStackView.snp.makeConstraints { make in
74+
make.edges.equalToSuperview()
75+
}
5976
}
6077
}
6178

CLPlayer/CLPlayerContentView/CLPlayerContentView.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -612,7 +612,7 @@ private extension CLPlayerContentView {
612612
}
613613

614614
func autoFadeOutTooView() {
615-
autoFadeOutTimer = CLGCDTimer(interval: 0, initialDelay: 0.25 + config.autoFadeOut)
615+
autoFadeOutTimer = CLGCDTimer(interval: 0.25 + config.autoFadeOut, initialDelay: 0.25 + config.autoFadeOut)
616616
autoFadeOutTimer?.run { [weak self] _ in
617617
self?.hiddenToolView()
618618
}

CLPlayer/CLPlayerView.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -362,15 +362,15 @@ private extension CLPlayerView {
362362
})
363363
}
364364

365-
func presentWithOrientation(_ orientation: CLAnimationTransitioning.CLAnimationOrientation) {
365+
func presentWithOrientation(_ orientation: CLAnimationTransitioning.AnimationOrientation) {
366366
guard Thread.isMainThread else { return DispatchQueue.main.async { self.presentWithOrientation(orientation) } }
367367
guard superview != nil else { return }
368368
guard fullScreenController == nil else { return }
369369
guard contentView.screenState == .small else { return }
370370
guard let rootViewController = keyWindow?.rootViewController else { return }
371371
contentView.screenState = .animating
372372

373-
animationTransitioning = CLAnimationTransitioning(playView: self, orientation: orientation)
373+
animationTransitioning = CLAnimationTransitioning(playerView: self, animationOrientation: orientation)
374374

375375
fullScreenController = orientation == .right ? CLFullScreenLeftController() : CLFullScreenRightController()
376376
fullScreenController?.transitioningDelegate = self

0 commit comments

Comments
 (0)