Дэйв, вот простой способ сделать это, это без протоколов, а вместо этого мы используем блоки.в пользовательской UITableViewCell, мы делаем это:
SETUP:
import Foundation
import UIKit
class EXTableViewCell: UITableViewCell {
@IBOutlet var nameLabel: UILabel!
@IBOutlet var descLabel: UILabel!
var doWork: (() -> Void)?
func swipedLeft (sender: UISwipeGestureRecognizer) {
if let callback = self.doWork {
println("swipe detected, cell function run")
callback()
}
}
override func awakeFromNib() {
super.awakeFromNib()
let swipeLeft: UISwipeGestureRecognizer = UISwipeGestureRecognizer(target: self, action: "swipedLeft")
swipeLeft.direction = UISwipeGestureRecognizerDirection.Left
self.addGestureRecognizer(swipeLeft)
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
}
Пользовательские ViewController:
import UIKit
class DetailViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
}
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 0 //replace with the correct info
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 4 //replace with the correct info
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! FFViewCell
cell.doWork = {
() -> Void in
self.doStuff(indexPath.row)
}
cell.labelMessage.text = items[indexPath.row] as String
return cell
}
func doStuff(integer: NSInteger) {
println("i got here \(integer)")
}
}
Как это работает:
Вы видите, мы объявляя свойство блока, которое позволяет нам передать пустой вызов функции (PER SE) на любой «EXTable» ViewCell ", который вы создаете в своем UIViewController.
Так, в обычае UITableViewCell, мы объявляем свойство пустоты блока:
var doWork: (() -> Void)?
Мы придаем сенсорный обработчик клетку:
func swipedLeft (sender: UISwipeGestureRecognizer) {
if let callback = self.doWork {
println("swipe detected, cell function run")
callback()
}
}
Затем мы называем в этот обработчик внутри или основных UIViewController и установить это свойство при настройке нашего вида таблицы. Клетки:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! EXTableViewCell
cell.doWork = {
() -> Void in
self.doStuff()
}
return cell
}
Спецификация fically:
cell.doWork = {
() -> Void in
self.doStuff()
}
Мы, очевидно, затем настроить функцию «DoStuff» делать то, что мы хотим сделать в нашем UIViewController:
func doStuff() {
println("i got here")
}
Нет протоколов, не беспорядок, не завинчивания вокруг с созданием делегации происходят, все функции, основанные на блоках. Я не тестировал этот код с фактическим UIViewController, однако это работает безупречно в Objective-C и перед публикацией этого кода я убедился, что он компилируется.
Как быстрая заметка об огромности блоков, почти все, что кажется супер сложным с делегированием и протоколами, может быть выполнено с помощью блоков, жесткая часть используется для использования блоков и понимания их универсальности. Вероятно, наиболее приятной является тот факт, что вы можете использовать «свойства блока», как обычное свойство, но с дополнительным преимуществом присоединения события обработчика к объекту, которому принадлежит свойство блока. Во всяком случае, еще одна вещь, которую вы, возможно, придется сделать это, но это просто:
Вам может понадобиться, чтобы начать свой собственный вид ячейки таблицы, как это так, что делает его делегатом UIGestureRecognizer так:
class EXTableViewCell: UITableViewCell, UIGestureRecognizerDelegate {
и вам, возможно, придется объявить жест распознаватель в классе настраиваемой таблицы вида клеток, так это выглядит примерно так:
swipeLeft.delegate = self
swipeLeft.cancelsTouchesInView = false
Кроме того, если у вас есть проблемы, делая это произойдет, то дайте мне знать, я буду видеть если я не могу просто получить полную реализацию для этого.
Рабочий пример, испытания и готов к работе:
Пользовательские tableViewCell:
import Foundation
import UIKit
class FFViewCell: UITableViewCell, UIGestureRecognizerDelegate {
var labelMessage = UILabel()
var doWork: (() -> Void)?
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
let swipeLeft: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: "this")
swipeLeft.delegate = self
swipeLeft.cancelsTouchesInView = false
self.addGestureRecognizer(swipeLeft)
labelMessage.setTranslatesAutoresizingMaskIntoConstraints(false)
contentView.addSubview(labelMessage)
var viewsDict = ["labelMessage" : labelMessage]
contentView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|[labelMessage]|", options: NSLayoutFormatOptions(0), metrics: nil, views: viewsDict))
contentView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-20-[labelMessage]", options: NSLayoutFormatOptions(0), metrics: nil, views: viewsDict))
}
required init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func this() {
if let callback = self.doWork {
println("swipe detected, cell function run")
callback()
}
}
}
AppDelegate:
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
var rootViewController: UINavigationController?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
window = UIWindow(frame: UIScreen.mainScreen().bounds)
rootViewController = UINavigationController(rootViewController: ViewController())
if let window = window {
window.backgroundColor = UIColor.whiteColor()
window.rootViewController = rootViewController
window.makeKeyAndVisible()
}
return true
}
func applicationWillResignActive(application: UIApplication) {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}
func applicationDidEnterBackground(application: UIApplication) {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
func applicationWillEnterForeground(application: UIApplication) {
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}
func applicationDidBecomeActive(application: UIApplication) {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
func applicationWillTerminate(application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
}
ViewController:
import UIKit
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
var tableView : UITableView?
var items = ["asdf","asdf","asdf","asdf","asdf"]
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
}
required init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
tableView = UITableView(frame: CGRectMake(0, 0, 414, 736), style: UITableViewStyle.Plain)
tableView!.delegate = self
tableView!.dataSource = self
tableView!.registerClass(FFViewCell.self, forCellReuseIdentifier: "Cell")
self.view .addSubview(tableView!)
}
override func loadView() {
var stuf = UIView()
stuf.frame = CGRectMake(0, 0, 414, 736)
stuf.backgroundColor = UIColor .redColor()
self.view = stuf
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return items.count;
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView:UITableView, heightForRowAtIndexPath indexPath:NSIndexPath)->CGFloat
{
return 44
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! FFViewCell
cell.doWork = {
() -> Void in
self.doStuff()
}
cell.labelMessage.text = items[indexPath.row] as String
return cell
}
func doStuff() {
println("i got here")
}
}
Вот «коромысло gesture ", Dave:
import Foundation
import UIKit
class FFViewCell: UITableViewCell, UIGestureRecognizerDelegate {
var labelMessage = UILabel()
var doWork: (() -> Void)?
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
let swipeLeft: UISwipeGestureRecognizer = UISwipeGestureRecognizer(target: self, action: "this")
swipeLeft.direction = UISwipeGestureRecognizerDirection.Left
swipeLeft.delegate = self
swipeLeft.cancelsTouchesInView = false
self.addGestureRecognizer(swipeLeft)
labelMessage.setTranslatesAutoresizingMaskIntoConstraints(false)
contentView.addSubview(labelMessage)
var viewsDict = ["labelMessage" : labelMessage]
contentView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|[labelMessage]|", options: NSLayoutFormatOptions(0), metrics: nil, views: viewsDict))
contentView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-20-[labelMessage]", options: NSLayoutFormatOptions(0), metrics: nil, views: viewsDict))
}
required init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func this() {
if let callback = self.doWork {
println("swipe detected, cell function run")
callback()
}
}
}
Larcerax, спасибо. Эта вещь блока совершенно для меня совершенно. Что означает пустота? Кроме того, теперь я получаю индексный путь, просто ссылаясь на переменную 'cell'? Я обязательно попробую это, но хочу быть бодрым. Здесь почти 6 утра, и я работаю над этим всю ночь, поэтому примерно через 8-10 часов я дам вам знать, если это сработает. Спасибо –
Да, так что вы можете ссылаться на ячейку так же, как вы делаете, более чем вероятно, а «void» просто означает, что нет никакого возвращаемого значения, это просто funciton, который работает, и вот так. – Loxx
У меня, вероятно, будет решение, полностью в течение следующих 2 часов, поэтому, когда вы встаете и пробудитесь, повторите проверку – Loxx