以编程方式创建具有单元格属性的自定义 table 视图
Creating custom table View with Cell properties programmatically
我是 swift 的新手。我正在尝试以编程方式创建 table 视图和单元格。我想将下面的三个标签属性显示到另一个。我添加了具有各自标签属性的内容视图。我已经设置了行高,但是当我 运行 应用重叠时。
这是我的 Table 带有视图控制器的视图代码。
class RoomViewController: UIViewController {
var coordinator: RoomBaseCoordinator?
init(coordinator: RoomBaseCoordinator) {
super.init(nibName: nil, bundle: nil)
self.coordinator = coordinator
title = "People"
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private let roomviewModel = RoomViewModel()
private var subscribers = Set<AnyCancellable>()
var activityIndicator = UIActivityIndicatorView(style: .medium)
private lazy var tableView: UITableView = {
let tableview = UITableView()
tableview.translatesAutoresizingMaskIntoConstraints = false
tableview.dataSource = self
tableview.prefetchDataSource = self
tableview.showsVerticalScrollIndicator = false
tableview.register(RoomCellTableViewCell.self, forCellReuseIdentifier: RoomCellTableViewCell.identifier)
return tableview
}()
override func viewDidLoad() {
super.viewDidLoad()
activityIndicator.startAnimating()
setUpUI()
setUpBinding()
self.activityIndicator.stopAnimating()
}
private func setUpUI() {
view.backgroundColor = .white
title = "Room List "
view.addSubview(tableView)
tableView.rowHeight = 100
// create constraints
tableView.topAnchor.constraint(equalTo:view.safeAreaLayoutGuide.topAnchor).isActive = true
tableView.leftAnchor.constraint(equalTo:view.safeAreaLayoutGuide.leftAnchor).isActive = true
tableView.rightAnchor.constraint(equalTo:view.safeAreaLayoutGuide.rightAnchor).isActive = true
tableView.bottomAnchor.constraint(equalTo:view.safeAreaLayoutGuide.bottomAnchor).isActive = true
tableView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor).isActive = true
// Creating constrain for Indecator
activityIndicator.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(activityIndicator)
activityIndicator.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
activityIndicator.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
}
private func setUpBinding() {
roomviewModel
.$rooms
.receive(on : RunLoop.main)
.sink { [weak self ] _ in
self?.tableView.reloadData()
}
.store(in: &subscribers)
roomviewModel.getRoom()
}
}
extension RoomViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return roomviewModel.rooms.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: RoomCellTableViewCell.identifier, for: indexPath) as? RoomCellTableViewCell
else { return UITableViewCell() }
let row = indexPath.row
let room = roomviewModel.rooms[row]
cell.configureCell(createdAt: room.createdAt, IsOccupied: room.isOccupied, maxOccupancy: String(room.maxOccupancy), id: room.id)
return cell
}
}
extension RoomViewController: UITableViewDataSourcePrefetching {
func tableView(_ tableView: UITableView, prefetchRowsAt indexPaths: [IndexPath]) {
roomviewModel.getRoom()
}
}
这是单元格。
class RoomCellTableViewCell: UITableViewCell {
static let identifier = "RoomCell"
private lazy var createdAtLabel: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.font = UIFont.boldSystemFont(ofSize: 15)
label.numberOfLines = 0
label.textAlignment = .left
return label
}()
private lazy var IsOccupiedLabel: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.font = UIFont.boldSystemFont(ofSize: 15)
label.numberOfLines = 0
//label.backgroundColor = #colorLiteral(red: 0.1764705926, green: 0.4980392158, blue: 0.7568627596, alpha: 1)
label.textAlignment = .left
return label
}()
private lazy var maxOccupancyLabel: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.font = UIFont.boldSystemFont(ofSize: 15)
label.numberOfLines = 0
label.textAlignment = .left
return label
}()
private lazy var idLabel: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.font = UIFont.boldSystemFont(ofSize: 15)
label.numberOfLines = 0
label.textAlignment = .left
return label
}()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
// self.contentView.addSubview(containerView)
contentView.addSubview(createdAtLabel)
contentView.addSubview(IsOccupiedLabel)
contentView.addSubview(maxOccupancyLabel)
createdAtLabel.centerYAnchor.constraint(equalTo:self.contentView.centerYAnchor).isActive = true
createdAtLabel.leadingAnchor.constraint(equalTo:self.contentView.leadingAnchor, constant:10).isActive = true
createdAtLabel.widthAnchor.constraint(equalToConstant:50).isActive = true
createdAtLabel.heightAnchor.constraint(equalToConstant:50).isActive = true
contentView.centerYAnchor.constraint(equalTo:self.contentView.centerYAnchor).isActive = true
contentView.leadingAnchor.constraint(equalTo:self.createdAtLabel.trailingAnchor, constant:10).isActive = true
contentView.trailingAnchor.constraint(equalTo:self.contentView.trailingAnchor, constant:-10).isActive = true
contentView.heightAnchor.constraint(equalToConstant:50).isActive = true
IsOccupiedLabel.topAnchor.constraint(equalTo:self.contentView.topAnchor).isActive = true
IsOccupiedLabel.leadingAnchor.constraint(equalTo:self.contentView.leadingAnchor).isActive = true
IsOccupiedLabel.trailingAnchor.constraint(equalTo:self.contentView.trailingAnchor).isActive = true
maxOccupancyLabel.topAnchor.constraint(equalTo:self.IsOccupiedLabel.bottomAnchor).isActive = true
maxOccupancyLabel.leadingAnchor.constraint(equalTo:self.contentView.leadingAnchor).isActive = true
maxOccupancyLabel.topAnchor.constraint(equalTo:self.IsOccupiedLabel.bottomAnchor).isActive = true
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func configureCell(createdAt: String, IsOccupied: Bool, maxOccupancy: String, id : String ) {
createdAtLabel.text = "CreatedAt :\(createdAt)"
IsOccupiedLabel.text = "IsOccupied : \(IsOccupied)"
maxOccupancyLabel.text = "MaxOccupancy : \(maxOccupancy)"
idLabel.text = "Id : \(id)"
}
}
这是结果。
在 RoomViewController class 的 setUpUI()
方法中,将 tableView 的 rowHeight
设置为 UITableView.automaticDimension 并将 estimatedRowHeight
设置为 100。
import UIKit
class RoomViewController: UIViewController {
private func setUpUI() {
view.backgroundColor = .white
title = "Room List "
view.addSubview(tableView)
tableView.estimatedRowHeight = 100
tableView.rowHeight = UITableView.automaticDimension
// create constraints
tableView.topAnchor.constraint(equalTo:view.safeAreaLayoutGuide.topAnchor).isActive = true
tableView.leftAnchor.constraint(equalTo:view.safeAreaLayoutGuide.leftAnchor).isActive = true
tableView.rightAnchor.constraint(equalTo:view.safeAreaLayoutGuide.rightAnchor).isActive = true
tableView.bottomAnchor.constraint(equalTo:view.safeAreaLayoutGuide.bottomAnchor).isActive = true
tableView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor).isActive = true
// Creating constrain for Indecator
activityIndicator.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(activityIndicator)
activityIndicator.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
activityIndicator.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
}
}
并在 RoomCellTableViewCell
class 中添加 UIStackView,如下所示:
import UIKit
class RoomCellTableViewCell: UITableViewCell {
private var stackView: UIStackView = {
let stackView = UIStackView()
stackView.axis = .vertical
stackView.distribution = .fill
stackView.alignment = .fill
stackView.spacing = 8
stackView.translatesAutoresizingMaskIntoConstraints = false
return stackView
}()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
addSubview(stackView)
NSLayoutConstraint.activate([
stackView.topAnchor.constraint(equalTo: topAnchor),
stackView.bottomAnchor.constraint(equalTo: bottomAnchor),
stackView.leftAnchor.constraint(equalTo: leftAnchor),
stackView.rightAnchor.constraint(equalTo: rightAnchor)
])
stackView.addArrangedSubview(createdAtLabel)
stackView.addArrangedSubview(isOccupiedLabel)
stackView.addArrangedSubview(maxOccupancyLabel)
// stackView.addArrangedSubview(idLabel)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
我是 swift 的新手。我正在尝试以编程方式创建 table 视图和单元格。我想将下面的三个标签属性显示到另一个。我添加了具有各自标签属性的内容视图。我已经设置了行高,但是当我 运行 应用重叠时。
这是我的 Table 带有视图控制器的视图代码。
class RoomViewController: UIViewController {
var coordinator: RoomBaseCoordinator?
init(coordinator: RoomBaseCoordinator) {
super.init(nibName: nil, bundle: nil)
self.coordinator = coordinator
title = "People"
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private let roomviewModel = RoomViewModel()
private var subscribers = Set<AnyCancellable>()
var activityIndicator = UIActivityIndicatorView(style: .medium)
private lazy var tableView: UITableView = {
let tableview = UITableView()
tableview.translatesAutoresizingMaskIntoConstraints = false
tableview.dataSource = self
tableview.prefetchDataSource = self
tableview.showsVerticalScrollIndicator = false
tableview.register(RoomCellTableViewCell.self, forCellReuseIdentifier: RoomCellTableViewCell.identifier)
return tableview
}()
override func viewDidLoad() {
super.viewDidLoad()
activityIndicator.startAnimating()
setUpUI()
setUpBinding()
self.activityIndicator.stopAnimating()
}
private func setUpUI() {
view.backgroundColor = .white
title = "Room List "
view.addSubview(tableView)
tableView.rowHeight = 100
// create constraints
tableView.topAnchor.constraint(equalTo:view.safeAreaLayoutGuide.topAnchor).isActive = true
tableView.leftAnchor.constraint(equalTo:view.safeAreaLayoutGuide.leftAnchor).isActive = true
tableView.rightAnchor.constraint(equalTo:view.safeAreaLayoutGuide.rightAnchor).isActive = true
tableView.bottomAnchor.constraint(equalTo:view.safeAreaLayoutGuide.bottomAnchor).isActive = true
tableView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor).isActive = true
// Creating constrain for Indecator
activityIndicator.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(activityIndicator)
activityIndicator.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
activityIndicator.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
}
private func setUpBinding() {
roomviewModel
.$rooms
.receive(on : RunLoop.main)
.sink { [weak self ] _ in
self?.tableView.reloadData()
}
.store(in: &subscribers)
roomviewModel.getRoom()
}
}
extension RoomViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return roomviewModel.rooms.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: RoomCellTableViewCell.identifier, for: indexPath) as? RoomCellTableViewCell
else { return UITableViewCell() }
let row = indexPath.row
let room = roomviewModel.rooms[row]
cell.configureCell(createdAt: room.createdAt, IsOccupied: room.isOccupied, maxOccupancy: String(room.maxOccupancy), id: room.id)
return cell
}
}
extension RoomViewController: UITableViewDataSourcePrefetching {
func tableView(_ tableView: UITableView, prefetchRowsAt indexPaths: [IndexPath]) {
roomviewModel.getRoom()
}
}
这是单元格。
class RoomCellTableViewCell: UITableViewCell {
static let identifier = "RoomCell"
private lazy var createdAtLabel: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.font = UIFont.boldSystemFont(ofSize: 15)
label.numberOfLines = 0
label.textAlignment = .left
return label
}()
private lazy var IsOccupiedLabel: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.font = UIFont.boldSystemFont(ofSize: 15)
label.numberOfLines = 0
//label.backgroundColor = #colorLiteral(red: 0.1764705926, green: 0.4980392158, blue: 0.7568627596, alpha: 1)
label.textAlignment = .left
return label
}()
private lazy var maxOccupancyLabel: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.font = UIFont.boldSystemFont(ofSize: 15)
label.numberOfLines = 0
label.textAlignment = .left
return label
}()
private lazy var idLabel: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.font = UIFont.boldSystemFont(ofSize: 15)
label.numberOfLines = 0
label.textAlignment = .left
return label
}()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
// self.contentView.addSubview(containerView)
contentView.addSubview(createdAtLabel)
contentView.addSubview(IsOccupiedLabel)
contentView.addSubview(maxOccupancyLabel)
createdAtLabel.centerYAnchor.constraint(equalTo:self.contentView.centerYAnchor).isActive = true
createdAtLabel.leadingAnchor.constraint(equalTo:self.contentView.leadingAnchor, constant:10).isActive = true
createdAtLabel.widthAnchor.constraint(equalToConstant:50).isActive = true
createdAtLabel.heightAnchor.constraint(equalToConstant:50).isActive = true
contentView.centerYAnchor.constraint(equalTo:self.contentView.centerYAnchor).isActive = true
contentView.leadingAnchor.constraint(equalTo:self.createdAtLabel.trailingAnchor, constant:10).isActive = true
contentView.trailingAnchor.constraint(equalTo:self.contentView.trailingAnchor, constant:-10).isActive = true
contentView.heightAnchor.constraint(equalToConstant:50).isActive = true
IsOccupiedLabel.topAnchor.constraint(equalTo:self.contentView.topAnchor).isActive = true
IsOccupiedLabel.leadingAnchor.constraint(equalTo:self.contentView.leadingAnchor).isActive = true
IsOccupiedLabel.trailingAnchor.constraint(equalTo:self.contentView.trailingAnchor).isActive = true
maxOccupancyLabel.topAnchor.constraint(equalTo:self.IsOccupiedLabel.bottomAnchor).isActive = true
maxOccupancyLabel.leadingAnchor.constraint(equalTo:self.contentView.leadingAnchor).isActive = true
maxOccupancyLabel.topAnchor.constraint(equalTo:self.IsOccupiedLabel.bottomAnchor).isActive = true
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func configureCell(createdAt: String, IsOccupied: Bool, maxOccupancy: String, id : String ) {
createdAtLabel.text = "CreatedAt :\(createdAt)"
IsOccupiedLabel.text = "IsOccupied : \(IsOccupied)"
maxOccupancyLabel.text = "MaxOccupancy : \(maxOccupancy)"
idLabel.text = "Id : \(id)"
}
}
这是结果。
在 RoomViewController class 的 setUpUI()
方法中,将 tableView 的 rowHeight
设置为 UITableView.automaticDimension 并将 estimatedRowHeight
设置为 100。
import UIKit
class RoomViewController: UIViewController {
private func setUpUI() {
view.backgroundColor = .white
title = "Room List "
view.addSubview(tableView)
tableView.estimatedRowHeight = 100
tableView.rowHeight = UITableView.automaticDimension
// create constraints
tableView.topAnchor.constraint(equalTo:view.safeAreaLayoutGuide.topAnchor).isActive = true
tableView.leftAnchor.constraint(equalTo:view.safeAreaLayoutGuide.leftAnchor).isActive = true
tableView.rightAnchor.constraint(equalTo:view.safeAreaLayoutGuide.rightAnchor).isActive = true
tableView.bottomAnchor.constraint(equalTo:view.safeAreaLayoutGuide.bottomAnchor).isActive = true
tableView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor).isActive = true
// Creating constrain for Indecator
activityIndicator.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(activityIndicator)
activityIndicator.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
activityIndicator.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
}
}
并在 RoomCellTableViewCell
class 中添加 UIStackView,如下所示:
import UIKit
class RoomCellTableViewCell: UITableViewCell {
private var stackView: UIStackView = {
let stackView = UIStackView()
stackView.axis = .vertical
stackView.distribution = .fill
stackView.alignment = .fill
stackView.spacing = 8
stackView.translatesAutoresizingMaskIntoConstraints = false
return stackView
}()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
addSubview(stackView)
NSLayoutConstraint.activate([
stackView.topAnchor.constraint(equalTo: topAnchor),
stackView.bottomAnchor.constraint(equalTo: bottomAnchor),
stackView.leftAnchor.constraint(equalTo: leftAnchor),
stackView.rightAnchor.constraint(equalTo: rightAnchor)
])
stackView.addArrangedSubview(createdAtLabel)
stackView.addArrangedSubview(isOccupiedLabel)
stackView.addArrangedSubview(maxOccupancyLabel)
// stackView.addArrangedSubview(idLabel)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}