Skip to content

Instantly share code, notes, and snippets.

@djk12587
Last active March 7, 2023 15:53
Show Gist options
  • Save djk12587/7d00ec31024f80dc06466cfb9abd83e5 to your computer and use it in GitHub Desktop.
Save djk12587/7d00ec31024f80dc06466cfb9abd83e5 to your computer and use it in GitHub Desktop.
Swift: UIStackView arrangedSubview update helper. (Helpful for stackViews embedded in a UITableViewCell/UICollectionViewCell)
import UIKit
extension UIStackView {
/**
Removes or adds views to a stackview. This is usefull if you have a stackview within a tableviewcell or collectionviewcell
- Parameters:
- desiredCount: The new total count of `ViewType`
- viewType: Your custom view type
Becareful using this if all of the stackview's arranged subviews are not of the same type! The returned array could be missing views & your datasource index might not match up resulting in an index out of bounds crash.
~~~
//Usage example
aStackView.updateArrangedSubviews(toCount: newTotalCount, ofType: SomeCustomView.self).forEach { customView in
customView.configure()
}
class SomeCustomView: UIView {
func configure() {}
}
~~~
- returns: An array of the arrangedSubviews that are of type ViewType. You can use this to configure the UI of the ViewType.
*/
func updateArrangedSubviews<ViewType: UIView>(toCount desiredCount: Int, ofType viewType: ViewType.Type) -> [ViewType] {
switch UpdateAction(desiredArrangedSubViewCountOffset: desiredCount - arrangedSubviews.count) {
case .add(let numberOfViews):
(0..<numberOfViews).forEach { _ in addArrangedSubview(viewType.init()) }
case .remove(let numberOfViews):
(0..<numberOfViews).forEach { _ in arrangedSubviews[0].removeFromSuperview() }
case .noAction: break
}
return arrangedSubviews.compactMap { $0 as? ViewType }
}
private enum UpdateAction {
case add(numberOfViews: Int)
case remove(numberOfViews: Int)
case noAction
init(desiredArrangedSubViewCountOffset: Int) {
switch desiredArrangedSubViewCountOffset {
case Int.min..<0:
self = .remove(numberOfViews: abs(desiredArrangedSubViewCountOffset))
case 1...Int.max:
self = .add(numberOfViews: abs(desiredArrangedSubViewCountOffset))
default:
self = .noAction
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment