Skip to content

Commit

Permalink
improvement: set origin when install indicator
Browse files Browse the repository at this point in the history
  • Loading branch information
iWECon committed Apr 25, 2023
1 parent 9b4b1fd commit 9dda279
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 30 deletions.
3 changes: 1 addition & 2 deletions Demo/Segmenter/ViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,7 @@ class ViewController: UIViewController {
let r = UIView()
r.backgroundColor = .blue
segmenter.isShadowShouldShow = false
segmenter.contentInset.bottom = 14
segmenter.currentIndex = 1
segmenter.contentInset.bottom = 10
// set indicator
segmenter.indicator = LineIndicator()
segmenter.segments = [
Expand Down
9 changes: 4 additions & 5 deletions Sources/Segmenter/Indicator/LineIndicator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,8 @@ public final class LineIndicator: UIView, Indicator {
}

public func install(withSementView segmentView: SegmentView) {
UIView.animate(withDuration: Segmenter.default.animateDuration, delay: 0, usingSpringWithDamping: 0.8, initialSpringVelocity: 0.9) {
self.frame.size = CGSize(width: segmentView.frame.width, height: 4)
}
self.frame.size = CGSize(width: segmentView.frame.width, height: 4)
self.frame.origin.x = segmentView.frame.minX
}

enum Behavior {
Expand All @@ -47,9 +46,9 @@ public final class LineIndicator: UIView, Indicator {
UIView.addKeyframe(withRelativeStartTime: 0, relativeDuration: 0.3) {
switch behavior {
case .forward:
self.frame.size.width = (from.frame.maxX - from.frame.minX) + (to.frame.maxX - to.frame.minX)
self.frame.size.width = (to.frame.midX - from.frame.minX)
case .backward:
self.frame.size.width = (from.frame.maxX - to.frame.minX)
self.frame.size.width = (from.frame.maxX - to.frame.midX)
self.frame.origin.x = right - self.frame.width
}
}
Expand Down
34 changes: 11 additions & 23 deletions Sources/Segmenter/Segmenter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -76,22 +76,15 @@ public final class Segmenter: UIControl {
}

/// Indicator, indicating the currently active segment
public var indicator: Indicator? {
didSet {
oldValue?.removeFromSuperview()
DispatchQueue.main.async {
self.reloadIndicator()
}
}
}
public var indicator: Indicator?

/// some property(left/right) won’t be join calculate when use `.cetered` or `.evened`
/// default is .init(top: 0, left: 15, bottom: 6, right: 15)
///
/// 当 `distribution` 为 `.centered` or `.evened` 时,其 `left` 和 `right` 在计算位置时会被忽略
@IBInspectable public lazy var contentInset: UIEdgeInsets = Self.default.contentInset {
didSet {
layoutSubviews()
setNeedsLayout()
}
}

Expand All @@ -100,7 +93,7 @@ public final class Segmenter: UIControl {
/// segment 间距,当 `distribution` 为 `.evened` 或 `.aroundEvened` 在计算位置时会被忽略, 默认值为 15
@IBInspectable public lazy var segmentSpacing: CGFloat = Self.default.segmentSpacing {
didSet {
layoutSubviews()
setNeedsLayout()
}
}

Expand Down Expand Up @@ -134,7 +127,7 @@ public final class Segmenter: UIControl {
/// segment 与附加视图之间的距离
@IBInspectable public lazy var spacingOfSegmentAndSupplementary: CGFloat = Self.default.spacingOfSegmentAndSupplementary {
didSet {
layoutSubviews()
setNeedsLayout()
}
}

Expand All @@ -159,7 +152,7 @@ public final class Segmenter: UIControl {
} else {
supplementaryView.clearGradientColor()
}
self.layoutSubviews()
setNeedsLayout()
}
}

Expand Down Expand Up @@ -408,7 +401,6 @@ public final class Segmenter: UIControl {
}

reloadSupplementaryViews()
reloadIndicator()
}

func reloadSupplementaryViews() {
Expand All @@ -428,25 +420,19 @@ public final class Segmenter: UIControl {
supplementaryViewIndependentControls()
}

layoutSubviews()
reloadIndicator()
setNeedsLayout()
}

func reloadIndicator() {
guard !segmentViews.isEmpty else { return }
func installIndicatorIfNeeded() {
guard !segmentViews.isEmpty, self.indicator?.superview != self.scrollContainer else { return }
let indexRange = 0 ..< segmentViews.count
guard let indicator, indexRange.contains(currentIndex) else { return }

// force to refresh layout
self.setNeedsLayout()
self.layoutIfNeeded()

let selectedSegmentView = segmentViews[currentIndex]
self.scrollContainer.addSubview(indicator)
indicator.install(withSementView: selectedSegmentView)
// set origin
// set origin.y
indicator.frame.origin.y = selectedSegmentView.frame.maxY + indicator.spacing
indicator.frame.origin.x = selectedSegmentView.frame.minX
}

/// check the segment item size
Expand Down Expand Up @@ -740,6 +726,8 @@ public final class Segmenter: UIControl {
}
break
}

installIndicatorIfNeeded()
}

public override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
Expand Down

0 comments on commit 9dda279

Please sign in to comment.