Music_Player3/Pods/JXSegmentedView/Sources/Indicator/JXSegmentedIndicatorLineView.swift
2024-05-14 15:04:59 +08:00

117 lines
5.0 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// JXSegmentedIndicatorLineView.swift
// JXSegmentedView
//
// Created by jiaxin on 2018/12/26.
// Copyright © 2018 jiaxin. All rights reserved.
//
import UIKit
public enum JXSegmentedIndicatorLineStyle {
case normal
case lengthen
case lengthenOffset
}
open class JXSegmentedIndicatorLineView: JXSegmentedIndicatorBaseView {
open var lineStyle: JXSegmentedIndicatorLineStyle = .normal
/// lineStylelengthenOffset使x
open var lineScrollOffsetX: CGFloat = 10
open override func commonInit() {
super.commonInit()
indicatorHeight = 3
}
open override func refreshIndicatorState(model: JXSegmentedIndicatorSelectedParams) {
super.refreshIndicatorState(model: model)
backgroundColor = indicatorColor
layer.cornerRadius = getIndicatorCornerRadius(itemFrame: model.currentSelectedItemFrame)
let width = getIndicatorWidth(itemFrame: model.currentSelectedItemFrame, itemContentWidth: model.currentItemContentWidth)
let height = getIndicatorHeight(itemFrame: model.currentSelectedItemFrame)
let x = model.currentSelectedItemFrame.origin.x + (model.currentSelectedItemFrame.size.width - width)/2
var y: CGFloat = 0
switch indicatorPosition {
case .top:
y = verticalOffset
case .bottom:
y = model.currentSelectedItemFrame.size.height - height - verticalOffset
case .center:
y = (model.currentSelectedItemFrame.size.height - height)/2 + verticalOffset
}
frame = CGRect(x: x, y: y, width: width, height: height)
}
open override func contentScrollViewDidScroll(model: JXSegmentedIndicatorTransitionParams) {
super.contentScrollViewDidScroll(model: model)
guard canHandleTransition(model: model) else {
return
}
let rightItemFrame = model.rightItemFrame
let leftItemFrame = model.leftItemFrame
let percent = model.percent
var targetX: CGFloat = leftItemFrame.origin.x
var targetWidth = getIndicatorWidth(itemFrame: leftItemFrame, itemContentWidth: model.leftItemContentWidth)
let leftWidth = targetWidth
let rightWidth = getIndicatorWidth(itemFrame: rightItemFrame, itemContentWidth: model.rightItemContentWidth)
let leftX = leftItemFrame.origin.x + (leftItemFrame.size.width - leftWidth)/2
let rightX = rightItemFrame.origin.x + (rightItemFrame.size.width - rightWidth)/2
switch lineStyle {
case .normal:
targetX = JXSegmentedViewTool.interpolate(from: leftX, to: rightX, percent: CGFloat(percent))
if indicatorWidth == JXSegmentedViewAutomaticDimension {
targetWidth = JXSegmentedViewTool.interpolate(from: leftWidth, to: rightWidth, percent: CGFloat(percent))
}
case .lengthen:
//50%width50%xwidth
let maxWidth = rightX - leftX + rightWidth
if percent <= 0.5 {
targetX = leftX
targetWidth = JXSegmentedViewTool.interpolate(from: leftWidth, to: maxWidth, percent: CGFloat(percent*2))
}else {
targetX = JXSegmentedViewTool.interpolate(from: leftX, to: rightX, percent: CGFloat((percent - 0.5)*2))
targetWidth = JXSegmentedViewTool.interpolate(from: maxWidth, to: rightWidth, percent: CGFloat((percent - 0.5)*2))
}
case .lengthenOffset:
//50%widthx50%xwidth
let maxWidth = rightX - leftX + rightWidth - lineScrollOffsetX*2
if percent <= 0.5 {
targetX = JXSegmentedViewTool.interpolate(from: leftX, to: leftX + lineScrollOffsetX, percent: CGFloat(percent*2))
targetWidth = JXSegmentedViewTool.interpolate(from: leftWidth, to: maxWidth, percent: CGFloat(percent*2))
}else {
targetX = JXSegmentedViewTool.interpolate(from:leftX + lineScrollOffsetX, to: rightX, percent: CGFloat((percent - 0.5)*2))
targetWidth = JXSegmentedViewTool.interpolate(from: maxWidth, to: rightWidth, percent: CGFloat((percent - 0.5)*2))
}
}
self.frame.origin.x = targetX
self.frame.size.width = targetWidth
}
open override func selectItem(model: JXSegmentedIndicatorSelectedParams) {
super.selectItem(model: model)
let targetWidth = getIndicatorWidth(itemFrame: model.currentSelectedItemFrame, itemContentWidth: model.currentItemContentWidth)
var toFrame = self.frame
toFrame.origin.x = model.currentSelectedItemFrame.origin.x + (model.currentSelectedItemFrame.size.width - targetWidth)/2
toFrame.size.width = targetWidth
if canSelectedWithAnimation(model: model) {
UIView.animate(withDuration: scrollAnimationDuration, delay: 0, options: .curveEaseOut, animations: {
self.frame = toFrame
}) { (_) in
}
}else {
frame = toFrame
}
}
}