在iPhone中,每个UIContrrol都有预定义的委托方法,但我们将如何创建自己的自定义委托方法
答案 0 :(得分:19)
在您的标头文件中,@interface
之前,插入
@protocol YourDelegate <NSObject>
@optional
- (void) anOptionalDelegateFunction;
@required
- (void) aRequiredDelegateFunction;
@end
并在@interface
下
@property (nonatomic, assign) id<YourDelegate> delegate;
// Remember to synthesize in implementation file
现在您可以调用.m文件
[delegate aRequiredDelegateFunction];
并在代表
中<YourDelegate>
self
答案 1 :(得分:1)
创建自定义代理和协议iOS |斯威夫特&amp;目标C
协议
协议是一个方法列表,用于指定代理将实现的接口。我们可以使用两种代理:Option和Required。它们是非常自我解释但不同的是必须会抛出一个错误,让你知道你的类不符合协议。默认情况下也需要协议方法,因此如果您希望它是可选的,请不要忘记可选关键字。如果你使用swift,你还需要添加@objc前缀,如果你想要一个可选的方法。
<强>夫特强>
//
// MyTimer.swift
// SwiftProtocol
//
// Created by Barrett Breshears on 10/11/14.
// Copyright (c) 2014 Sledge Dev. All rights reserved.
//
import UIKit
// set up the MyTimerDelegate protocol with a single option timer function
@objc protocol MyTimerDelegate{
optional func timerFinished()
}
class MyTimer: UIViewController {
// this is where we declare our protocol
var delegate:MyTimerDelegate?
// set up timer variables and labels
var timer:NSTimer! = NSTimer()
var labelTimer:NSTimer! = NSTimer()
var timerLabel:UILabel! = UILabel()
var timerCount = 0
var duration = 0
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
timerLabel = UILabel(frame: self.view.frame)
timerLabel.textAlignment = NSTextAlignment.Center
self.view.addSubview(timerLabel)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func startTimer(timerDuration:Double){
self.duration = Int(timerDuration)
timerLabel.text = String(format: "%d", duration)
timer = NSTimer.scheduledTimerWithTimeInterval(timerDuration, target: self, selector: Selector("timerFired:"), userInfo: nil, repeats: false)
labelTimer = NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: Selector("updateLabel:"), userInfo: nil, repeats: true)
}
timer.invalidate()
}
if(labelTimer.valid){
labelTimer.invalidate()
}
// ************************************** \\
// ************************************** \\
// This is the important part right here
// we want to call our protocol method
// so the class implementing this delegate will know
// when the timer has finished
// ************************************** \\
// ************************************** \\
delegate?.timerFinished!()
}
func updateLabel(timer:NSTimer){
duration = duration - 1
timerLabel.text = String(format: "%d", duration)
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}
*/
}
这是一个非常简单的例子,但这是正在发生的事情。 UIViewController有一个启动计时器方法,用于设置两个计时器:一个在整个时间结束时触发,另一个在每秒触发一次以更新计时器标签。当总持续时间计时器结束时,调用timerFired方法,这就是我们运行委托的timerFinished方法的地方。现在让我们做同样的事情,但使用Objective-C。
<强>目标C 强>
//
// MyTimer.h
// ObjectIveCProtocol
//
// Created by Barrett Breshears on 10/11/14.
// Copyright (c) 2014 Sledge Dev. All rights reserved.
//
#import
// set up the MyTimerDelegate protocol with a single option timer finished function
@protocol MyTimerDelegate
@optional
-(void)timerFinished;
@end
@interface MyTimer : UIViewController
// this is where we declare our protocol
@property (nonatomic, strong) id delegate;
// set up timer variables and labels
@property (nonatomic, strong) NSTimer *timer;
@property (nonatomic, strong) NSTimer *labelTimer;
@property (nonatomic, strong) UILabel *timerLabel;
@property (nonatomic, assign) int timerCount;
@property (nonatomic, assign) int duration;
- (void)startTimer:(float)duration;
@end
//
// MyTimer.m
// ObjectIveCProtocol
//
// Created by Barrett Breshears on 10/11/14.
// Copyright (c) 2014 Sledge Dev. All rights reserved.
//
#import "MyTimer.h"
@interface MyTimer ()
@end
@implementation MyTimer
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
_timer = [[NSTimer alloc] init];
_labelTimer = [[NSTimer alloc] init];
_timerCount = 0;
_duration = 0;
_timerLabel = [[UILabel alloc] initWithFrame:self.view.frame];
[self.view addSubview:_timerLabel];
[_timerLabel setTextAlignment:NSTextAlignmentCenter];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)startTimer:(float)duration{
_duration = (int)duration;
_timerLabel.text = [NSString stringWithFormat:@"%d", _duration];
_timer = [NSTimer scheduledTimerWithTimeInterval:duration target:self selector:@selector(timerFired:) userInfo:nil repeats:NO];
_labelTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updateLabel:) userInfo:nil repeats:YES];
}
- (void)timerFired:(NSTimer *)timer {
if ([_timer isValid]) {
[_timer invalidate];
}
_timer = nil;
if ([_labelTimer isValid]) {
_labelTimer invalidate];
}
_labelTimer = nil;
// ************************************** \\
// This is the important part right here
// we want to call our protocol method here
// so the class implementing this delegate will know
// when the timer has finished
// ************************************** \\
[_delegate timerFinished];
}
- (void)updateLabel:(NSTimer *)timer{
_duration = _duration - 1;
_timerLabel.text = [NSString stringWithFormat:@"%d",
_duration];
}
@end
同样的事情只是不同的语法。 UIViewController有一个启动计时器方法,用于设置两个计时器:一个在整个时间结束时触发,另一个在每秒触发一次以更新计时器标签。当总持续时间计时器结束时,调用timerFired方法,这就是我们运行委托的timerFinished方法的地方。
<强> 代表 强>
既然我们已经设置了所有协议,我们所要做的就是实现它们。我们将通过创建委托来实现此目的。委托是符合协议的变量,类通常用于通知事件,在这种情况下计时器结束。为此,我们将协议添加到类声明中,让我们的类知道它必须符合委托。然后我们将我们的委托方法添加到我们的类中。
<强>夫特强>
//
// ViewController.swift
// Swift-Protocol
// Created by Barrett Breshears on 10/11/14.
// Copyright (c) 2014 Sledge Dev. All rights reserved.
import UIKit
// add our MyTimerDelegate to our class
class ViewController: UIViewController, MyTimerDelegate {
var timer:MyTimer = MyTimer()
override func viewDidLoad() {
super.viewDidLoad()
timer.view.frame = self.view.frame
// ************************ \\
// This is where we let the delegate know
// we are listening for the timerFinished method
// ************************ \\
timer.delegate = self
self.view.addSubview(timer.view)
timer.startTimer(10.0)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// ************************ \\
// This is where our delegate method is fired
// ************************ \\
func timerFinished(){
timer.startTimer(10.0)
println("Hey my delegate is working")
}
}
所以重要的是我们将timer.delegate设置为self,以便调用ViewController的方法timerFinished()类。
<强>目标C 强>
//
// ViewController.h
// ObjectIveCProtocol
//
// Created by Barrett Breshears on 10/10/14.
// Copyright (c) 2014 Sledge Dev. All rights reserved.
#import
#import "MyTimer.h"
// add our MyTimerDelegate to our class
@interface ViewController : UIViewController
@property (nonatomic, strong) MyTimer *timer;
@end
// ViewController.m
// ObjectIveCProtocol
// Created by Barrett Breshears on 10/10/14.
// Copyright (c) 2014 Sledge Dev. All rights reserved.
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
_timer = [[MyTimer alloc] init];
_timer.view.frame = self.view.frame;
_timer.delegate = self;
[self.view addSubview:_timer.view];
[_timer startTimer:10.0];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void)timerFinished{
[_timer startTimer:10.0];
NSLog(@"Hey my delegate is working!");
}
@end
当我们运行代码时,我们看到添加了计时器标签并设置为10秒计时器。它倒计时,当它达到0时,它通知视图控制器,重新启动计时器并打印“嘿,我的委托在控制台中工作”。
如果您对代码有任何疑问或发现本教程有帮助,请在下面的评论中告诉我们!我很感激反馈。另外别忘了在twitter上关注我。我一直在寻找iOS开发人员发推文。
如果您想关注允许,可以在此处从GitHub下载项目:
https://github.com/barrettbreshears/objective-c-protocol
,或者
答案 2 :(得分:-5)
在您的班级中创建一个id对象委托。创建一个getter和setter,以便其他类可以将自己设置为委托。 在你的课堂上添加:
@interface MyClass (Private)
-(void)myDelegateMethod;
@end
然后在你想要回调给委托的类的任何函数中做这样的事情:
if ( [delegate respondsToSelector:@selector(myDelegateMethod)] ) {
[delegate myDelegateMethod];
}