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

132 lines
5.8 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.

//
// JXSegmentedIndicatorGradientView.swift
// JXSegmentedView
//
// Created by jiaxin on 2019/1/16.
// Copyright © 2019 jiaxin. All rights reserved.
//
import UIKit
/// layergradientMaskLayer
open class JXSegmentedIndicatorGradientView: JXSegmentedIndicatorBaseView {
@available(*, deprecated, renamed: "indicatorWidthIncrement")
open var gradientViewWidthIncrement: CGFloat = 20 {
didSet {
indicatorWidthIncrement = gradientViewWidthIncrement
}
}
/// colors
open var gradientColors = [CGColor]()
/// CAGradientLayerstartPointendPoint
open var gradientLayer: CAGradientLayer {
return layer as! CAGradientLayer
}
public let gradientMaskLayer: CAShapeLayer = CAShapeLayer()
open class override var layerClass: AnyClass {
return CAGradientLayer.self
}
private var gradientMaskLayerFrame = CGRect.zero
open override func commonInit() {
super.commonInit()
indicatorWidthIncrement = 20
indicatorHeight = 26
indicatorPosition = .center
verticalOffset = 0
gradientColors = [UIColor(red: 194.0/255, green: 229.0/255, blue: 156.0/255, alpha: 1).cgColor, UIColor(red: 100.0/255, green: 179.0/255, blue: 244.0/255, alpha: 1).cgColor]
gradientLayer.startPoint = CGPoint(x: 0, y: 0)
gradientLayer.endPoint = CGPoint(x: 1, y: 0)
layer.mask = gradientMaskLayer
}
open override func refreshIndicatorState(model: JXSegmentedIndicatorSelectedParams) {
super.refreshIndicatorState(model: model)
gradientLayer.colors = gradientColors
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
}
gradientMaskLayerFrame = CGRect(x: x, y: y, width: width, height: height)
let path = UIBezierPath(roundedRect: gradientMaskLayerFrame, cornerRadius: getIndicatorCornerRadius(itemFrame: model.currentSelectedItemFrame))
CATransaction.begin()
CATransaction.setDisableActions(true)
gradientMaskLayer.path = path.cgPath
CATransaction.commit()
if let collectionViewContentSize = model.collectionViewContentSize {
frame = CGRect(x: 0, y: 0, width: collectionViewContentSize.width, height: collectionViewContentSize.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 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
let targetX = JXSegmentedViewTool.interpolate(from: leftX, to: rightX, percent: CGFloat(percent))
if indicatorWidth == JXSegmentedViewAutomaticDimension {
targetWidth = JXSegmentedViewTool.interpolate(from: leftWidth, to: rightWidth, percent: CGFloat(percent))
}
gradientMaskLayerFrame.origin.x = targetX
gradientMaskLayerFrame.size.width = targetWidth
let path = UIBezierPath(roundedRect: gradientMaskLayerFrame, cornerRadius: getIndicatorCornerRadius(itemFrame: leftItemFrame))
CATransaction.begin()
CATransaction.setDisableActions(true)
gradientMaskLayer.path = path.cgPath
CATransaction.commit()
}
open override func selectItem(model: JXSegmentedIndicatorSelectedParams) {
super.selectItem(model: model)
let width = getIndicatorWidth(itemFrame: model.currentSelectedItemFrame, itemContentWidth: model.currentItemContentWidth)
var toFrame = gradientMaskLayerFrame
toFrame.origin.x = model.currentSelectedItemFrame.origin.x + (model.currentSelectedItemFrame.size.width - width)/2
toFrame.size.width = width
let path = UIBezierPath(roundedRect: toFrame, cornerRadius: getIndicatorCornerRadius(itemFrame: model.currentSelectedItemFrame))
if canSelectedWithAnimation(model: model) {
gradientMaskLayer.removeAnimation(forKey: "path")
let animation = CABasicAnimation(keyPath: "path")
animation.fromValue = gradientMaskLayer.path
animation.toValue = path.cgPath
animation.duration = scrollAnimationDuration
animation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeOut)
gradientMaskLayer.add(animation, forKey: "path")
gradientMaskLayer.path = path.cgPath
}else {
CATransaction.begin()
CATransaction.setDisableActions(true)
gradientMaskLayer.path = path.cgPath
CATransaction.commit()
}
}
}