Compatibility
- 2.3.5 and master5.35.25.15.04.2
- 2.3.5 and masteriOSmacOS(Intel)macOS(ARM)LinuxtvOSwatchOS
UISegmentedControl remake that supports selecting multiple segments, vertical stacking, combining text and images.
UISegmentedControl remake that supports selecting multiple segments, vertical stacking, combining text and images.
Very similar to UISegmentedControl
, can be used as a drop-in replacement in most cases.
If you use Interface Builder, add a regular UIView
and then set its class to MultiSelectSegmentedControl
.
MultiSegmentPicker(
selectedSegmentIndexes: $indexSet,
items: ["One", "Two", image, [image2, "Text"], "Last"]
)
The properties mentioned below can be passed as arguments to the MultiSegmentPicker
initializer, or used as view modifiers (e.g., .borderWidth(3)
).
Each segment can contain an image, a text, or both:
let multiSelect = MultiSelectSegmentedControl()
multiSelect.items = ["One", "Two", image, [image2, "Text"], "Last"]
Images are shown in full color (unlike UISegmentedControl
). To make them render in the same tintColor
as the control, use template mode:
multiSelect.items = [image1, image2, image3].map { $0.withRenderingMode(.alwaysTemplate) }
multiSelect.selectedSegmentIndexes = [1, 2, 4]
Or just single selection:
multiSelect.allowsMultipleSelection = false
multiSelect.selectedSegmentIndex = 3
let selectedIndices: IndexSet = multiSelect.selectedSegmentIndexes
Or to get the titles:
let titles: [String] = multiSelect.selectedSegmentTitles
You can use standard target-action:
multiSelect.addTarget(self, action: #selector(selectionChanged), for: .valueChanged)
Or conform to the delegate protocol:
extension MyViewController: MultiSelectSegmentedControlDelegate {
func multiSelect(_ multiSelectSegmentedControl: MultiSelectSegmentedControl, didChange value: Bool, at index: Int) {
print("selected \(value) at \(index)")
}
}
... and set the delegate:
multiSelect.delegate = self
Color:
multiSelect.tintColor = .green
Background Color (optional - use if background color should be different from tint color):
multiSelect.selectedBackgroundColor = .blue
Shape:
multiSelect.borderWidth = 3 // Width of the dividers between segments and the border around the view.
multiSelect.borderRadius = 32 // Corner radius of the view.
Stack the segments vertically:
multiSelect.isVertical = true
Stack each segment contents vertically when it contains both image and text:
multiSelect.isVerticalSegmentContents = true
Text styling:
multiSelect.setTitleTextAttributes([.foregroundColor: UIColor.yellow], for: .selected)
multiSelect.setTitleTextAttributes([.obliqueness: 0.25], for: .normal)
More label styling:
multiSelect.titleConfigurationHandler = {
$0.numberOfLines = 0
$0.lineBreakMode = .byWordWrapping
}
pod 'MultiSelectSegmentedControl'
dependencies: [
.package(url: "https://github.com/yonat/MultiSelectSegmentedControl", from: "2.3.5")
]
layoutMargins
, stackView.spacing