99import Foundation
1010import 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+
1219open 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