首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Swift 4:按钮在另一个UITableViewCell中触发相同的操作

Swift 4:按钮在另一个UITableViewCell中触发相同的操作
EN

Stack Overflow用户
提问于 2018-10-21 02:55:14
回答 1查看 181关注 0票数 0

我有一个单元格,它有两个按钮(用于收听和语音识别)、标签和文本字段。我试图实现的是,当选择语音识别按钮时,用户说出标签中显示的内容。我的问题是,根据indexPath.row,监听按钮工作得很好,但说话按钮就不行了,因为当它处于活动状态时,另一个单元格中的按钮也会变为活动状态。它在这些细胞中也记录了同样的情况。

You can see the picture of what I am talking about here

收听(音频合成器)和语音识别的方法在UITableViewCell中。我已经尝试了所有我能在网上找到的解决方案,但都没有奏效。已经尝试过了

代码语言:javascript
复制
protocol RepeatCellDelegate: class {
    func buttonTapped(cell: RepeatCell)
}

但问题依然存在。此外,我创建了另一个项目,而不是使用按钮进行语音识别,我刚才使用的是直接textField输入,但仍然出现了相同的问题。

TableViewCell类中的按钮:

代码语言:javascript
复制
@IBAction func speakButtonPressed(_ sender: Any) {
self.delegate?.buttonTapped(cell: self)

}

我的cellForRowAt indexPath

代码语言:javascript
复制
let cell = tableView.dequeueReusableCell(withIdentifier: "RepeatCell") as! RepeatCell

cell.delegate = self

cell.conditionlabel.text = repeatTask[indexPath.row].conditionLabel

return cell

检测单元格索引并记录语音输入的buttonTapped函数。点击按钮后,它会打印正确的单元格索引,但该操作也会在另一个单元格中触发。

代码语言:javascript
复制
func buttonTapped(cell: RepeatCell) {
guard let indexPath = self.repeatTV.indexPath(for: cell) else {
    return
}

cell.speakButton.isSelected = !cell.speakButton.isSelected

if (cell.speakButton.isSelected){
    self.recordAndRecognizeSpeech()
} else {
    audioEngine.inputNode.removeTap(onBus: 0)
    recognitionTask?.cancel()
}

print("Button tapped on row \(indexPath.row)")

}

//语音输入识别器函数:

代码语言:javascript
复制
// variables for speech recognizer

让audioEngine = AVAudioEngine()让speechRecognizer: SFSpeechRecognizer?=SFSpeechRecognizer(区域设置:Locale.init(标识符:"en-US"))让audioEngine= SFSpeechAudioBufferRecognitionRequest() var recognitionTask: SFSpeechRecognitionTask?

//语音函数func recordAndRecognizeSpeech(){

代码语言:javascript
复制
let node = audioEngine.inputNode
let recordingFormat = node.outputFormat(forBus: 0)
node.installTap(onBus: 0, bufferSize: 1024, format: recordingFormat) { buffer, _ in
    self.request.append(buffer)
}
audioEngine.prepare()

do {
    try audioEngine.start()
} catch {
    return print(error)
}

guard let myRecognizer = SFSpeechRecognizer() else {
    return
}
if !myRecognizer.isAvailable {
    return
}

recognitionTask = speechRecognizer?.recognitionTask(with: request, resultHandler: { (result, error) in
    if result != nil { //
        if let result = result{
            let cell = self.repeatTV.dequeueReusableCell(withIdentifier: "RepeatCell") as! RepeatCell
            let bestString = result.bestTranscription.formattedString
            if cell.speakButton.isSelected == true {
                cell.userInput.text = bestString
            }

        }else if let error = error{
            print(error)
        }
    }
})

}

我从本地JSON文件中获取数据,这是一个模型:

代码语言:javascript
复制
struct RepeatTask: Codable {
let name: String
let label: String
let conditionWord: String

}

也许有人能帮我这个忙?

EN

回答 1

Stack Overflow用户

发布于 2018-10-21 11:15:17

此处没有足够的代码来重新创建您的问题,请在将来提供一个Minimal, Complete, and Verifiable example。不幸的是,如果他们不能重新创建问题,没有人可以为您提供有效的解决方案来帮助您解决问题。

然而,我相信我理解你想要实现的目标:

  1. 模型对象,即具有对所有单元都相同的默认实现的struct.
  2. A协议。
  3. 符合调用协议的方法的协议的TableViewCell类。
  4. 管理来自1的对象的TableViewDelegate和数据源。

请考虑以下几点:

代码语言:javascript
复制
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”,将产生以下输出:

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52909068

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档