点击单元格按钮时如何更新单元格滑块的值?
How to update a cell slider's value when the cell's button tapped?
我有一个集合视图单元格,它有两个视图。一个是按钮,另一个是水平滑块。我想做的是,我想在点击单元格的按钮时播放曲目,一旦曲目开始播放,滑块的值就应该增加。
点击播放按钮后,我需要访问 UI 滑块并更新它的值。这是我尝试过的;
点击按钮:
@IBAction func playPreviewButtonTapped(sender: UIButton) {
playPreviewSound(fileName: fileName)
setPausePreviewSoundButtonImage(button: sender)
}
播放声音功能:
private func playPreviewSound(fileName: String) {
let url = Bundle.main.url(forResource: fileName, withExtension: "mp3")
do {
try AVAudioSession.sharedInstance().setActive(true)
player = try AVAudioPlayer(contentsOf: url!, fileTypeHint: AVFileType.mp3.rawValue)
guard let player = player else { return }
player.play()
setIsPreviewPlaying(state: true)
let selectedIndexPath = cellIndexPathDict[fileName]!.indexPath
let asset = AVAsset(url: url!)
let audioDuration = asset.duration
let audioDurationSeconds = Float(CMTimeGetSeconds(audioDuration))
getCellByIndexPath(indexPath: selectedIndexPath).previewSoundSlider.maximumValue = audioDurationSeconds
timer = Timer.scheduledTimer(timeInterval: 0.5, target: self, selector: #selector(updateSliderWithTimer), userInfo: ["slider": getCellByIndexPath(indexPath: selectedIndexPath).previewSoundSlider], repeats: true)
} catch let error {
print(error.localizedDescription)
}
}
private func getCellByIndexPath (indexPath: IndexPath) -> BackStageCollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: BackStageCollectionViewCell.REUSE, for: indexPath) as! BackStageCollectionViewCell
setCellInstances(cell: cell, indexPath: indexPath)
print("cell title; ", cell.processorNameLabel.text!) // here, the title always the default title.
return cell
}
定时器功能:
@objc private func updateSliderWithTimer(slider: UISlider) {
let userInfo = timer.userInfo as! Dictionary<String, AnyObject>
let slider: UISlider = (userInfo["slider"] as! UISlider)
print(slider.maximumValue) // here, the max value is always 1
slider.value += 0.5
}
如何访问单元格?我创建了一本字典;
private var cellIndexPathDict: [String: CellIndexModel] = [:]
struct CellIndexModel {
var indexPath : IndexPath
}
在创建单元格时推送到 dic:
UICollectionViewDelegate 扩展:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: BackStageCollectionViewCell.REUSE, for: indexPath) as! BackStageCollectionViewCell
setCellInstances(cell: cell, indexPath: indexPath)
let gearsGroup = listGearsGroups.object(at: indexPath.section) as! GearsGroup
let gear = gearsGroup.listGears.object(at: indexPath.row) as! BaseGear
let mod : CellIndexModel = CellIndexModel(indexPath: indexPath)
cellIndexPathDict[gear.previewSoundFile as String] = mod
cell.playPreviewButton.addTarget(self, action:#selector(playPreviewButtonTapped(sender:)), for: .touchUpInside)
cell.playPreviewButton.accessibilityLabel = gear.previewSoundFile as String?
return cell
}
基本上我正在创建一个字典来存储单元格索引路径并尝试在 tap 函数中访问它,但我只获得默认值。不是选中的。
点击按钮时如何访问和更新单元格?
我刚开始学习Swift,所以解释一下会很棒!谢谢
因为cell复用机制,当你使用
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: BackStageCollectionViewCell.REUSE, for: indexPath) as! BackStageCollectionViewCell
在大多数情况下,你不会得到你看到的那个indexPath的单元格。
它的状态属于对象池中的一个单元格。
也许你得到了新创建的单元格,它的状态是默认的。
典型解法:
当您的播放声音按钮被点击时,您可以相应地获取它的 indexPath。
然后你可以访问audioPlayer.currentTime
,
的值
重新加载相关单元格。
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
// configure the slide value here
}
调用它重新加载
collectionView.reloadItems(at: [indexPath])
通常我们要更新单元格的值,我们不会直接处理单元格,
我们记录单元格的值属性,然后配置通过重新加载更新的单元格。
我给模式命名mark & config
其他提示一:
很多时候,我们不使用
@objc private func updateSliderWithTimer(slider: UISlider) {
let userInfo = timer.userInfo as! Dictionary<String, AnyObject>
let slider: UISlider = (userInfo["slider"] as! UISlider)
print(slider.maximumValue) // here, the max value is always 1
slider.value += 0.5
}
我们使用
@objc private func updateSliderWithTimer(slider: UISlider) {
let slider: UISlider = (userInfo["slider"] as! UISlider)
slider.value = Float(audioPlayer.currentTime)
}
我们可以访问当前播放器的音频播放时间,
最好使用准确的时间,而不是大概的时间。
其他提示2:
通常我们不使用
private func getCellByIndexPath (indexPath: IndexPath) -> BackStageCollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: BackStageCollectionViewCell.REUSE, for: indexPath) as! BackStageCollectionViewCell
//...
return cell
}
我们使用
private func getCellByIndexPath (indexPath: IndexPath) -> BackStageCollectionViewCell? {
if collectionView.indexPathsForVisibleItems.contains(indexPath){
// ...
return collectionView.cellForItem(at: indexPath) as? BackStageCollectionViewCell
}else{
return nil
}
}
因为collectionView的cell复用,如果看不到cell,则cell不存在。
对于用户界面,如果看不到该单元格,则该单元格对用户没有用。
我有一个集合视图单元格,它有两个视图。一个是按钮,另一个是水平滑块。我想做的是,我想在点击单元格的按钮时播放曲目,一旦曲目开始播放,滑块的值就应该增加。
点击播放按钮后,我需要访问 UI 滑块并更新它的值。这是我尝试过的;
点击按钮:
@IBAction func playPreviewButtonTapped(sender: UIButton) {
playPreviewSound(fileName: fileName)
setPausePreviewSoundButtonImage(button: sender)
}
播放声音功能:
private func playPreviewSound(fileName: String) {
let url = Bundle.main.url(forResource: fileName, withExtension: "mp3")
do {
try AVAudioSession.sharedInstance().setActive(true)
player = try AVAudioPlayer(contentsOf: url!, fileTypeHint: AVFileType.mp3.rawValue)
guard let player = player else { return }
player.play()
setIsPreviewPlaying(state: true)
let selectedIndexPath = cellIndexPathDict[fileName]!.indexPath
let asset = AVAsset(url: url!)
let audioDuration = asset.duration
let audioDurationSeconds = Float(CMTimeGetSeconds(audioDuration))
getCellByIndexPath(indexPath: selectedIndexPath).previewSoundSlider.maximumValue = audioDurationSeconds
timer = Timer.scheduledTimer(timeInterval: 0.5, target: self, selector: #selector(updateSliderWithTimer), userInfo: ["slider": getCellByIndexPath(indexPath: selectedIndexPath).previewSoundSlider], repeats: true)
} catch let error {
print(error.localizedDescription)
}
}
private func getCellByIndexPath (indexPath: IndexPath) -> BackStageCollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: BackStageCollectionViewCell.REUSE, for: indexPath) as! BackStageCollectionViewCell
setCellInstances(cell: cell, indexPath: indexPath)
print("cell title; ", cell.processorNameLabel.text!) // here, the title always the default title.
return cell
}
定时器功能:
@objc private func updateSliderWithTimer(slider: UISlider) {
let userInfo = timer.userInfo as! Dictionary<String, AnyObject>
let slider: UISlider = (userInfo["slider"] as! UISlider)
print(slider.maximumValue) // here, the max value is always 1
slider.value += 0.5
}
如何访问单元格?我创建了一本字典;
private var cellIndexPathDict: [String: CellIndexModel] = [:]
struct CellIndexModel {
var indexPath : IndexPath
}
在创建单元格时推送到 dic:
UICollectionViewDelegate 扩展:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: BackStageCollectionViewCell.REUSE, for: indexPath) as! BackStageCollectionViewCell
setCellInstances(cell: cell, indexPath: indexPath)
let gearsGroup = listGearsGroups.object(at: indexPath.section) as! GearsGroup
let gear = gearsGroup.listGears.object(at: indexPath.row) as! BaseGear
let mod : CellIndexModel = CellIndexModel(indexPath: indexPath)
cellIndexPathDict[gear.previewSoundFile as String] = mod
cell.playPreviewButton.addTarget(self, action:#selector(playPreviewButtonTapped(sender:)), for: .touchUpInside)
cell.playPreviewButton.accessibilityLabel = gear.previewSoundFile as String?
return cell
}
基本上我正在创建一个字典来存储单元格索引路径并尝试在 tap 函数中访问它,但我只获得默认值。不是选中的。
点击按钮时如何访问和更新单元格? 我刚开始学习Swift,所以解释一下会很棒!谢谢
因为cell复用机制,当你使用
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: BackStageCollectionViewCell.REUSE, for: indexPath) as! BackStageCollectionViewCell
在大多数情况下,你不会得到你看到的那个indexPath的单元格。
它的状态属于对象池中的一个单元格。
也许你得到了新创建的单元格,它的状态是默认的。
典型解法:
当您的播放声音按钮被点击时,您可以相应地获取它的 indexPath。
然后你可以访问audioPlayer.currentTime
,
重新加载相关单元格。
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
// configure the slide value here
}
调用它重新加载
collectionView.reloadItems(at: [indexPath])
通常我们要更新单元格的值,我们不会直接处理单元格,
我们记录单元格的值属性,然后配置通过重新加载更新的单元格。
我给模式命名mark & config
其他提示一:
很多时候,我们不使用
@objc private func updateSliderWithTimer(slider: UISlider) {
let userInfo = timer.userInfo as! Dictionary<String, AnyObject>
let slider: UISlider = (userInfo["slider"] as! UISlider)
print(slider.maximumValue) // here, the max value is always 1
slider.value += 0.5
}
我们使用
@objc private func updateSliderWithTimer(slider: UISlider) {
let slider: UISlider = (userInfo["slider"] as! UISlider)
slider.value = Float(audioPlayer.currentTime)
}
我们可以访问当前播放器的音频播放时间,
最好使用准确的时间,而不是大概的时间。
其他提示2:
通常我们不使用
private func getCellByIndexPath (indexPath: IndexPath) -> BackStageCollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: BackStageCollectionViewCell.REUSE, for: indexPath) as! BackStageCollectionViewCell
//...
return cell
}
我们使用
private func getCellByIndexPath (indexPath: IndexPath) -> BackStageCollectionViewCell? {
if collectionView.indexPathsForVisibleItems.contains(indexPath){
// ...
return collectionView.cellForItem(at: indexPath) as? BackStageCollectionViewCell
}else{
return nil
}
}
因为collectionView的cell复用,如果看不到cell,则cell不存在。
对于用户界面,如果看不到该单元格,则该单元格对用户没有用。