iPhone では、すべての UIControlrol に事前定義されたデリゲート メソッドがありますが、独自のカスタム デリゲート メソッドを作成する方法
3 に答える
ヘッダー ファイルの の前@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>
いつものように .h ファイルに含めます- .m で、クラスのデリゲート プロパティをカスタム デリゲートに割り当てます。
self
カスタム デリゲートとプロトコル iOS を作成するには | Swift & Objective-C
プロトコル
プロトコルは、デリゲートが実装するインターフェイスを指定するメソッドのリストです。使用できるデリゲートには、オプションと必須の 2 種類があります。それらはかなり自明ですが、違いは 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 には、2 つのタイマーを設定する開始タイマー メソッドがあります。1 つは全体の時間が完了すると起動し、もう 1 つは毎秒起動してタイマー ラベルを更新します。総継続時間タイマーが終了すると、timerFired メソッドが呼び出され、そこでデリゲートの timerFinished メソッドを実行します。今度は、Objective-C を使用して同じことを行いましょう。
Objective-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 には、2 つのタイマーを設定する開始タイマー メソッドがあります。1 つは全体の時間が完了すると起動し、もう 1 つは毎秒起動してタイマー ラベルを更新します。総継続時間タイマーが終了すると、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() クラスが呼び出されるようにすることです。
Objective-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 に達すると、ViewController に通知し、タイマーを再起動して、「Hey my delegate is working in the console」を出力します。
コードについて質問がある場合、またはこのチュートリアルが役に立った場合は、下のコメントでお知らせください。フィードバックに感謝します。また、ツイッターで私をフォローすることを忘れないでください。私は常に、ツイートする iOS 開発者を探しています。
許可に従いたい場合は、こちらの GitHub からプロジェクトをダウンロードできます。
https://github.com/barrettbreshears/objective-c-protocol
また、
クラスで id オブジェクト デリゲートを作成します。ゲッターとセッターを作成して、他のクラスが自分自身をデリゲートとして設定できるようにします。あなたのクラスにこれを追加してください:
@interface MyClass (Private)
-(void)myDelegateMethod;
@end
次に、デリゲートであるクラスにコールバックする関数で、次のようにします。
if ( [delegate respondsToSelector:@selector(myDelegateMethod)] ) {
[delegate myDelegateMethod];
}