TSImageIPanComparisonView.swift 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. //
  2. // TSImageIPanComparisonView.swift
  3. // testApp
  4. //
  5. // Created by 100Years on 2025/5/11.
  6. //
  7. import UIKit
  8. class TSImageIPanComparisonView: UIView , UIGestureRecognizerDelegate{
  9. // MARK: - 属性
  10. let oldImageView = UIImageView()
  11. let newImageView = UIImageView()
  12. private let lineView = UIView()
  13. private var maskLayer = CAShapeLayer()
  14. // MARK: - 初始化
  15. override init(frame: CGRect) {
  16. super.init(frame: frame)
  17. setupViews()
  18. }
  19. required init?(coder: NSCoder) {
  20. super.init(coder: coder)
  21. setupViews()
  22. }
  23. lazy var lineX:CGFloat = self.bounds.size.width/2.0 {
  24. didSet{
  25. updateView()
  26. }
  27. }
  28. lazy var panGesture: UIPanGestureRecognizer = {
  29. let panGesture = UIPanGestureRecognizer(target: self, action: #selector(handlePan(_:)))
  30. panGesture.delegate = self
  31. return panGesture
  32. }()
  33. // MARK: - 视图设置
  34. private func setupViews() {
  35. // 旧图片视图(初始显示)
  36. oldImageView.contentMode = .scaleAspectFill
  37. oldImageView.clipsToBounds = true
  38. addSubview(oldImageView)
  39. // 新图片视图(初始隐藏)
  40. newImageView.contentMode = .scaleAspectFill
  41. newImageView.clipsToBounds = true
  42. addSubview(newImageView)
  43. // 分割线样式
  44. lineView.backgroundColor = .white
  45. lineView.isHidden = true
  46. addSubview(lineView)
  47. let leftRigntImageView = UIImageView.createImageView(image: .leftContrastRight)
  48. addSubview(leftRigntImageView)
  49. leftRigntImageView.snp.makeConstraints { make in
  50. make.center.equalTo(lineView.snp.center)
  51. }
  52. addGestureRecognizer(panGesture)
  53. }
  54. func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer,
  55. shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
  56. if gestureRecognizer == panGesture {
  57. let velocity = panGesture.velocity(in: self)
  58. return abs(velocity.x) < abs(velocity.y) // 只有垂直速度更快时才响应
  59. }
  60. return true // 允许同时识别
  61. }
  62. // 处理拖动手势
  63. @objc private func handlePan(_ gesture: UIPanGestureRecognizer) {
  64. // 获取手指在视图中的移动距离(相对起点)
  65. let translation = gesture.translation(in: self)
  66. // 只处理水平移动
  67. if abs(translation.x) > abs(translation.y) {
  68. if translation.x > 0 {
  69. lineX = min(lineX + translation.x, self.width-1)
  70. } else if translation.x < 0 {
  71. lineX = max(lineX + translation.x, 0)
  72. }
  73. gesture.setTranslation(.zero, in: self)
  74. }
  75. }
  76. // MARK: - 布局
  77. override func layoutSubviews() {
  78. super.layoutSubviews()
  79. oldImageView.frame = bounds
  80. newImageView.frame = bounds
  81. lineView.frame = CGRect(x: lineX, y: 0, width: 1, height: bounds.height)
  82. }
  83. // MARK: - 公开方法
  84. func configure(oldImage: UIImage?, newImage: UIImage?) {
  85. oldImageView.image = oldImage
  86. newImageView.image = newImage
  87. lineView.isHidden = false
  88. updateView()
  89. }
  90. func configure(oldImageURLString: String, newImageURLString: String) {
  91. oldImageView.setAsyncImage(urlString: oldImageURLString)
  92. newImageView.setAsyncImage(urlString: newImageURLString)
  93. lineView.isHidden = false
  94. updateView()
  95. }
  96. // MARK: - 动画更新
  97. @objc private func updateView() {
  98. let x = lineX
  99. let frame = CGRect(
  100. x: x,
  101. y: 0,
  102. width: bounds.width - x,
  103. height: bounds.height
  104. )
  105. let path = UIBezierPath(rect: frame)
  106. // 更新分割线位置
  107. lineView.frame.origin.x = x
  108. // print("frame=\(frame)")
  109. maskLayer.path = path.cgPath
  110. newImageView.layer.mask = maskLayer
  111. }
  112. }