从不同的viewcontroller按字母顺序对tableview内的单元格进行排序

时间:2016-03-25 15:39:15

标签: swift uitableview uiviewcontroller

我有两个场景。场景A是由水果列表组成的桌面视图。场景B有一个分段控制器,其中一个选项是按字母顺序对水果进行排序。

场景A:

@IBOutlet weak var tableView: UITableView!


override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if  segue.identifier == "showFilter" {
        _ = segue.destinationViewController as! FilterViewController
    } 
}

?func alpheticalOrder(sender: AnyObject) { 
    fruits.sortInPlace({$0.name < $1.name }) } ?

场景B:

func tableView(tableView:UITableView, cellForRowAtIndexPath indexPath:NSIndexPath) -> UITableViewCell {
    if indexPath.row == 0 {
        let cell = tableView.dequeueReusableCellWithIdentifier("FilterCell") as! FilterCell
        cell.segmentedController.addTarget(self, action: "segmentedControllerActionChanged:", forControlEvents: .ValueChanged)
        return cell

    } 

    @IBAction func segmentedControllerActionChanged(sender: AnyObject) {
    if sender.selectedSegmentIndex == 0 {
        fruits.sortInPlace({$0.name < $1.name })
    }

override func viewDidLoad() {
    super.viewDidLoad()
    let tap = UITapGestureRecognizer(target: self, action: "close:")
    greyView.addGestureRecognizer(tap)
}

func close(tap: UITapGestureRecognizer) {
    self.presentingViewController?.dismissViewControllerAnimated(true, completion: nil)
}

这里的ViewController().tableView.reloadData()行是不正确的,虽然我把它放进去帮助理解我想要实现的目标。不知何故,我需要重新加载tableview数据,以便在退出场景B后返回到场景A,按字母顺序按字母顺序对单元格进行排序。

1 个答案:

答案 0 :(得分:1)

考虑代码行:

ViewController().tableView.reloadData()

这并不能告诉现有的ViewController重新加载。 ViewController()创建该视图控制器的 new 实例(未连接到任何故事板场景;没有数据;将立即释放),并告诉它重新加载。

你需要让B引用现有的A,而不是创建一个新的A.另外,你可能不想在B中排序fruits,而是在A中排序。因此:

  • 在B中添加一个指向A:

    的属性
    var sourceViewController: ViewControllerA! 
    
  • 在A的prepareForSegue中,您必须在B中设置此属性,例如:

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if segue.identifier == "showFilter" {
            let filterViewController = segue.destinationViewController as! FilterViewController
            filterViewController.sourceViewController = self
        } 
    }
    
  • 实现A中的方法,对数据进行排序并重新加载表:

    func sortFruitsAndReload() {
        fruits.sortInPlace {$0.name < $1.name }
        tableView.reloadData()
    }
    
  • B中的segmentedControllerActionChanged应该在A:

    中调用该方法
    @IBAction func segmentedControllerActionChanged(sender: AnyObject) {
        if sender.selectedSegmentIndex == 0 {
            sourceViewController.sortFruitsAndReload()
        }
    }
    

或者,更好的是,使用协议来保持这两个类&#34;弱耦合&#34; (即在其他情况下打开门以使用此过滤器/排序视图控制器):

  • 在B中添加协议:

    protocol FilterViewDelegate {
        func sortAndReload()
    }
    
  • 在B中添加一个属性以维护对此delegate的引用:

    var delegate: FilterViewDelegate?
    
  • 指定A符合此协议:

    class ViewControllerA: UIViewController, FilterViewDelegate { ... }
    

    显然,将A&#39的视图控制器类和基类的名称保存到您现在使用的任何名称,但只需将FilterViewDelegate添加到类声明中;

  • 实现A中的方法,对数据进行排序并重新加载表,以满足符合此协议的要求:

    func sortAndReload() {
        fruits.sortInPlace {$0.name < $1.name }
        tableView.reloadData()
    }
    
  • 在A的prepareForSegue
  • ,您在B中设置了此delegate属性,例如

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if segue.identifier == "showFilter" {
            let filterViewController = segue.destinationViewController as! FilterViewController
            filterViewController.delegate = self
        } 
    }
    
  • B中的segmentedControllerActionChanged应该在A中调用该方法。

    @IBAction func segmentedControllerActionChanged(sender: AnyObject) {
        if sender.selectedSegmentIndex == 0 {
            delegate?.sortAndReload()
        }
    }