Как автоматически прокручивать UITableView ячейку за ячейкой. Хорошо, я думаю этого легко добиться, и я так близко сделал
This is my SPEECH function in ViewController below
var myUtterance = AVSpeechUtterance(string: "")
let speecher = AVSpeechSynthesizer()
func speechWord(word: String){
DispatchQueue.main.async {
self.speecher.stopSpeaking(at: AVSpeechBoundary.immediate)
self.myUtterance = AVSpeechUtterance(string: word)
self.myUtterance.voice = AVSpeechSynthesisVoice(language: "en-US")
self.myUtterance.rate = 0.5
self.speecher.speak(self.myUtterance)
}
}
This is my AutoSpeech function in ViewController below
func startAutoSpeechList(row: Int){
let indexPath = IndexPath(row: row, section: 0)
print(indexPath)
myTableView.selectRow(at: indexPath, animated: true, scrollPosition: .top) //Select
myTableView.scrollToNearestSelectedRow(at: .top, animated: true) //Scroll
let cell = tableView(myTableView, cellForRowAt: indexPath) as! WordTableViewCell
self.speechWord(word: cell.spell.text!) //Speech
}
(Method 1) This is The Button I use to activate The AutoSpeech function
var row = 0
@IBAction func myAutoButton(_ sender: UIBarButtonItem) {
self.startAutoSpeechList(row: row)
row += 1
}
Метод 1. Посмотрите на загруженное мной изображение. Когда я нажимаю AutoButton в первый раз, он переходит на экран A. И я снова нажимаю кнопку AutoSpeech, на экран B. Затем я нажимаю AutoButton в третий раз, он переходит на экран C.
(Method 2) This is The Button I use to activate The AutoSpeech function
@IBAction func myAutoButton(_ sender: UIBarButtonItem) {
for myRow in 0..<3{
self.startAutoSpeechList(row: myRow)
}
}
Способ 2, Когда я нажимаю кнопку AutoSpeech, происходит переход к экрану C немедленно, не оставаясь на экране A, B какое-либо время. Вы можете объяснить, почему он сразу ускользает от осыпи A, B?
Is there Method 3 to help me achieve that When I click AutoSpeech Button, it will jump to Screen A and pronounce the word "cat", then jump to B after finishing the pronunciation and pronounce "dog", then jump to C, and so on.... Who can help me to achieve Method 3? Swift 4 will be better for me.
Проблема с методом 2 в том, что он сразу переходит к экрану C, не оставаясь на экране A, B, как я могу исправить
Я знаю, это то, что я сказал в своем комментарии? исправление также предлагается в комментарии выше
Есть ли способ наблюдать, закончил ли он воспроизведение речи?





Ваш код метода 2 - это то, что вам нужно, но он работает непрерывно и завершается за миллисекунды.
Лучшим доступным вариантом было бы использование методов AVSpeechSynthesizerDelegate для отслеживания разговора.
В вашем случае вы можете использовать
func speechSynthesizer(AVSpeechSynthesizer, didFinish: AVSpeechUtterance)
чтобы получать уведомление, когда воспроизводимая в данный момент речь заканчивается. Как только это будет вызвано, вы можете вызвать такую функцию, как speakNextRow или что-то еще, чтобы перейти к следующему в списке.
Грубо говоря, это то, чем вы должны заниматься. (не тестировалось в xcode, используйте как руководство о том, как делать то, что вам нужно).
class ViewController: UIViewController, AVSpeechSynthesizerDelegate {
var currentSelectedRow: Int?
var isAutoPlaying = false
var myUtterance = AVSpeechUtterance(string: "")
let speecher = AVSpeechSynthesizer()
override func viewDidLoad() {
super.viewDidLoad()
self.speecher.delegate = self
}
func speechWord(word: String){
DispatchQueue.main.async {
self.speecher.stopSpeaking(at: AVSpeechBoundary.immediate)
self.myUtterance = AVSpeechUtterance(string: word)
self.myUtterance.voice = AVSpeechSynthesisVoice(language: "en-US")
self.myUtterance.rate = 0.5
self.speecher.speak(self.myUtterance)
}
}
func startAutoPlay() {
isAutoPlaying = true
currentSelectedRow = 0
scrollToAndSpeak(at: currentSelectedRow)
}
func scrollToAndSpeak(at index: Int) {
// make sure to check not going out of bounds!!
let indexPath = IndexPath(row: index, section: 0)
myTableView.selectRow(at: indexPath, animated: true, scrollPosition: .top) //Select
myTableView.scrollToNearestSelectedRow(at: .top, animated: true) //Scroll
let cell = tableView(myTableView, cellForRowAt: indexPath) as! WordTableViewCell
self.speechWord(word: cell.spell.text!) //Speech
}
func speechSynthesizer(AVSpeechSynthesizer, didFinish: AVSpeechUtterance) {
if isAutoPlaying {
// make sure to check not going out of bounds!!
currentSelectedRow = (currentSelectedRow ?? 0) + 1
scrollToAndSpeak(at: currentSelectedRow)
}
}
}
Поэтому, когда вы выбираете автоматическое воспроизведение, установите для флага isAutoPlaying значение true и начните воспроизведение с первого. Как только это закончится, делегат будет уведомлен, и мы увеличим индекс и начнем воспроизведение следующего и так далее, пока либо пользователь не отменит его, либо у нас не закончатся ячейки.
Я проверил ваш ответ, и у меня он работает. Спасибо за вашу помощь. Я думаю, что функция SpeechSynthesizer необходима для наблюдения, закончила ли она речь.
Метод 2 выглядит так, как будто он делает именно то, что вы хотите, просто он делает это за миллисекунды. Вам либо нужен таймер для контроля времени между рядами, либо вам нужно знать, когда каждый из них заканчивает воспроизведение речи, чтобы затем вы могли перейти к следующему