I am a total noob and learning iOS development programmatically and not with storyboards.
I have created two test controllers
- Uses a UIPicker to allow selection of a Job Role using the scroll wheel
- Uses a UICollectionView to all selection of a Job Role by tapping an Icon
I will probably use the UIPicker when a user registers and the UICollectionView to select a role to view its details as a Menu
I have created arrays in each controller to provide the required data for each
What I would like to do is be able to use a Data Model to hold eNums that hold the common data used by both.
I am not sure how to create arrays for my picker and collection views
I wanted to use enums as later on when a user has made a selection and I pass the output to my next controllers to act on I felt it would be good to do a switch on the selected item.
Appreciate any guidance and also if I am totally mad and going about it all wrong.
Cheers
JobRoleMenuViewController.swift
import UIKit
private let reuseIdentifier = "Cell"
class JobRoleMenuViewController: UICollectionViewController {
// MARK: - Properties
var jobRoleLabel: [String] = [
"Doctor",
"Teacher",
"Student",
"Shop Keeper",
"Fire Fighter",
"I'm So Lucky!"
]
var jobRoleImage: [UIImage] = [
UIImage(named: "doctor")!,
UIImage(named: "teacher")!,
UIImage(named: "student")!,
UIImage(named: "retailer")!,
UIImage(named: "firefighter")!,
UIImage(named: "astronaut")!
]
// MARK: - Lifecycle
override func viewDidLoad() {
super.viewDidLoad()
collectionView.backgroundColor = .white
self.collectionView.register(JobRoleCell.self, forCellWithReuseIdentifier: reuseIdentifier)
}
// MARK: -
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return jobRoleImage.count
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! JobRoleCell
cell.categoryLabel.text = jobRoleLabel[indexPath.item]
cell.categoryImage = jobRoleImage[indexPath.row]
return cell
}
override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
print("DEBUG: Tapped cell at: \(indexPath.row)")
}
}
// MARK: -
extension JobRoleMenuViewController: UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 1
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
return 1
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let width = (view.frame.width - 2) / 3
return CGSize(width: width, height: width)
}
}
}
JobRoleCell.swift
Please note: in the below code centerX and anchor are extensions I have created in Extensions.swfit so I can reuse across all code
import UIKit
class JobRoleCell: UICollectionViewCell {
// MARK: - Properties
var categoryImage: UIImage? {
didSet {
guard let categoryImage = categoryImage else { return }
imageView.image = categoryImage
}
}
let categoryLabel: UILabel = {
let label = UILabel()
label.font = UIFont.boldSystemFont(ofSize: 16)
label.tintColor = .black
return label
}()
let imageView: UIImageView = {
let iv = UIImageView()
return iv
}()
// MARK: - Lifcycle
override init(frame: CGRect) {
super.init(frame: frame)
addSubview(imageView)
imageView.anchor(top: topAnchor, left: leftAnchor, bottom: bottomAnchor, right: rightAnchor, paddingTop: 40, paddingLeft: 40, paddingBottom: 40, paddingRight: 40)
addSubview(categoryLabel)
categoryLabel.centerX(inView: self)
categoryLabel.anchor(bottom: bottomAnchor)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
JobRolePicker.swift
import UIKit
class JobRolePickerController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {
// MARK: - Properties
let jobRolePickerData: [String] = [
"Doctor",
"Teacher",
"Student",
"Shop Keeper",
"Fire Fighter",
"Astronaut"
]
// MARK: - Lifecycle
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
let picker: UIPickerView = UIPickerView()
picker.delegate = self as UIPickerViewDelegate
picker.dataSource = self as UIPickerViewDataSource
self.view.addSubview(picker)
picker.center = self.view.center
}
// MARK: - PickerController
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return jobRolePickerData.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
let row = jobRolePickerData[row]
return row
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
// let jobRoleSelected = jobRolePickerData[pickerView.selectedRow(inComponent: 0)]
print("DEBUG: Tapped cell at: \(jobRolePickerData[row])")
}
}
I would like to try and use this to hold the data and share across all that need it and also use this to switch the outputs of both JobRoleMenuView and JobRolePickerView
Job.swift
import Foundation
enum JobRole: Int {
//enum TradeType: CaseIterable {
case doctor
case teacher
case student
case retailer
case fireFighter
case astronaut
var JobTitle: String {
switch self {
case .doctor:
return "Doctor"
case .teacher:
return "Teacher"
case .student:
return "Student"
case .retailer:
return "Shop Keeper"
case .fireFighter:
return "Fire Fighter"
case .astronaut:
return "Fly me to the Moon"
}
}
var JobImage: String? {
switch self {
case .doctor:
return "doctor"
case .teacher:
return "teacher"
case .student:
return "student"
case .retailer:
return "retailer"
case .fireFighter:
return "firefighter"
case .astronaut:
return "astronaut"
}
}
}
I currently have the following screens and currently in debug window it prints out whatever is selected on each
JobRoleMenuScreenShot
JobRolePickerScreenShot