我的tableview显示播客数据。所有单元格都可以正常使用,并以正确的顺序显示播客。我添加下载和播放按钮作为每个单元格的子视图。当我向下滚动列表时,将显示意图为未下载的剧集隐藏的播放按钮,并将保存先前发起下载的单元格的数据。例如,如果我点击单元格1中的下载按钮,它将下载正确的剧集,播放按钮将完美地播放该剧集。如果我向下滚动到单元格10,将出现相同的播放按钮,并将从按钮1播放剧集。我的代码出了什么问题?
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath, object: PFObject?) -> PFTableViewCell? {
let cell: PFTableViewCell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! PFTableViewCell
if let title = object?["title"] as? String {
cell.textLabel?.text = title
let downloadButton = UIButton(type: UIButtonType.Custom)
downloadButton.frame = CGRectMake(cell.contentView.bounds.width - 100, cell.contentView.bounds.height / 2, 100, 35)
downloadButton.setTitle("Download", forState: .Normal)
downloadButton.setTitleColor(UIColor.blueColor(), forState: .Normal)
downloadButton.tag = indexPath.row
downloadButton.addTarget(self, action: "downloadEpisode:", forControlEvents: .TouchUpInside)
cell.addSubview(downloadButton)
let playButton = UIButton(type: UIButtonType.Custom)
playButton.frame = CGRectMake(cell.contentView.bounds.width - 100, cell.contentView.bounds.height - 89, 100, 35)
playButton.setTitle("Play", forState: .Normal)
playButton.setTitleColor(UIColor.blueColor(), forState: .Normal)
playButton.tag = indexPath.row
playButton.addTarget(self, action: "playEpisode:", forControlEvents: .TouchUpInside)
if let isDownloaded = object?["isDownloaded"] as? String {
if isDownloaded == "yes" {
playButton.hidden = false
} else {
playButton.hidden = true
}
}
cell.addSubview(playButton)
}
return cell
}
编辑:
我也试过了,但它不起作用,仍然每个单元格再创建一个按钮:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath, object: PFObject?) -> PFTableViewCell? {
let cell: PFTableViewCell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! PFTableViewCell
if let title = object?["title"] as? String {
cell.textLabel?.text = title
}
if let button = cell.viewWithTag(indexPath.row) {
print(button)
} else {
if let isDownloaded = object?["isDownloaded"] as? String {
if isDownloaded == "yes" {
let downloadButton = UIButton(type: UIButtonType.Custom)
downloadButton.frame = CGRectMake(cell.contentView.bounds.width - 100, cell.contentView.bounds.height / 2, 100, 35)
downloadButton.setTitle("Play", forState: .Normal)
downloadButton.setTitleColor(UIColor.blueColor(), forState: .Normal)
downloadButton.tag = indexPath.row
downloadButton.addTarget(self, action: "playEpisode:", forControlEvents: .TouchUpInside)
cell.addSubview(downloadButton)
} else {
let downloadButton = UIButton(type: UIButtonType.Custom)
downloadButton.frame = CGRectMake(cell.contentView.bounds.width - 100, cell.contentView.bounds.height / 2, 100, 35)
downloadButton.setTitle("Download", forState: .Normal)
downloadButton.setTitleColor(UIColor.blueColor(), forState: .Normal)
downloadButton.tag = indexPath.row
downloadButton.addTarget(self, action: "downloadEpisode:", forControlEvents: .TouchUpInside)
cell.addSubview(downloadButton)
}
}
}
return cell
}
EDIT2:
添加了下载方法:
func downloadEpisode(sender: UIButton) {
print("Downloading..")
let indexPath = NSIndexPath(forRow: sender.tag, inSection: 0)
let object = self.objectAtIndexPath(indexPath)
if let result = object {
let urlstring = result["downloadURL"] as? String
if urlstring != nil {
let episodeURL = NSURL(string: urlstring!)
downloader.downloadPodcastEpisode(episodeURL!, podcast: result)
}
}
}
答案:
虽然所有答案都是正确的,但我决定最后删除按钮下载/播放单元格。非常感谢!
答案 0 :(得分:1)
问题是您每次都要添加新按钮。当您的单元格被重用时,它将有一个按钮。您需要编写代码以确保只创建一次按钮,然后修改现有按钮而不是创建新按钮。
有两种常见方法:
viewWithTag
检查按钮是否存在(创建按钮并设置其标签,如果没有)UITableViewCell
,在初始化程序中创建按钮,并在每次使用单元格时配置按钮。搜索“uitableviewcell viewwithtag”或“subclass uitableviewcell”应该会提供大量的示例代码,所以我不会在这里重复。
答案 1 :(得分:0)
这是因为在代码中单元格中放置按钮是单向的:一旦按钮被添加到单元格中,它就永远不会被删除或变得不可见。
如果该按钮存在,您需要在else
语句中添加if
以从已回收的单元格中删除该按钮。
更好的是,将按钮设为"Cell"
的永久部分,并在同一if
语句中控制其可见性:不添加按钮,使其可见;而不是删除按钮,使其不可见。作为一个额外的好处,这将允许您在界面构建器中设置按钮的视觉外观,并设置一些约束,这将有助于避免"魔术数字"例如代码正文中的100,89和35。
答案 2 :(得分:0)
查看您的代码清楚地知道您已经是UITableViewCell
的子类并拥有自定义用户界面,然后在初始化或UITableViewCell
xib
的{{1}}旁边建议添加按钮1}}然后在cell
中添加UIButton
(通过界面构建器)并为新添加的按钮创建xib
。
现在当重新使用IBOutlet
时,您也将拥有该按钮,当重复使用单元格时,您有责任保持其状态正确(意味着更新其UI),对于覆盖cell
自定义prepareForReuse
类中的方法和单元格的重置UI,在tableViewCell
中,您可以根据新数据对象更新UI。