2012-04-01 16 views
3

私は研究を行いましたが、次の問題に対する答えを見つけられませんでした:カスタム代理人 - UIViewのサブクラス - 何らかの理由でtouchesBeganが代理人の実装で動作していません。カスタムUIView代理人がtouchesBeganを検出しない

TestView.h

#import <UIKit/UIKit.h> 

@class TestView; 

@protocol TestViewDelegate <NSObject> 
@end 

@interface TestView : UIView 
@property (assign) id <TestViewDelegate> delegate; 
@end 

TestView.m

#import "TestView.h" 

@implementation TestView 

@synthesize delegate = _delegate; 

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { 
    NSLog(@"Touch detected on TestViewDelegate"); 
} 

@end 

ViewController.h

#import <UIKit/UIKit.h> 
#import "TestView.h" 

@interface ViewController : UIViewController<TestViewDelegate> 
@end 

ViewController.m

#import "ViewController.h" 

@interface ViewController() 
@end 

@implementation ViewController 

- (void)viewDidLoad 
{ 
[super viewDidLoad]; 

UILabel* title = [[UILabel alloc] initWithFrame:CGRectMake(20, 30, 280, 40)]; 
[title setFont:[UIFont fontWithName:@"Helvetica-Bold" size:30]]; 
[title setTextColor:[UIColor blackColor]]; 
[title setTextAlignment:UITextAlignmentCenter]; 
[title setBackgroundColor:[UIColor clearColor]]; 
[tile setText:@"Test"]; 
[self.view addSubview:title];  
} 

- (void)viewDidUnload 
{ 
[super viewDidUnload]; 
} 

@end 

タッチがViewController.mに発生したとき私はTestView.mからtouchesBeganを確認するために足りないのですが呼び出されますか?

+1

あなたは主要な部分を見逃していました。正しいものにするためにTestViewを作成して使用する必要があります。 – beryllium

+0

実装が間違っています。ドキュメントと例を確認してください – Legolas

答えて

8

最後の行は、ビューとビューコントローラの基本的な誤解を示しています。タッチはビューコントローラには発生しません。ビューにタッチが発生します。ビューがタッチされた後、ビューはタッチされたことをコントローラに通知し、コントローラはこの情報で何かを行います。それを行う方法は、委任と呼ばれるパターンを通してです。

だから、この作品をひとつずつ見てみましょう。

最初に:TestViewのインスタンスを作成し、それをビューコントローラーのビューのサブビューとして追加する必要があります。

ビューが存在し、それをタップすると、"Touch detected on TestViewDelegate"がコンソールに記録されます。しかし、実際にはデリゲートと何もしません(デリゲートはまだありません!)。

2番目:新しく作成されたTestViewdelegateプロパティをView Controllerに設定します。これは、TestViewインスタンスを作成した後で、ビュー階層に追加する前に行います。

これはちょっと魅力的ですが、ビューはその代理人と決して話していません(これは自動的には起こりません;デリゲートプロトコルを作成するときに、ビューが送信できるメッセージを指定する必要があります)。

第3:メソッドをTestViewDelegateプロトコルに追加し、そのメソッドをビューコントローラに実装します。これは、touchesBeganOnTestView:(TestView *)senderのようなものでも、それがタッチされたときにビューがデリゲートに伝えたいものでもかまいません。すなわち、このようになります:プロトコルの宣言がTestViewの宣言の前に来るので

@class TestView; 
@protocol TestViewDelegate <NSObject> 
- (void)touchesBeganOnTestView:(TestView *)sender; 
@end 

あなたが@class行を追加する必要があります - その時点でファイルに、コンパイラがどのような「TestView」の手段を知りません、警告を避けるために、「心配しないで、私は後でこれを宣言します。

第4回:TestViewtouchesBeganからそのメソッドを呼び出します。これは、行[self.delegate touchesBeganOnTestView:self];を追加するのと同じくらい簡単です。

あなたが望むものを手に入れることができます。あなたの質問から、私はあなたがiOS/Objective-Cをかなり新しくしていることを集めており、ファンダメンタルズをしっかり理解していないと難しいでしょう。始めるのに適した場所はApple's description of delegationです。

+0

私は本当に感謝します。そして、あなたはそれを正しく推測しました、私はiOS/Ocjectice-Cの新人です:) – James

+0

私はこのことをはじめて学んでいます。そして、この説明は私が見た中で最も良い/最も明白なものでした。どうもありがとうございます! – GangstaGraham

関連する問題