如何像Swift中的手风琴那样正确地扩展和折叠单元格?

时间:2015-02-21 17:28:14

标签: ios uitableview swift

在我的应用中,我正在尝试播放UITableView中的音频文件。当我点击单元格时,它必须扩展并播放音频。然后,如果我点击另一个单元格,它应该像手风琴一样,前一个单元格必须崩溃,音频才能停止。但是我的实现不会这样做:

import UIKit
import AVFoundation

class AudioTableViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {

@IBOutlet weak var tableView: UITableView!
var audioPlayer: AVAudioPlayer?
let mp3sPaths = NSBundle.mainBundle().pathsForResourcesOfType("mp3", inDirectory: nil)
var filteredAudios = [AnyObject]()
var mp3names:NSMutableArray = []
var cellTapped:Bool = true
var currentRow = 0;

override func viewDidLoad() {
    super.viewDidLoad()
    for mp3 in mp3sPaths as Array<String> {
        var mp3name = mp3.lastPathComponent
        mp3names.addObject(mp3name.stringByDeletingPathExtension)
    }
    println(mp3names)
    println(mp3sPaths)
    self.tableView.reloadData()
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
}

func tableView(tableView: UITableView, numberOfRowsInSection section:Int) -> Int {
    if tableView == self.searchDisplayController!.searchResultsTableView {
        return self.filteredAudios.count
    } else {
        return self.mp3names.count
    }
}

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("AudioCell") as AudioCell

    if tableView == self.searchDisplayController!.searchResultsTableView {
        cell.titleLabel.text = filteredAudios[indexPath.row] as? String

    } else {
        cell.titleLabel.text = mp3names[indexPath.row] as? String
    }

    cell.playIcon.text = "▶️"
    return cell
}

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    var mp3file = mp3sPaths[indexPath.row] as NSString
    var mp3URL: NSURL = NSURL.fileURLWithPath(mp3file)!
    var error: NSError?
    audioPlayer?.stop()
    audioPlayer = AVAudioPlayer(contentsOfURL: mp3URL, error: &error)
    audioPlayer?.play()
    if let cell = tableView.cellForRowAtIndexPath(indexPath) as? AudioCell {
        cell.playIcon.text = "◾️"
    }

    var selectedRowIndex = indexPath
    currentRow = selectedRowIndex.row
    tableView.beginUpdates()
    tableView.endUpdates()
}

func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath) {
    if let cell = tableView.cellForRowAtIndexPath(indexPath) as? AudioCell {
        cell.playIcon.text = "▶️"
    }
    audioPlayer?.stop()

    var selectedRowIndex = indexPath
    currentRow = selectedRowIndex.row
    tableView.beginUpdates()
    tableView.endUpdates()
}

func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
    if indexPath.row == currentRow {
        if cellTapped == false {
            cellTapped = true
            return 70
        } else {
            cellTapped = false
            return 40
        }
    }
    return 40
}

func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
    cell.layer.transform = CATransform3DMakeScale(0.1,0.1,1)
    UIView.animateWithDuration(0.25, animations: {
        cell.layer.transform = CATransform3DMakeScale(1,1,1)
    })
}

func filterContentForSearchText(searchText: String) {
    filteredAudios = mp3names as Array
    filteredAudios.filter{($0 as NSString).localizedCaseInsensitiveContainsString("\(searchText)")}
}

func searchDisplayController(controller: UISearchDisplayController!, shouldReloadTableForSearchString searchString: String!) -> Bool {
    self.filterContentForSearchText(searchString)
    return true
}

func tableView(tableView: UITableView!, editActionsForRowAtIndexPath indexPath: NSIndexPath!) -> [AnyObject]! {
    var shareAction = UITableViewRowAction(style: .Normal, title: "Share") { (action, indexPath) -> Void in
        tableView.editing = false
        println("shareAction")
    }
    shareAction.backgroundColor = UIColor.grayColor()

    var doneAction = UITableViewRowAction(style: .Default, title: "Done") { (action, indexPath) -> Void in
        tableView.editing = false
        println("readAction")
    }
    doneAction.backgroundColor = UIColor.greenColor()

    var deleteAction = UITableViewRowAction(style: .Default, title: "Delete") { (action, indexPath) -> Void in
        tableView.editing = false
        println("deleteAction")
    }

    return [deleteAction, doneAction, shareAction]
}

func tableView(tableView: UITableView!, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath!) {
}
}

截图如下: My Swift app

有人可以帮忙吗?

1 个答案:

答案 0 :(得分:1)

我认为您没有在示例中显示所有代码或当前代码。 我已经在swift中实现了同样的东西,我知道如果处理得当,表动画效果会非常好。

如果单元格框架本身大于表格所示的高度并且它有内容,则在通过heightForRowAtIndexPath折叠单元格时,或者可见的子视图悬垂时,需要隐藏单元格内容视图中的悬垂子视图在单元格折叠后,单元格框架将通过表格中的其他单元格显示。这可能是你案件中发生的事情,但你的写作很难确定。

但是直接设置alpha直接看起来很俗气。您应该使用UIView.animateWithDuration()在单元格缩小时以及单元格展开时需要隐藏的cell.contentView子视图的alpha属性设置动画。您希望它们在行收缩时淡出,并在展开时淡入。