UISegmentedControl remake that supports selecting multiple segments, vertical stacking, combining text and images.
- Single or multiple selection.
- Horizontal or vertical stacking.
- Can show text and images together.
- Use from either storyboard or code.
- UIAppearance support.
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 = 3let selectedIndices: IndexSet = multiSelect.selectedSegmentIndexesOr to get the titles:
let titles: [String] = multiSelect.selectedSegmentTitlesYou 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 = selfColor:
multiSelect.tintColor = .greenBackground Color (optional - use if background color should be different from tint color):
multiSelect.selectedBackgroundColor = .blueShape:
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 = trueStack each segment contents vertically when it contains both image and text:
multiSelect.isVerticalSegmentContents = trueText 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.4.2")
]- foreground color of selected segment should be/appear transparent
- configure segment
layoutMargins,stackView.spacing
