我有UITableView
由自定义UITableViewCells
组成。在每个单元格中,有UILabel
和UISlider
。有人知道如何在其中一个滑块的值发生变化时,将滑块的新值从自定义UITableViewCell
(在单独的文件中)发送到UITableViewController
,以便我可以然后更新填充表的数组?
我到目前为止最接近的是一次失败的黑客攻击:当滑块值发生变化时触发setSelected
事件。虽然这会突出显示已更改的自定义单元格,但didSelectRowAtIndexPath
中的UITableViewController
未收到该事件。
提前谢谢你, 杰米
答案 0 :(得分:6)
您需要的是Delegate Pattern。
从那里引用来解释它的含义:
委托是一个简单而强大的模式,其中一个对象在一个 程序代表另一个对象或与另一个对象协调。 委托对象保持对另一个对象的引用 - 委托 - 并在适当的时间向其发送消息。该 消息通知委托委托对象的事件 即将处理或刚刚处理。代表可以回复 通过更新自身或其他对象的外观或状态来显示消息 在应用程序中,在某些情况下,它可以返回一个值 影响即将发生的事件的处理方式。主要价值 委托是它允许您轻松自定义行为 一个中心对象中的几个对象。
这些图表将帮助您了解发生了什么:
架构:
操作:
现在关于如何实现它,这是你必须要做的。
适用于Objective-C
:
首先,创建UITableViewCell
的委托方法。让我们将其命名为ContactTableViewCell
。
在ContactTableViewCell.h
文件中,执行以下操作:
@protocol ContactCellDelegate <NSObject>
@required
-(void) didMoveSliderWithValue:(float) value;
@end
@interface ContactTableViewCell : UITableViewCell
@property (weak, nonatomic) id<ContactCellDelegate> delegate;
现在将TableViewController符合此委托。我们将您的VC命名为MyTableViewController
。
在MyTableViewController.h
中,执行此操作:
@interface MyTableViewController : UIViewController <ContactCellDelegate> //Use UITableViewController if you are using that instead of UIViewController.
在cellForRowAtIndexPath
中,在返回单元格之前,添加以下行:
cell.delegate = self;
在MyTableViewController.m
。
-(void) didMoveSliderWithValue: (float) value
{
NSLog(@"Value is : %f",value);
//Do whatever you need to do with the value after receiving it in your VC
}
现在让我们回到你的ContactTableViewCell.m
。在该文件中,您必须添加一些IBAction以捕获滑块中的值更改事件。让我们说以下是:
- (IBAction)sliderValueChanged:(UISlider *)sender {
self.myTextLabel.text = [@((int)sender.value) stringValue]; //Do whatever you need to do in cell.
//Now call delegate method which will send value to your view controller:
[delegate didMoveSliderWithValue:sender.value];
}
当你调用delegate方法时,它将运行我们之前在MyTableViewController
中编写的实现。做任何你需要的方法。
这里发生的是你的Cell将消息发送到你想要的VC(Cell的代表),“嘿,调用我们之前写在你身体中的委托方法。我立刻给你发送参数” 。你的VC会获取参数,并在那时做你想要它做的任何事情。
适用于Swift
:
首先,您的TableViewCell.swift
文件,创建一个这样的协议:
@class_protocol protocol ContactCellDelegate {
func didMoveSliderWithValue(value: Float)
}
现在在您的Cell类中,创建一个委托属性,如:
var cellDelegate: ContactCellDelegate?
在Slider IBAction中,调用委托方法,如下所示:
self.cellDelegate?.didMoveSliderWithValue(slider.value)
在您的VC中执行以下更改:
使其符合代表:
class MyTableViewController: UIViewController, ContactCellDelegate
在cellForRowAtIndexPath
cell.cellDelegate = self //Dont forget to make it conform to the delegate method
添加所需委托方法的实现:
func didMoveSliderWithValue(value:float) {
//do what you want
}
我保持Swift部分的精确和总结,因为将详细的Obj-C解释更改为Swift实现应该非常容易。但是,如果您对上述任何指针感到困惑,请发表评论。
另见:StackOverflow answer on using Delegate pattern to pass data back