TSCustomStackView.swift 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. //
  2. // CustomStackView.swift
  3. // TestUIKit
  4. //
  5. // Created by 100Years on 2025/2/24.
  6. //
  7. import UIKit
  8. import SnapKit
  9. open class TSCustomStackView: UIView {
  10. // 内部的 UIScrollView 和 UIStackView
  11. public let scrollView: UIScrollView
  12. // public let scrollView: KLMultiScrollContainer
  13. public let stackView: UIStackView
  14. // 开放的属性,用于设置方向和间距
  15. public var axis: NSLayoutConstraint.Axis {
  16. get {
  17. return stackView.axis
  18. }
  19. set {
  20. stackView.axis = newValue
  21. updateScrollViewConstraints()
  22. }
  23. }
  24. public var spacing: CGFloat {
  25. get {
  26. return stackView.spacing
  27. }
  28. set {
  29. stackView.spacing = newValue
  30. }
  31. }
  32. public var viewH:CGFloat {
  33. get {
  34. return scrollView.contentSize.height
  35. }
  36. }
  37. // 初始化方法
  38. public init(axis: NSLayoutConstraint.Axis = .vertical,alignment:UIStackView.Alignment = .leading, spacing: CGFloat = 0) {
  39. self.scrollView = UIScrollView()
  40. self.scrollView.showsVerticalScrollIndicator = false
  41. self.scrollView.showsHorizontalScrollIndicator = false
  42. self.stackView = UIStackView()
  43. self.stackView.axis = axis
  44. self.stackView.spacing = spacing
  45. self.stackView.alignment = alignment
  46. self.stackView.distribution = .fill
  47. super.init(frame: .zero)
  48. setupUI()
  49. }
  50. required public init?(coder: NSCoder) {
  51. fatalError("init(coder:) has not been implemented")
  52. }
  53. // 设置 UI
  54. private func setupUI() {
  55. // 添加 scrollView
  56. addSubview(scrollView)
  57. scrollView.snp.makeConstraints { make in
  58. make.edges.equalToSuperview()
  59. }
  60. // 添加 stackView 到 scrollView
  61. scrollView.addSubview(stackView)
  62. updateScrollViewConstraints()
  63. }
  64. // 根据轴方向更新约束
  65. private func updateScrollViewConstraints() {
  66. stackView.snp.remakeConstraints { make in
  67. make.edges.equalToSuperview()
  68. // 根据轴方向设置 contentSize
  69. if axis == .vertical {
  70. make.width.equalTo(scrollView)
  71. } else {
  72. make.height.equalTo(scrollView)
  73. }
  74. }
  75. }
  76. // 动态添加子视图的方法
  77. public func addSubviewToStack(_ view: UIView,length:CGFloat? = nil) {
  78. stackView.addArrangedSubview(view)
  79. view.snp.makeConstraints { make in
  80. if axis == .vertical {
  81. make.width.equalTo(stackView)
  82. if let length = length {
  83. make.height.equalTo(length)
  84. }
  85. } else {
  86. make.height.equalTo(stackView)
  87. if let length = length {
  88. make.width.equalTo(length)
  89. }
  90. }
  91. }
  92. }
  93. //动态添加子视图的方法(添加到白板一个空板 View)
  94. public func addSubviewToStackWhiteBoard(_ view: UIView,length:CGFloat? = nil) {
  95. let bgView = UIView()
  96. bgView.addSubview(view)
  97. addSubviewToStack(bgView,length: length)
  98. }
  99. // 在指定位置插入子视图
  100. public func insertViewToStack(_ view: UIView, at stackIndex: Int) {
  101. stackView.insertArrangedSubview(view, at: stackIndex)
  102. // 可以根据需要对子视图进行额外的布局设置
  103. view.snp.makeConstraints { make in
  104. if axis == .vertical {
  105. make.width.equalTo(stackView)
  106. } else {
  107. make.height.equalTo(stackView)
  108. }
  109. }
  110. }
  111. // 移除子视图
  112. public func removeViewToStack(_ view: UIView) {
  113. stackView.removeArrangedSubview(view)
  114. view.removeFromSuperview()
  115. }
  116. public func addSpacing(length:CGFloat) {
  117. let view = UIView()
  118. addSubviewToStack(view)
  119. view.snp.makeConstraints { make in
  120. if axis == .vertical {
  121. make.height.equalTo(length)
  122. } else {
  123. make.width.equalTo(length)
  124. }
  125. }
  126. }
  127. }
  128. extension UIStackView {
  129. public func addSpacing(length:CGFloat) {
  130. let view = UIView()
  131. self.addArrangedSubview(view)
  132. view.snp.makeConstraints { make in
  133. if axis == .vertical {
  134. make.width.equalToSuperview()
  135. make.height.equalTo(length)
  136. } else {
  137. make.width.equalTo(length)
  138. make.height.equalToSuperview()
  139. }
  140. }
  141. }
  142. }