点击单元格按钮时如何更新单元格滑块的值?
Posted
技术标签:
【中文标题】点击单元格按钮时如何更新单元格滑块的值?【英文标题】:How to update a cell slider's value when the cell's button tapped? 【发布时间】:2020-10-28 08:03:53 【问题描述】:我有一个集合视图单元格,它有两个视图。一个是按钮,另一个是水平滑块。我想要做的是我想在点击单元格按钮时播放曲目,一旦曲目开始播放,滑块的值应该增加。
当点击播放按钮时,我需要访问 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,所以一个解释会很棒!谢谢
【问题讨论】:
【参考方案1】:由于单元格复用机制,当你使用时
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])
通常我们要更新单元格的值,我们不直接处理单元格,
我们记录cell的属性值,然后配置通过reloading更新的cell。
我将模式命名为 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不存在。
对于用户界面,如果单元格不可见,则该单元格对用户没有用处。
【讨论】:
return collectionView.cellForItem(at: indexPath) as? BackStageCollectionViewCell
成功了。谢谢!以上是关于点击单元格按钮时如何更新单元格滑块的值?的主要内容,如果未能解决你的问题,请参考以下文章