Commit 64c6f640 by Dmitry Stepanets

Added custom animation to page control

parent 41db5cfa
...@@ -12,7 +12,6 @@ class OnboardingPageControl: UIView { ...@@ -12,7 +12,6 @@ class OnboardingPageControl: UIView {
private let kSpacePerDot: CGFloat = 10 private let kSpacePerDot: CGFloat = 10
private let kDotSize: CGSize = .init(width: 9, height: 9) private let kDotSize: CGSize = .init(width: 9, height: 9)
private let kIndicatorSize: CGSize = .init(width: 6, height: 6) private let kIndicatorSize: CGSize = .init(width: 6, height: 6)
private var currentPageIndex = 0
private let totalPagesCount: Int private let totalPagesCount: Int
private let indicator = UIView() private let indicator = UIView()
private var dots = [UIView]() private var dots = [UIView]()
...@@ -20,46 +19,58 @@ class OnboardingPageControl: UIView { ...@@ -20,46 +19,58 @@ class OnboardingPageControl: UIView {
init(totalPagesCount: Int) { init(totalPagesCount: Int) {
self.totalPagesCount = totalPagesCount self.totalPagesCount = totalPagesCount
super.init(frame: .zero) super.init(frame: .zero)
self.backgroundColor = .lightGray
prepareView()
prepareDots() prepareDots()
prepareIndicator() prepareIndicator()
snp.makeConstraints { make in
make.height.equalTo(kDotSize.height)
}
} }
required init?(coder: NSCoder) { required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented") fatalError("init(coder:) has not been implemented")
} }
func scroll(toPage index: Int, screenTransitionProgress: CGFloat) { func scroll(toPage nextPageIndex: Int, currentPageIndex: Int, screenTransitionProgress: CGFloat) {
guard screenTransitionProgress != 0 else { return } guard screenTransitionProgress != 0 else { return }
var scrollProgress = max(0, screenTransitionProgress) var scrollProgress = max(0, screenTransitionProgress)
scrollProgress = min(screenTransitionProgress, 1) scrollProgress = min(screenTransitionProgress, 1)
print("[Page] scroll to \(index) progress: \(scrollProgress)") let targetDot = dots[nextPageIndex]
let targetDot = dots[index] let previousDot = dots[currentPageIndex]
let previousDot = dots[index == 0 ? 0 : index - 1]
//Scale //Scale
// let scaleDelta = (kDotSize.width - kIndicatorSize.width) * scrollProgress let scaleDelta = (kDotSize.width - kIndicatorSize.width) * scrollProgress
// previousDot.frame.size = .init(width: kIndicatorSize.width + scaleDelta, height: kIndicatorSize.height + scaleDelta) targetDot.snp.updateConstraints { update in
// print("[Frame] prev dot frame: \(previousDot.frame)") update.width.equalTo(kDotSize.width - scaleDelta)
update.height.equalTo(kDotSize.height - scaleDelta)
}
targetDot.layer.cornerRadius = (kDotSize.height - scaleDelta) / 2
let delta = targetDot.frame.origin.x - previousDot.frame.origin.x previousDot.snp.updateConstraints { update in
update.width.equalTo(kIndicatorSize.width + scaleDelta)
update.height.equalTo(kIndicatorSize.height + scaleDelta)
}
previousDot.layer.cornerRadius = (kIndicatorSize.height + scaleDelta) / 2
//Offset
let offsetDelta = targetDot.frame.origin.x - previousDot.frame.origin.x
indicator.snp.updateConstraints { update in indicator.snp.updateConstraints { update in
update.left.equalToSuperview().inset(previousDot.frame.origin.x + delta * scrollProgress) update.left.equalToSuperview().inset(previousDot.frame.origin.x + offsetDelta * scrollProgress)
} }
// indicator.frame.origin.x = previousDot.frame.origin.x + delta * scrollProgress
} }
} }
//MARK:- Prepare
private extension OnboardingPageControl { private extension OnboardingPageControl {
func prepareView() {
snp.makeConstraints { make in
make.height.equalTo(kDotSize.height)
}
}
func prepareDots() { func prepareDots() {
for index in 0..<totalPagesCount { for index in 0..<totalPagesCount {
let dot = UIView() let dot = UIView()
dot.backgroundColor = UIColor.blue dot.backgroundColor = UIColor(hex: 0xD0D0D0)
dot.layer.cornerRadius = kDotSize.height / 2 dot.layer.cornerRadius = kDotSize.height / 2
addSubview(dot) addSubview(dot)
dots.append(dot) dots.append(dot)
...@@ -76,7 +87,7 @@ private extension OnboardingPageControl { ...@@ -76,7 +87,7 @@ private extension OnboardingPageControl {
} }
func prepareIndicator() { func prepareIndicator() {
indicator.backgroundColor = UIColor.red indicator.backgroundColor = ThemeManager.currentTheme.graphTintColor
indicator.layer.cornerRadius = kIndicatorSize.height / 2 indicator.layer.cornerRadius = kIndicatorSize.height / 2
addSubview(indicator) addSubview(indicator)
......
...@@ -48,8 +48,7 @@ enum OnboardingControllerType { ...@@ -48,8 +48,7 @@ enum OnboardingControllerType {
class OnboardingPageController: UIPageViewController, UIScrollViewDelegate { class OnboardingPageController: UIPageViewController, UIScrollViewDelegate {
private let coordinator: AppCoordinator private let coordinator: AppCoordinator
private let control = OnboardingPageControl(totalPagesCount: 3) private let pageControl = OnboardingPageControl(totalPagesCount: 3)
private let pageControl = UIPageControl()
private let closeButton = UIButton() private let closeButton = UIButton()
private var pages = [UIViewController]() private var pages = [UIViewController]()
private let skipButton = SelfSizingButton() private let skipButton = SelfSizingButton()
...@@ -74,16 +73,6 @@ class OnboardingPageController: UIPageViewController, UIScrollViewDelegate { ...@@ -74,16 +73,6 @@ class OnboardingPageController: UIPageViewController, UIScrollViewDelegate {
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
#if DEBUG
view.addSubview(control)
control.snp.makeConstraints { make in
make.top.equalToSuperview().inset(80)
make.left.equalToSuperview().inset(100)
}
#else
fatalError("Remove in release")
#endif
prepareController() prepareController()
prepareCloseButton() prepareCloseButton()
preparePageControl() preparePageControl()
...@@ -91,7 +80,6 @@ class OnboardingPageController: UIPageViewController, UIScrollViewDelegate { ...@@ -91,7 +80,6 @@ class OnboardingPageController: UIPageViewController, UIScrollViewDelegate {
prepareNextButton() prepareNextButton()
prepareDoneButton() prepareDoneButton()
updateUI() updateUI()
control.sizeToFit()
} }
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
...@@ -123,7 +111,6 @@ class OnboardingPageController: UIPageViewController, UIScrollViewDelegate { ...@@ -123,7 +111,6 @@ class OnboardingPageController: UIPageViewController, UIScrollViewDelegate {
guard nextIndex < pages.count else { return } guard nextIndex < pages.count else { return }
setViewControllers([pages[nextIndex]], direction: .forward, animated: true) {[weak self] _ in setViewControllers([pages[nextIndex]], direction: .forward, animated: true) {[weak self] _ in
self?.currentPageIndex = nextIndex self?.currentPageIndex = nextIndex
self?.pageControl.currentPage = nextIndex
self?.showDoneIfNeeded(for: nextIndex) self?.showDoneIfNeeded(for: nextIndex)
} }
} }
...@@ -136,13 +123,11 @@ class OnboardingPageController: UIPageViewController, UIScrollViewDelegate { ...@@ -136,13 +123,11 @@ class OnboardingPageController: UIPageViewController, UIScrollViewDelegate {
closeButton.tintColor = color closeButton.tintColor = color
skipButton.setTitleColor(color, for: .normal) skipButton.setTitleColor(color, for: .normal)
nextButton.tintColor = color nextButton.tintColor = color
pageControl.pageIndicatorTintColor = UIColor(hex: 0xd0d0d0)
case .dark: case .dark:
let color = ThemeManager.currentTheme.primaryTextColor let color = ThemeManager.currentTheme.primaryTextColor
closeButton.tintColor = color closeButton.tintColor = color
skipButton.setTitleColor(color, for: .normal) skipButton.setTitleColor(color, for: .normal)
nextButton.tintColor = color nextButton.tintColor = color
pageControl.pageIndicatorTintColor = UIColor.white
} }
} }
...@@ -178,13 +163,10 @@ private extension OnboardingPageController { ...@@ -178,13 +163,10 @@ private extension OnboardingPageController {
} }
func preparePageControl() { func preparePageControl() {
pageControl.currentPageIndicatorTintColor = .blue
pageControl.currentPage = 0
pageControl.numberOfPages = pages.count
view.addSubview(pageControl) view.addSubview(pageControl)
pageControl.snp.makeConstraints { make in pageControl.snp.makeConstraints { make in
make.left.equalToSuperview().inset(20) make.left.equalToSuperview().inset(26)
make.bottom.equalTo(view.safeAreaLayoutGuide.snp.bottom).offset(-32) make.bottom.equalTo(view.safeAreaLayoutGuide.snp.bottom).offset(-32)
} }
} }
...@@ -267,14 +249,15 @@ extension OnboardingPageController { ...@@ -267,14 +249,15 @@ extension OnboardingPageController {
func scrollViewDidScroll(_ scrollView: UIScrollView) { func scrollViewDidScroll(_ scrollView: UIScrollView) {
let pageWidth = scrollView.contentSize.width / CGFloat(pages.count) let pageWidth = scrollView.contentSize.width / CGFloat(pages.count)
let progress = (scrollView.contentOffset.x - pageWidth) / pageWidth let progress = (scrollView.contentOffset.x - pageWidth) / pageWidth
print("progress: \(progress)")
let nextPageIndex = progress < 0 ? currentPageIndex - 1 : currentPageIndex + 1 let nextPageIndex = progress < 0 ? currentPageIndex - 1 : currentPageIndex + 1
if nextPageIndex > pages.count - 1 || nextPageIndex < 0 { if nextPageIndex > pages.count - 1 || nextPageIndex < 0 {
return return
} }
control.scroll(toPage: nextPageIndex, screenTransitionProgress: abs(progress)) pageControl.scroll(toPage: nextPageIndex,
currentPageIndex: currentPageIndex,
screenTransitionProgress: abs(progress))
} }
} }
...@@ -309,7 +292,6 @@ extension OnboardingPageController: UIPageViewControllerDelegate { ...@@ -309,7 +292,6 @@ extension OnboardingPageController: UIPageViewControllerDelegate {
return return
} }
pageControl.currentPage = currentPageIndex
self.currentPageIndex = currentPageIndex self.currentPageIndex = currentPageIndex
showDoneIfNeeded(for: currentPageIndex) showDoneIfNeeded(for: currentPageIndex)
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment