block-employee-directory/EmployeeDirectory/Views/EmployeeTableViewCell.swift
Matt Bruce 3314304b46 fixed bug
Signed-off-by: Matt Bruce <mbrucedogs@gmail.com>
2025-01-21 11:15:41 -06:00

151 lines
5.7 KiB
Swift

//
// EmployeeTableViewCell.swift
// EmployeeDirectory
//
// Created by Matt Bruce on 1/20/25.
//
import UIKit
import Combine
/// This is the Cell used in the EmployeesTableViewController to show
/// the properties of an Employee model.
public class EmployeeTableViewCell: UITableViewCell {
/// Used in the TableView registration
static let identifier = "EmployeeTableViewCell"
// MARK: - Properties
/// UI Elements
private let photoImageView = UIImageView()
private let nameLabel = UILabel()
private let emailLabel = UILabel()
private let teamLabel = UILabel()
private let employeeTypeLabel = UILabel()
private let phoneLabel = UILabel()
private let bioLabel = UILabel()
private let stackView = UIStackView()
/// Used for grabbing the photo
private var smallPhotoSubscriber: AnyCancellable?
// MARK: - Initializer
public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
setupUI()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
// MARK: - Private Methods
private func setupUI() {
// Configure photoImageView
photoImageView.contentMode = .scaleAspectFill
photoImageView.clipsToBounds = true
photoImageView.layer.cornerRadius = 25
photoImageView.translatesAutoresizingMaskIntoConstraints = false
photoImageView.image = UIImage(systemName: "person.crop.circle")
// Configure labels with text styles
nameLabel.font = UIFont.preferredFont(forTextStyle: .headline) // Bold, prominent text
nameLabel.adjustsFontForContentSizeCategory = true // Adapts to Dynamic Type
emailLabel.font = UIFont.preferredFont(forTextStyle: .body)
emailLabel.textColor = .blue
emailLabel.adjustsFontForContentSizeCategory = true // Adapts to Dynamic Type
teamLabel.font = UIFont.preferredFont(forTextStyle: .subheadline) // Secondary, smaller text
teamLabel.textColor = .gray
teamLabel.adjustsFontForContentSizeCategory = true // Adapts to Dynamic Type
employeeTypeLabel.font = UIFont.preferredFont(forTextStyle: .subheadline)
employeeTypeLabel.adjustsFontForContentSizeCategory = true // Adapts to Dynamic Type
phoneLabel.font = UIFont.preferredFont(forTextStyle: .body) // Standard body text
phoneLabel.textColor = .darkGray
phoneLabel.adjustsFontForContentSizeCategory = true// Adapts to Dynamic Type
bioLabel.font = UIFont.preferredFont(forTextStyle: .footnote) // Smaller text for additional info
bioLabel.numberOfLines = 0
bioLabel.textColor = .lightGray
bioLabel.adjustsFontForContentSizeCategory = true // Adapts to Dynamic Type
// Configure stackView
stackView.axis = .vertical
stackView.spacing = 5
stackView.translatesAutoresizingMaskIntoConstraints = false
// Add labels to stackView
stackView.addArrangedSubview(nameLabel)
stackView.addArrangedSubview(teamLabel)
stackView.addArrangedSubview(employeeTypeLabel)
stackView.addArrangedSubview(phoneLabel)
stackView.addArrangedSubview(emailLabel)
stackView.addArrangedSubview(bioLabel)
// Add subviews
contentView.addSubview(photoImageView)
contentView.addSubview(stackView)
// Add constraints
NSLayoutConstraint.activate([
photoImageView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 10),
photoImageView.centerYAnchor.constraint(equalTo: contentView.centerYAnchor),
photoImageView.widthAnchor.constraint(equalToConstant: 50),
photoImageView.heightAnchor.constraint(equalToConstant: 50),
stackView.leadingAnchor.constraint(equalTo: photoImageView.trailingAnchor, constant: 10),
stackView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -10),
stackView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 10),
stackView.bottomAnchor.constraint(lessThanOrEqualTo: contentView.bottomAnchor, constant: -10)
])
}
// MARK: - Public Methods
/// Override for setting back to a default state
public override func prepareForReuse() {
super.prepareForReuse()
smallPhotoSubscriber = nil
photoImageView.image = UIImage(systemName: "person.crop.circle")
nameLabel.text = nil
emailLabel.text = nil
teamLabel.text = nil
employeeTypeLabel.text = nil
phoneLabel.text = nil
bioLabel.text = nil
}
/// Configures the UI Elements with the properties of the EmployeeCellViewModel.
/// - Parameter viewModel: Employee Model wrapped for Cell.
public func configure(with viewModel: EmployeeCellViewModel) {
// Bind the image to the photoImageView
smallPhotoSubscriber = viewModel.$smallPhoto
.compactMap { $0 }
.receive(on: DispatchQueue.main)
.sink { [weak self] image in
self?.photoImageView.image = image
}
// Bind data to UI components
nameLabel.text = viewModel.fullName
emailLabel.text = viewModel.emailAddress
teamLabel.text = viewModel.team
employeeTypeLabel.text = viewModel.employeeType
phoneLabel.text = viewModel.phoneNumber
bioLabel.text = viewModel.biography
// Dynamically show or hide elements based on their content
phoneLabel.isHidden = viewModel.phoneNumber == nil
bioLabel.isHidden = viewModel.biography == nil
}
}