在 Tableview 上滚动时按钮图像发生变化
Button image changes while scrolling on Tableview
我需要认真的帮助,因为我正在 Tableview 上播放音频并使用 AVPlayer 管理 (Play/pause/stop) 它。所有功能都运行良好。
但问题是如何在滚动时只管理 TableView 中的按钮图像?
主要有两点需要考虑
- 第一步是在播放音频的相应单元格上设置按钮图像("media-pause")。
2是设置rest所有绝对没有播放的Buttons image("play-button")
class AudiosController: UIViewController {
//outlets
@IBOutlet weak var tableView: UITableView!
//properties
let menuArray: [String] = [
"Song 1",
"Song 2”,
"Song 3”,
"Song 4”,
“Song 5”,
“Song 6”,
"Song 7”,
"Song 8”,
"Song 9”,
“Song 10”,
“Song 11”,
“Song 12”]
let audioUrl: [String] = ["https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3",
"http://transom.org/wp-content/uploads/2004/03/200206.hodgman8.mp3",
"https://www.hrupin.com/wp-content/uploads/mp3/testsong_20_sec.mp3",
"https://ia801409.us.archive.org/12/items/1HourThunderstorm/1HrThunderstorm.mp3",
"https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3",
"http://transom.org/wp-content/uploads/2004/03/200206.hodgman8.mp3",
"https://www.hrupin.com/wp-content/uploads/mp3/testsong_20_sec.mp3",
"https://ia801409.us.archive.org/12/items/1HourThunderstorm/1HrThunderstorm.mp3",
"https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3",
"http://transom.org/wp-content/uploads/2004/03/200206.hodgman8.mp3",
"https://www.hrupin.com/wp-content/uploads/mp3/testsong_20_sec.mp3",
"https://ia801409.us.archive.org/12/items/1HourThunderstorm/1HrThunderstorm.mp3"]
var previous = UIButton().tag
var player : AVPlayer?
var previousCell:PlayerCell?
var currentCell:PlayerCell?
//MARK: - View Life Cycle
override func viewDidLoad() {
super.viewDidLoad()
//TableView Config
tableView.dataSource = self
tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 44
}
//MARK: - Actions
@IBAction func play_pauseButtonPressed(_ sender: UIButton) {
let cell = sender.superview?.superview?.superview as! PlayerCell
currentCell = cell // current cell
let currentIndex = sender.tag // current Button tag value
let current = sender // current Button
if player?.isPlaying == true && previous == currentIndex {
player?.pause()
sender.setImage(UIImage(named: "play-button"), for: .normal)
previous = currentIndex
} else if player?.isPlaying == true {
player?.pause()
previousCell?.play_pauseButton.setImage( imageLiteral(resourceName: "play-button"), for: .normal)
current.setImage(UIImage(named: "media-pause"), for: .normal)
play(audioUrl: audioUrl[currentIndex])
previous = currentIndex
} else {
current.setImage(UIImage(named: "media-pause"), for: .normal)
play(audioUrl: audioUrl[currentIndex])
current.isSelected = true
previous = currentIndex
}
previousCell = cell
}
func play(audioUrl: String) {
guard let url = URL.init(string: audioUrl) else { return }
let playerItem = AVPlayerItem.init(url: url)
player = AVPlayer.init(playerItem: playerItem)
player?.play()
}
}
//MARK: - AVPlayer
extension AVPlayer {
var isPlaying: Bool {
return ((rate != 0) && (error == nil))
}
}
//MARK: - UITableViewDataSource
extension AudiosController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return menuArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "PlayerCell", for: indexPath) as! PlayerCell
cell.txtLabel.text = menuArray[indexPath.item]
cell.play_pauseButton.tag = indexPath.row
return cell
}
}
这是 PlayerCell class
class PlayerCell: UITableViewCell {
@IBOutlet weak var play_pauseButton: UIButton!
@IBOutlet weak var txtLabel: UILabel!
}
可以做的是在配置单元格时重置所有图像。因为 tableView
正在重复使用单元格,所以某些属性在上次更改时会保留下来。如果这是问题所在,代码可以修复为:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "PlayerCell", for: indexPath) as! PlayerCell
cell.txtLabel.text = menuArray[indexPath.item]
cell.play_pauseButton.tag = indexPath.row
if player?.isPlaying == true && indexPath.row == previous { //Sets the "media-pause" image to the currently played cell
cell.play_pauseButton.setImage(UIImage(named: "media-pause"), for: .normal)
} else { //Every other cell that is not the playing one is reseted to the "play-button" image
cell.play_pauseButton.setImage(UIImage(named: "play-button"), for: .normal)
}
return cell
}
我需要认真的帮助,因为我正在 Tableview 上播放音频并使用 AVPlayer 管理 (Play/pause/stop) 它。所有功能都运行良好。
但问题是如何在滚动时只管理 TableView 中的按钮图像? 主要有两点需要考虑
- 第一步是在播放音频的相应单元格上设置按钮图像("media-pause")。
2是设置rest所有绝对没有播放的Buttons image("play-button")
class AudiosController: UIViewController { //outlets @IBOutlet weak var tableView: UITableView! //properties let menuArray: [String] = [ "Song 1", "Song 2”, "Song 3”, "Song 4”, “Song 5”, “Song 6”, "Song 7”, "Song 8”, "Song 9”, “Song 10”, “Song 11”, “Song 12”] let audioUrl: [String] = ["https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3", "http://transom.org/wp-content/uploads/2004/03/200206.hodgman8.mp3", "https://www.hrupin.com/wp-content/uploads/mp3/testsong_20_sec.mp3", "https://ia801409.us.archive.org/12/items/1HourThunderstorm/1HrThunderstorm.mp3", "https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3", "http://transom.org/wp-content/uploads/2004/03/200206.hodgman8.mp3", "https://www.hrupin.com/wp-content/uploads/mp3/testsong_20_sec.mp3", "https://ia801409.us.archive.org/12/items/1HourThunderstorm/1HrThunderstorm.mp3", "https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3", "http://transom.org/wp-content/uploads/2004/03/200206.hodgman8.mp3", "https://www.hrupin.com/wp-content/uploads/mp3/testsong_20_sec.mp3", "https://ia801409.us.archive.org/12/items/1HourThunderstorm/1HrThunderstorm.mp3"] var previous = UIButton().tag var player : AVPlayer? var previousCell:PlayerCell? var currentCell:PlayerCell? //MARK: - View Life Cycle override func viewDidLoad() { super.viewDidLoad() //TableView Config tableView.dataSource = self tableView.rowHeight = UITableViewAutomaticDimension tableView.estimatedRowHeight = 44 } //MARK: - Actions @IBAction func play_pauseButtonPressed(_ sender: UIButton) { let cell = sender.superview?.superview?.superview as! PlayerCell currentCell = cell // current cell let currentIndex = sender.tag // current Button tag value let current = sender // current Button if player?.isPlaying == true && previous == currentIndex { player?.pause() sender.setImage(UIImage(named: "play-button"), for: .normal) previous = currentIndex } else if player?.isPlaying == true { player?.pause() previousCell?.play_pauseButton.setImage( imageLiteral(resourceName: "play-button"), for: .normal) current.setImage(UIImage(named: "media-pause"), for: .normal) play(audioUrl: audioUrl[currentIndex]) previous = currentIndex } else { current.setImage(UIImage(named: "media-pause"), for: .normal) play(audioUrl: audioUrl[currentIndex]) current.isSelected = true previous = currentIndex } previousCell = cell } func play(audioUrl: String) { guard let url = URL.init(string: audioUrl) else { return } let playerItem = AVPlayerItem.init(url: url) player = AVPlayer.init(playerItem: playerItem) player?.play() } } //MARK: - AVPlayer extension AVPlayer { var isPlaying: Bool { return ((rate != 0) && (error == nil)) } } //MARK: - UITableViewDataSource extension AudiosController: UITableViewDataSource { func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return menuArray.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "PlayerCell", for: indexPath) as! PlayerCell cell.txtLabel.text = menuArray[indexPath.item] cell.play_pauseButton.tag = indexPath.row return cell } }
这是 PlayerCell class
class PlayerCell: UITableViewCell {
@IBOutlet weak var play_pauseButton: UIButton!
@IBOutlet weak var txtLabel: UILabel!
}
可以做的是在配置单元格时重置所有图像。因为 tableView
正在重复使用单元格,所以某些属性在上次更改时会保留下来。如果这是问题所在,代码可以修复为:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "PlayerCell", for: indexPath) as! PlayerCell
cell.txtLabel.text = menuArray[indexPath.item]
cell.play_pauseButton.tag = indexPath.row
if player?.isPlaying == true && indexPath.row == previous { //Sets the "media-pause" image to the currently played cell
cell.play_pauseButton.setImage(UIImage(named: "media-pause"), for: .normal)
} else { //Every other cell that is not the playing one is reseted to the "play-button" image
cell.play_pauseButton.setImage(UIImage(named: "play-button"), for: .normal)
}
return cell
}