A customizable flat-design alternative to UIPickerView using UITableView, supporting infinite scroll, multiple components, and modern selection styles.
- Flat Design: Modern flat design using
UITableViewfor each component - Infinite Scrolling: Support for infinite scrolling that loops through data
- Multiple Components: Support for multiple columns (components) like
UIPickerView - Customizable Selection: Multiple selection styles (none, indicator, overlay, image)
- Familiar API: Similar API to
UIPickerViewfor easy adoption - Auto Layout: Built with Auto Layout for flexible sizing
- Customizable: Extensive customization options for appearance and behavior
- iOS 12.0+
- macOS 11.0+
- Swift 5.9+
- Xcode 15.0+
Add UIFlatPickerView to your project in Xcode:
- Go to File → Add Package Dependencies
- Enter the repository URL:
https://github.com/mrardyan/UIFlatPickerView.git - Click Add Package
Or add it to your Package.swift:
dependencies: [
.package(url: "https://github.com/mrardyan/UIFlatPickerView.git", from: "1.0.1")
]Here's a simple example of how to use UIFlatPickerView in your view controller:
import UIKit
import UIFlatPickerView
class ViewController: UIViewController {
@IBOutlet weak var pickerView: UIFlatPickerView!
let months = ["January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December"]
let years = Array(2020...2030).map { String($0) }
override func viewDidLoad() {
super.viewDidLoad()
// Set up the picker view
pickerView.dataSource = self
pickerView.delegate = self
// Configure appearance
pickerView.selectionStyle = .defaultIndicator
pickerView.selectionIndicatorColor = .systemBlue // Applies to all components
pickerView.infiniteScrollEnabled = false // Set to true for infinite scrolling
}
}
// MARK: - UIFlatPickerViewDataSource
extension ViewController: UIFlatPickerViewDataSource {
func numberOfComponents(in pickerView: UIFlatPickerView) -> Int {
return 2 // Month and Year
}
func pickerView(_ pickerView: UIFlatPickerView, numberOfRowsInComponent component: Int) -> Int {
switch component {
case 0: return months.count
case 1: return years.count
default: return 0
}
}
func pickerView(_ pickerView: UIFlatPickerView, titleForRow row: Int, forComponent component: Int) -> String {
switch component {
case 0: return months[row]
case 1: return years[row]
default: return ""
}
}
}
// MARK: - UIFlatPickerViewDelegate
extension ViewController: UIFlatPickerViewDelegate {
func pickerView(_ pickerView: UIFlatPickerView, didSelectRow row: Int, inComponent component: Int) {
let month = months[pickerView.selectedRow(inComponent: 0) ?? 0]
let year = years[pickerView.selectedRow(inComponent: 1) ?? 0]
print("Selected: \(month) \(year)")
}
}pickerView.infiniteScrollEnabled = true // Enables infinite scrolling for all componentspickerView.selectionIndicatorColor = .red // Changes indicator color for all componentsImplement the required protocols:
extension YourViewController: UIFlatPickerViewDataSource, UIFlatPickerViewDelegate {
func numberOfComponents(in pickerView: UIFlatPickerView) -> Int { 1 }
func pickerView(_ pickerView: UIFlatPickerView, numberOfRowsInComponent component: Int) -> Int { 12 }
func pickerView(_ pickerView: UIFlatPickerView, titleForRow row: Int, forComponent component: Int) -> String {
months[row]
}
func pickerViewRowsHeight(_ pickerView: UIFlatPickerView) -> CGFloat { 44 }
func pickerView(_ pickerView: UIFlatPickerView, didSelectRow row: Int, inComponent component: Int) {
// Handle selection
}
// ... other delegate methods as needed ...
}- Removed
ScrollingStyleenum andscrollingStyleproperty. UseinfiniteScrollEnabled(Bool) instead. selectionIndicatorColornow applies to all components.- All indicator/overlay/image logic is now handled in
PickerComponentonly.
This project is licensed under the MIT License - see the LICENSE file for details.
Contributions are welcome! Please feel free to submit a Pull Request.