这里没有足够的代码来重新创建您的问题,将来请提供一个最小、完整和可验证的示例。不幸的是,如果他们无法重现问题,没有人可以为您提供有效的解决方案来帮助您解决问题。
但是,我相信我了解您要完成的工作:
- 一个模型对象,即一个
struct
.
- 具有对所有单元相同的默认实现的协议。
TableViewCell
符合调用协议方法的协议的类。
- 用于管理 1 中的对象的 TableViewDelegate 和 Datasource。
考虑以下:
import UIKit
/// 1.
/// Data model for "Repeat Cell Objects"
struct RepeaterModel {
var outputText:String?
var inputAudio:Data?
}
/// 2.
/// Allows a cell to delegate listening and repeating (speaking)
protocol RepeatableCell {
func listen()
func speak()
}
// Extend your protocol to add a default implementation,
// that way you can just confrom to the protocol
// without implementing it every time, in every cell class.
extension RepeatableCell {
func listen() {
print("default implementation for listen")
}
func speak(){
print("default implementation for speak")
}
}
/// 3.
final class RepeatCell: UITableViewCell, RepeatableCell {
// MARK: - Properties
var model:RepeaterModel? {
didSet {
DispatchQueue.main.async {
self.titleLabel.text = self.model?.outputText
}
}
}
// MARK: - Views
lazy var listenButton: UIButton = {
let btn = UIButton(type: .system)
btn.setTitle("Listen", for: .normal)
btn.addTarget(self, action: #selector(activateListen), for: .touchUpInside)
btn.setTitleColor(.white, for: .normal)
btn.backgroundColor = .blue
btn.translatesAutoresizingMaskIntoConstraints = false
return btn
}()
lazy var speakButton: UIButton = {
let btn = UIButton(type: .system)
btn.setTitle("Speak", for: .normal)
btn.addTarget(self, action: #selector(activateSpeak), for: .touchUpInside)
btn.setTitleColor(.white, for: .normal)
btn.backgroundColor = .green
btn.translatesAutoresizingMaskIntoConstraints = false
return btn
}()
let titleLabel: UILabel = {
let l = UILabel()
l.translatesAutoresizingMaskIntoConstraints = false
l.textColor = .black
l.textAlignment = .center
l.text = "No Text"
return l
}()
//MARK: - Initializers
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
self.setup()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
//MARK: - Class Methods
func setup() {
self.contentView.addSubview(listenButton)
self.contentView.addSubview(speakButton)
self.contentView.addSubview(titleLabel)
let spacing: CGFloat = 25.0
//Listen top left
listenButton.topAnchor.constraint(equalTo: self.contentView.topAnchor, constant: spacing).isActive = true
listenButton.leadingAnchor.constraint(equalTo: self.contentView.leadingAnchor, constant: spacing).isActive = true
listenButton.widthAnchor.constraint(equalToConstant: 100).isActive = true
listenButton.heightAnchor.constraint(equalToConstant: 50).isActive = true
// title label, center top.
titleLabel.topAnchor.constraint(equalTo: self.contentView.topAnchor, constant: spacing).isActive = true
titleLabel.leadingAnchor.constraint(equalTo: self.listenButton.trailingAnchor, constant: spacing).isActive = true
titleLabel.trailingAnchor.constraint(equalTo: self.speakButton.leadingAnchor, constant: -spacing).isActive = true
titleLabel.heightAnchor.constraint(equalToConstant: 50).isActive = true
//Speak top right
speakButton.topAnchor.constraint(equalTo: self.contentView.topAnchor, constant: spacing).isActive = true
speakButton.trailingAnchor.constraint(equalTo: self.contentView.trailingAnchor, constant: -spacing).isActive = true
speakButton.widthAnchor.constraint(equalToConstant: 100).isActive = true
speakButton.heightAnchor.constraint(equalToConstant: 50).isActive = true
}
@objc func activateListen() {
print("listen was pressed! on cell \(self.model?.outputText ?? "No Text")")
/// The user wants to listen
// call the delegate method..
listen()
// use self.model?.outputText
}
@objc func activateSpeak() {
print("Speak was pressed! on cell \(self.model?.outputText ?? "No Text")")
/// The user is speaking, record audio
// call the delegate method..
speak()
//self.model?.inputAudio = somedata
}
}
/// 4.
class ViewController: UITableViewController {
// Array of your model objects
var objects:[RepeaterModel] = []
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.register(RepeatCell.self, forCellReuseIdentifier: "Repeat")
// create or fetch model objects
let items = [
RepeaterModel(outputText: "1st Cell", inputAudio: nil),
RepeaterModel(outputText: "2nd Cell", inputAudio: nil),
RepeaterModel(outputText: "3rd Cell", inputAudio: nil),
RepeaterModel(outputText: "4th Cell", inputAudio: nil),
RepeaterModel(outputText: "5th Cell", inputAudio: nil),
RepeaterModel(outputText: "6th Cell", inputAudio: nil),
RepeaterModel(outputText: "8th Cell", inputAudio: nil),
RepeaterModel(outputText: "9th Cell", inputAudio: nil),
RepeaterModel(outputText: "10th Cell", inputAudio: nil),
RepeaterModel(outputText: "11th Cell", inputAudio: nil),
RepeaterModel(outputText: "12th Cell", inputAudio: nil)
]
self.objects += items
}
//MARK: - TableView Methods
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
// 25 top spacing + 50 view element width + 25 bottom spacing
return 100.0
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return objects.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if let cell = self.tableView.dequeueReusableCell(withIdentifier: "Repeat") as? RepeatCell {
cell.model = objects[indexPath.row]
// other cell stuff
return cell
}
return UITableViewCell()
}
}
在每个向下的单元格上按“Listen”然后“Speak”会产生以下输出: