Iphone 如何在iOS应用程序中自定义委托

Iphone 如何在iOS应用程序中自定义委托,iphone,Iphone,在iPhone中,每个UIContrrol都有预定义的委托方法,但如何在类中创建自己的自定义委托方法创建id对象委托。创建一个getter和setter,以便其他类可以将自己设置为委托。 在类中添加以下内容: @interface MyClass (Private) -(void)myDelegateMethod; @end 然后,在任何一个函数中,您想要回调作为委托的类,请执行以下操作: if ( [delegate respondsToSelector:@selector(myDelega

在iPhone中,每个UIContrrol都有预定义的委托方法,但如何在类中创建自己的自定义委托方法创建id对象委托。创建一个getter和setter,以便其他类可以将自己设置为委托。 在类中添加以下内容:

@interface MyClass (Private)
-(void)myDelegateMethod;
@end
然后,在任何一个函数中,您想要回调作为委托的类,请执行以下操作:

if ( [delegate respondsToSelector:@selector(myDelegateMethod)] ) {
[delegate myDelegateMethod];
}

在头文件的
@interface
之前,插入

@protocol YourDelegate <NSObject> 

@optional
- (void) anOptionalDelegateFunction;

@required
- (void) aRequiredDelegateFunction;

@end
现在可以调用.m文件了

[delegate aRequiredDelegateFunction];
在代表中

  • 像往常一样在.h文件中包括
  • 在.m中,将带有自定义委托的类的委托属性分配给
    self

创建自定义代理和协议iOS | Swift&Objective-C

协议

协议是指定代理将实现的接口的方法列表。我们可以使用两种委托:选项委托和必需委托。它们是非常不言自明的,但所需的差异将抛出一个错误,让您知道您的类不符合协议。另外,协议方法在默认情况下是必需的,所以如果您希望它是可选的,请不要忘记optional关键字。如果您使用的是swift,那么如果需要可选方法,还需要添加@objc前缀

Swift

//
//  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.
    }
    */

}
     //
     //  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")
          }

  }
这是一个非常简单的例子,但下面是正在发生的事情。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
        //
        //  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
所以相同的东西只是不同的语法。UIViewController有一个启动计时器方法,用于设置两个计时器:一个在总时间完成时启动,另一个每秒启动以更新计时器标签。当总持续时间计时器完成时,将调用timerFired方法,这就是我们运行委托的timerFinished方法的地方

代表

现在我们已经建立了所有的协议,我们所要做的就是实现它们。我们将通过创建一个委托来实现这一点。委托是一个符合协议的变量,类通常使用该协议来通知事件,在本例中是计时器。为此,我们将协议添加到类声明中,让类知道它必须遵守委托。然后我们将委托方法添加到类中

Swift

//
//  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.
    }
    */

}
     //
     //  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

   //
   //  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
        //
        //  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时,它通知viewcontroller,重新启动计时器并打印“嘿,我的代理正在控制台中工作”

如果您对代码有任何疑问,或者觉得本教程很有帮助,请在下面的评论中告诉我!我感谢您的反馈。也别忘了在推特上关注我。我一直在寻找iOS开发者一起推特

如果您希望遵守“允许”,您可以从GitHub下载项目:

或者


第一个答案:您好-接受的答案不起作用,请接受@Wilhelmsen的回答,因为它起作用。与@jaguar的回答相反,属性不需要
响应。选择器
myDelegateMethod的存在在编译时被检查,所以您应该使用
@protocol
(请参阅Wilhelmsen的回答)。