2015-07-20 3 views
2

Я пытаюсь сделать протокол и делегат в Swift, но у меня есть некоторые проблемы. Я хочу иметь кнопку переключателя в ячейках таблицы. Вот мой протокол:Протокол и делегирование в Swift

import Foundation 
import UIKit 

protocol CellProtocol { 
    func onSwitchToogle (sender : AnyObject , onCell : UITableViewCell) 
} 

Вот мой мобильный класс:

import UIKit 

class Cell: UITableViewCell { 

    @IBOutlet weak var label: UILabel! 
    @IBOutlet weak var flag: UISwitch! 
    var cellDelegate:CellProtocol! 

    @IBAction func Toogle(sender: AnyObject) { 
     if((cellDelegate?.onSwitchToogle(sender, onCell: self)) != nil){ 

     } 
    } 
} 

А вот мой ViewController:

import UIKit 

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, CellProtocol {  
    func onSwitchToogle(sender: AnyObject, onCell: UITableViewCell) { 

    } 

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
     return 1 
    } 

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 
     let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! Cell 
     cell.label.text = "sadsad" 
     return cell 
    } 
} 

Проблема в том, что никогда не входит в если условие в IBAction моего переключателя, и он никогда не входит в метод на ViewController.

+2

Плюс ... 'onSwitchToogle()' ничего не возвращает, поэтому я даже не уверен, что вы пытаетесь сделать с этим оператором 'if' ... – nhgrif

+0

Не делайте ваш делегат неявно развернутым ! –

ответ

1

Пара вещей:

  1. Вы хотите, чтобы убедиться, что вы указываете делегат в cellForRowAtIndexPath:

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 
        let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! Cell 
        cell.cellDelegate = self 
        cell.label.text = "sadsad" 
        return cell 
    } 
    
  2. Убедитесь, что у вас нет сильного опорного цикла, делая cellDelegate свойство weak:

    weak var cellDelegate: CellProtocol! 
    
  3. Чтобы позволить вам иметь слабые ссылки на тип протокола, вы должны сделать протокол о class протокола:

    protocol CellProtocol : class { 
        func onSwitchToggle (sender : AnyObject, onCell : UITableViewCell) 
    } 
    
  4. Вы, очевидно, просто хотите позвонить onSwitchToggle, если делегат установлен (с использованием дополнительной цепочки):

    @IBAction func toggle(sender: AnyObject) { 
        cellDelegate?.onSwitchToggle(sender, onCell: self) 
    } 
    

    Тест не требуется чтобы делегат реализовал этот метод, поскольку, если контроллер представления соответствует протоколу, он должен реализовать этот метод.

Пожалуйста, простите меня, но я изменил имена методов (тумблер против Toogle, начинает методы имена с прописными буквами и т.д.), но, надеюсь, это иллюстрирует ключевые моменты.

+0

Я wold объявляю делегата как необязательный, вместо неявно развернутого необязательного: 'слабый var cellDelegate: CellProtocol?' –

+0

Это зависит от намерения OP. Если приложение сконструировано таким образом, что в некоторых ячейках есть делегаты, а другие нет, то я согласен, он должен быть факультативным. Если у _all_ членов класса «Ячейка» _ всегда будет «cellDelegate», то я лично предпочитаю неявно разворачивать, чтобы сделать это намерение понятным. – Rob

0

В cellForRowAtIndexPath создан делегат себя:

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 

     let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! Cell 

     cell.label.text = "sadsad" 
     cell.cellDelegate = self 

     return cell 

    } 
Смежные вопросы