Answers:
它与obj-c没什么不同。首先,您必须在类声明中指定协议,如下所示:
class MyClass: NSUserNotificationCenterDelegate
该实现将如下所示:
// NSUserNotificationCenterDelegate implementation
func userNotificationCenter(center: NSUserNotificationCenter, didDeliverNotification notification: NSUserNotification) {
//implementation
}
func userNotificationCenter(center: NSUserNotificationCenter, didActivateNotification notification: NSUserNotification) {
//implementation
}
func userNotificationCenter(center: NSUserNotificationCenter, shouldPresentNotification notification: NSUserNotification) -> Bool {
//implementation
return true
}
当然,您必须设置委托。例如:
NSUserNotificationCenter.defaultUserNotificationCenter().delegate = self;
@interface MyCustomClass: UIViewController <ClassIWantToUseDelegate>
,即允许您初始化/配置ViewController并在子视图上调用委托方法?与此相似吗?
这对两个视图控制器之间的委托有一些帮助:
第1步:在UIViewController中制定要删除/将要发送数据的协议。
protocol FooTwoViewControllerDelegate:class {
func myVCDidFinish(_ controller: FooTwoViewController, text: String)
}
步骤2: 在发送类中声明委托(即,UIViewcontroller)
class FooTwoViewController: UIViewController {
weak var delegate: FooTwoViewControllerDelegate?
[snip...]
}
步骤3: 在类方法中使用委托将数据发送到接收方法,该方法是采用协议的任何方法。
@IBAction func saveColor(_ sender: UIBarButtonItem) {
delegate?.myVCDidFinish(self, text: colorLabel.text) //assuming the delegate is assigned otherwise error
}
步骤4:在接收类中采用协议
class ViewController: UIViewController, FooTwoViewControllerDelegate {
步骤5:实现委托方法
func myVCDidFinish(_ controller: FooTwoViewController, text: String) {
colorLabel.text = "The Color is " + text
controller.navigationController.popViewController(animated: true)
}
步骤6:在prepareForSegue中设置委托:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "mySegue" {
let vc = segue.destination as! FooTwoViewController
vc.colorString = colorLabel.text
vc.delegate = self
}
}
那应该起作用。当然,这只是代码片段,但应该可以为您提供帮助。有关此代码的详细说明,您可以在这里转到我的博客条目:
如果您对与一名代表的幕后事情感兴趣,我确实在这里写过:
weak
仅对于类而不是结构和枚举才需要。如果委托将是一个结构体或枚举,那么您不必担心保留周期。但是,将其委托给一个类(在很多情况下,这是正确的,因为通常是一个ViewController),那么您需要weak
但需要将协议声明为一个类。在此处有更多信息stackoverflow.com/a/34566876/296446
在我意识到代表只是一个为另一个班做些工作的班之前,代表们总是使我困惑。这就像让其他人为您做所有您不想自己做的肮脏的工作。
我写了一个小故事来说明这一点。如果愿意,可以在操场上阅读。
// MARK: Background to the story
// A protocol is like a list of rules that need to be followed.
protocol OlderSiblingDelegate: class {
// The following command (ie, method) must be obeyed by any
// underling (ie, delegate) of the older sibling.
func getYourNiceOlderSiblingAGlassOfWater()
}
// MARK: Characters in the story
class BossyBigBrother {
// I can make whichever little sibling is around at
// the time be my delegate (ie, slave)
weak var delegate: OlderSiblingDelegate?
func tellSomebodyToGetMeSomeWater() {
// The delegate is optional because even though
// I'm thirsty, there might not be anyone nearby
// that I can boss around.
delegate?.getYourNiceOlderSiblingAGlassOfWater()
}
}
// Poor little sisters have to follow (or at least acknowledge)
// their older sibling's rules (ie, protocol)
class PoorLittleSister: OlderSiblingDelegate {
func getYourNiceOlderSiblingAGlassOfWater() {
// Little sis follows the letter of the law (ie, protocol),
// but no one said exactly how she had to respond.
print("Go get it yourself!")
}
}
// MARK: The Story
// Big bro is laying on the couch watching basketball on TV.
let bigBro = BossyBigBrother()
// He has a little sister named Sally.
let sally = PoorLittleSister()
// Sally walks into the room. How convenient! Now big bro
// has someone there to boss around.
bigBro.delegate = sally
// So he tells her to get him some water.
bigBro.tellSomebodyToGetMeSomeWater()
// Unfortunately no one lived happily ever after...
// The end.
在回顾中,制作和使用委托模式包含三个关键部分。
与上面的Bossy Big Brother故事相比,代表通常用于以下实际应用:
最重要的是,这些类不需要相互了解任何东西,除了委托类符合所需的协议。
我强烈建议阅读以下两篇文章。他们帮助我比文档更好地理解了代表。
多一点
引用他们不拥有的其他类的代表应使用weak
关键字来避免强引用周期。有关更多详细信息,请参见此答案。
我对@MakeAppPie的帖子进行了一些更正
首先,当您创建委托协议时,它应该符合Class协议。像下面的例子一样。
protocol ProtocolDelegate: class {
func myMethod(controller:ViewController, text:String)
}
其次,您的代表应虚弱以避免保留周期。
class ViewController: UIViewController {
weak var delegate: ProtocolDelegate?
}
最后,您很安全,因为您的协议是可选值。这意味着其“ nil”消息将不会发送到此属性。它类似于respondToselector
objC中的条件语句,但是在这里您将所有内容放在一行中:
if ([self.delegate respondsToSelector:@selector(myMethod:text:)]) {
[self.delegate myMethod:self text:@"you Text"];
}
上面有一个obj-C示例,下面有一个Swift外观示例。
delegate?.myMethod(self, text:"your Text")
delegate?.myMethod
不会崩溃,因为如果使用了委托,nil
那么什么也不会发生。但是,如果您写错了并写了信delegate!.myMethod
,如果未设置代表,则可能导致崩溃,因此从根本上来说,这是一种确保您安全的方法...
这是我总结的要点。我也想知道,这有助于增进我的理解。在Xcode Playground中打开它,看看发生了什么。
protocol YelpRequestDelegate {
func getYelpData() -> AnyObject
func processYelpData(data: NSData) -> NSData
}
class YelpAPI {
var delegate: YelpRequestDelegate?
func getData() {
println("data being retrieved...")
let data: AnyObject? = delegate?.getYelpData()
}
func processYelpData(data: NSData) {
println("data being processed...")
let data = delegate?.processYelpData(data)
}
}
class Controller: YelpRequestDelegate {
init() {
var yelpAPI = YelpAPI()
yelpAPI.delegate = self
yelpAPI.getData()
}
func getYelpData() -> AnyObject {
println("getYelpData called")
return NSData()
}
func processYelpData(data: NSData) -> NSData {
println("processYelpData called")
return NSData()
}
}
var controller = Controller()
UIViewController
班级都符合我们所做的委托?是否必须在一个快速文件中声明它们?任何帮助都将非常重要。
class ViewController : UIViewController NameOfDelegate
。
a.swift
根据上面的回答创建一个委托类时,它没有出现b.swift
。我无法在swift文件之外的任何课程上上课。有困难吗?
SWIFT 2中的代表
我以带有两个viewControllers的Delegate示例为例进行说明。在这种情况下,SecondVC Object将数据发送回第一个View Controller。
带有协议声明的类
protocol getDataDelegate {
func getDataFromAnotherVC(temp: String)
}
import UIKit
class SecondVC: UIViewController {
var delegateCustom : getDataDelegate?
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
@IBAction func backToMainVC(sender: AnyObject) {
//calling method defined in first View Controller with Object
self.delegateCustom?.getDataFromAnotherVC("I am sending data from second controller to first view controller.Its my first delegate example. I am done with custom delegates.")
self.navigationController?.popViewControllerAnimated(true)
}
}
在First ViewController协议中,此处符合条件:
class ViewController: UIViewController, getDataDelegate
First View Controller(ViewController)中的协议方法定义
func getDataFromAnotherVC(temp : String)
{
// dataString from SecondVC
lblForData.text = dataString
}
在从First View Controller(ViewController)推送SecondVC的过程中
let objectPush = SecondVC()
objectPush.delegateCustom = self
self.navigationController.pushViewController(objectPush, animated: true)
头等舱:
protocol NetworkServiceDelegate: class {
func didCompleteRequest(result: String)
}
class NetworkService: NSObject {
weak var delegate: NetworkServiceDelegate?
func fetchDataFromURL(url : String) {
delegate?.didCompleteRequest(url)
}
}
第二类:
class ViewController: UIViewController, NetworkServiceDelegate {
let network = NetworkService()
override func viewDidLoad() {
super.viewDidLoad()
network.delegate = self
network.fetchDataFromURL("Success!")
}
func didCompleteRequest(result: String) {
print(result)
}
}
Type 'ViewController' does not conform to protocol 'NetworkServiceDelegate'
plz建议。这是我第六天忙碌起来:)
一步一步非常简单(100%的工作和测试)
步骤1:在第一个视图控制器上创建方法
func updateProcessStatus(isCompleted : Bool){
if isCompleted{
self.labelStatus.text = "Process is completed"
}else{
self.labelStatus.text = "Process is in progress"
}
}
步骤2:在推送到第二个视图控制器时设置委托
@IBAction func buttonAction(_ sender: Any) {
let secondViewController = self.storyboard?.instantiateViewController(withIdentifier: "secondViewController") as! secondViewController
secondViewController.delegate = self
self.navigationController?.pushViewController(secondViewController, animated: true)
}
第三步:设置代表像
ViewController类:UIViewController,ProcessStatusDelegate {
步骤4:建立通讯协定
protocol ProcessStatusDelegate:NSObjectProtocol{
func updateProcessStatus(isCompleted : Bool)
}
第五步:取一个变量
var delegate:ProcessStatusDelegate?
步骤6:在返回上一个视图控制器调用委托方法的同时,第一个视图控制器使用数据进行通知
@IBAction func buttonActionBack(_ sender: Any) {
delegate?.updateProcessStatus(isCompleted: true)
self.navigationController?.popViewController(animated: true)
}
@IBAction func buttonProgress(_ sender: Any) {
delegate?.updateProcessStatus(isCompleted: false)
self.navigationController?.popViewController(animated: true)
}
简单的例子:
protocol Work: class {
func doSomething()
}
class Manager {
weak var delegate: Work?
func passAlong() {
delegate?.doSomething()
}
}
class Employee: Work {
func doSomething() {
print("Working on it")
}
}
let manager = Manager()
let developer = Employee()
manager.delegate = developer
manager.passAlong() // PRINTS: Working on it
上面的解决方案似乎有点耦合,同时又避免在其他控制器中重用相同的协议,这就是为什么我要使用通用类型擦除来提供更强类型的解决方案。
@noreturn public func notImplemented(){
fatalError("not implemented yet")
}
public protocol DataChangedProtocol: class{
typealias DataType
func onChange(t:DataType)
}
class AbstractDataChangedWrapper<DataType> : DataChangedProtocol{
func onChange(t: DataType) {
notImplemented()
}
}
class AnyDataChangedWrapper<T: DataChangedProtocol> : AbstractDataChangedWrapper<T.DataType>{
var base: T
init(_ base: T ){
self.base = base
}
override func onChange(t: T.DataType) {
base.onChange(t)
}
}
class AnyDataChangedProtocol<DataType> : DataChangedProtocol{
var base: AbstractDataChangedWrapper<DataType>
init<S: DataChangedProtocol where S.DataType == DataType>(_ s: S){
self.base = AnyDataChangedWrapper(s)
}
func onChange(t: DataType) {
base.onChange(t)
}
}
class Source : DataChangedProtocol {
func onChange(data: String) {
print( "got new value \(data)" )
}
}
class Target {
var delegate: AnyDataChangedProtocol<String>?
func reportChange(data:String ){
delegate?.onChange(data)
}
}
var source = Source()
var target = Target()
target.delegate = AnyDataChangedProtocol(source)
target.reportChange("newValue")
输出:获得新值newValue