Skip to content

Commit e7f7808

Browse files
committed
Developed segmented control according as page view logic.
1 parent 1dc3c32 commit e7f7808

2 files changed

Lines changed: 77 additions & 21 deletions

File tree

Source/PuiPageViewSegmentedControl.swift

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ open class PuiPageViewSegmentedControl: PuiSegmentedControl {
2020
for subview in self.pageViewController?.view.subviews ?? [] {
2121
if let scrollView = subview as? UIScrollView {
2222
scrollView.delegate = self
23+
self.scrollView = scrollView
2324
break
2425
}
2526
}
@@ -28,17 +29,32 @@ open class PuiPageViewSegmentedControl: PuiSegmentedControl {
2829

2930
// MARK: - Private Properties
3031

32+
private var scrollView: UIScrollView?
3133
private var initialScrollViewPosition: CGFloat = 0
32-
private var transactionCompleted: Bool = true
34+
35+
// MARK: - Override Methods
36+
37+
open override func segmentedControlTransationBegin(oldValue: Int, newValue: Int) {
38+
super.segmentedControlTransationBegin(oldValue: oldValue, newValue: newValue)
39+
40+
// When user tapped to segmented control, then tapped to pageview before animation finished.
41+
// Segment problem occurs. So I disable to scroll when animation.
42+
self.scrollView?.isScrollEnabled = false
43+
}
44+
45+
open override func segmentedControlTransationEnded(oldValue: Int, newValue: Int) {
46+
super.segmentedControlTransationEnded(oldValue: oldValue, newValue: newValue)
47+
48+
// Enable scroll end of animation.
49+
self.scrollView?.isScrollEnabled = true
50+
}
3351
}
3452

3553
extension PuiPageViewSegmentedControl: UIPageViewControllerDelegate {
3654
public func pageViewController(_ pageViewController: UIPageViewController,
3755
didFinishAnimating finished: Bool,
3856
previousViewControllers: [UIViewController],
3957
transitionCompleted completed: Bool) {
40-
self.transactionCompleted = true
41-
4258
// Call super method
4359
self.pageViewTransactionEnded(isCompleted: completed)
4460
}
@@ -47,9 +63,7 @@ extension PuiPageViewSegmentedControl: UIPageViewControllerDelegate {
4763
extension PuiPageViewSegmentedControl: UIScrollViewDelegate {
4864

4965
public func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
50-
if self.transactionCompleted {
51-
self.initialScrollViewPosition = scrollView.contentOffset.x
52-
}
66+
self.initialScrollViewPosition = scrollView.contentOffset.x
5367
}
5468

5569
public func scrollViewDidScroll(_ scrollView: UIScrollView) {

Source/PuiSegmentedControl.swift

Lines changed: 57 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,13 @@
99
import Foundation
1010
import UIKit
1111

12+
public protocol PuiSegmentedControlDelegate: NSObjectProtocol {
13+
14+
func segmentedControlTransationBegin(oldValue: Int, newValue: Int)
15+
func segmentedControlTransationEnded(oldValue: Int, newValue: Int)
16+
17+
}
18+
1219
open class PuiSegmentedControl: UIControl {
1320

1421
// MARK: - Data Structures
@@ -68,7 +75,9 @@ open class PuiSegmentedControl: UIControl {
6875
// The index of the selected segment's.
6976
@objc dynamic open var selectedIndex: Int = 0 {
7077
didSet {
71-
if self.isConfiguredView && oldValue != self.selectedIndex {
78+
if self.isConfiguredView
79+
&& !self.isDraggingSelectedView
80+
&& oldValue != self.selectedIndex {
7281
self.changeSegment(oldValue: oldValue, newValue: self.selectedIndex)
7382
}
7483
}
@@ -99,6 +108,8 @@ open class PuiSegmentedControl: UIControl {
99108
}
100109
}
101110

111+
public var delegate: PuiSegmentedControlDelegate?
112+
102113
// MARK: - Private Properties
103114

104115
private var isConfiguredView: Bool = false
@@ -109,6 +120,7 @@ open class PuiSegmentedControl: UIControl {
109120

110121
// Panned
111122
private var isDraggingSelectedView: Bool = false
123+
private var isAnimatingSelectedView: Bool = false
112124
private var destinationIndex: Int = 0
113125

114126
// MARK: - Init methods
@@ -133,15 +145,13 @@ open class PuiSegmentedControl: UIControl {
133145
}
134146

135147
// Configure segmented control
136-
if !self.isConfiguredView {
148+
if self.isConfiguredView {
149+
return
150+
} else {
137151
self.configure()
138152
self.isConfiguredView = true
139153
}
140154

141-
if self.isDraggingSelectedView {
142-
return
143-
}
144-
145155
// Update calculated width
146156
self.configureViewWidth()
147157

@@ -387,6 +397,16 @@ open class PuiSegmentedControl: UIControl {
387397
self.labels[newValue].isSelected = true
388398

389399
self.changeSeperatorVisibility()
400+
401+
// Set animated
402+
self.isDraggingSelectedView = false
403+
self.isAnimatingSelectedView = false
404+
405+
// Call end transaction method
406+
self.segmentedControlTransationEnded(oldValue: oldValue, newValue: newValue)
407+
408+
// Send action
409+
self.sendActions(for: .valueChanged)
390410
}
391411

392412
private func viewTappedSegmentChange(oldValue: Int, newValue: Int) {
@@ -398,10 +418,16 @@ open class PuiSegmentedControl: UIControl {
398418
// Set animated
399419
self.isDraggingSelectedView = true
400420

421+
// Call begin transaction method
422+
self.segmentedControlTransationBegin(oldValue: oldValue, newValue: newValue)
423+
424+
// Check is animated tab transation
401425
if self.isAnimatedTabTransation {
402426
UIView.animate(withDuration: self.animatedTabTransationDuration,
403427
animations: { [weak self] in
404428
guard let self = self else { return }
429+
self.isAnimatingSelectedView = true
430+
405431
// Update frame position
406432
self.selectedView.frame.origin.x = self.selectedViews[newValue].position
407433

@@ -416,6 +442,7 @@ open class PuiSegmentedControl: UIControl {
416442
}
417443
}
418444
} else {
445+
self.isAnimatingSelectedView = true
419446
self.viewTappedSegmentChangeEnded(oldValue: oldValue, newValue: newValue)
420447
}
421448
}
@@ -426,12 +453,6 @@ open class PuiSegmentedControl: UIControl {
426453

427454
// Remove animation
428455
self.selectedView.layer.removeAllAnimations()
429-
430-
// Send action
431-
self.sendActions(for: .valueChanged)
432-
433-
// Set animated
434-
self.isDraggingSelectedView = false
435456
}
436457

437458
// Configure selected view frame according to global
@@ -441,6 +462,9 @@ open class PuiSegmentedControl: UIControl {
441462
width: self.selectedViews[self.selectedIndex].width,
442463
height: self.bounds.height)
443464
self.selectedView.frame = self.applyMargin(rect: frame, to: self.selectedViewMargins)
465+
466+
// Remove animation
467+
self.selectedView.layer.removeAllAnimations()
444468
}
445469

446470
// Configure seperator visibility according to selected index
@@ -511,7 +535,12 @@ open class PuiSegmentedControl: UIControl {
511535

512536
// MARK: - Helper Methods for Page View
513537

538+
// When scrolling pageview, we need to upload segmented control with private function in this class
514539
public func scrollSegmentedControl(ratio: CGFloat) {
540+
if self.isAnimatingSelectedView {
541+
return
542+
}
543+
515544
// For Layoutsubviews control
516545
self.isDraggingSelectedView = true
517546

@@ -521,6 +550,8 @@ open class PuiSegmentedControl: UIControl {
521550
// Check out of view
522551
if (isMovingToRight && self.selectedIndex == (self.selectedViews.count - 1))
523552
|| (!isMovingToRight && self.selectedIndex == 0) {
553+
// When dragging out of view, then we can set dragging property to false
554+
self.isDraggingSelectedView = false
524555
return
525556
}
526557

@@ -557,14 +588,25 @@ open class PuiSegmentedControl: UIControl {
557588
}
558589
}
559590

591+
// When page view delegate triggered, this function configure to segmented control.
560592
public func pageViewTransactionEnded(isCompleted: Bool) {
561-
self.isDraggingSelectedView = false
562-
563593
if isCompleted {
564594
self.changeSegment(oldValue: self.selectedIndex, newValue: self.destinationIndex)
565595
} else {
566-
self.changeSegment(oldValue: self.selectedIndex, newValue: self.selectedIndex)
596+
self.isDraggingSelectedView = false
567597
}
568598
}
599+
600+
// Call function, if subclass is page view segmented control.
601+
// Then, developer configured view when transaction beginned.
602+
open func segmentedControlTransationBegin(oldValue: Int, newValue: Int) {
603+
self.delegate?.segmentedControlTransationBegin(oldValue: oldValue, newValue: newValue)
604+
}
605+
606+
// Call deelgate function, if subclass is page view segmented control.
607+
// Then, developer configured view when transaction ended.
608+
open func segmentedControlTransationEnded(oldValue: Int, newValue: Int) {
609+
self.delegate?.segmentedControlTransationEnded(oldValue: oldValue, newValue: newValue)
610+
}
569611
}
570612

0 commit comments

Comments
 (0)