2012-04-01 78 views
3

我做了我的研究,但還沒有找到對以下問題的答案:我有一個自定義委託-subclass 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 

我缺少什麼,以確保從TestView.m touchesBegan當觸摸發生在ViewController.m被調用?

+1

您錯過了主要部分 - 您需要創建並使用TestView以使其正確 – beryllium 2012-04-01 20:50:32

+0

實現是錯誤的。請檢查文檔和示例 – Legolas 2012-04-01 20:51:54

回答

8

您的最後一行表示對視圖和視圖控制器的根本性誤解。在視圖控制器中不會發生觸摸;觸摸發生在視圖中。觸摸視圖後,它會告訴其控制器它已被觸摸,並且控制器會使用此信息做一些事情。它這樣做的方式是通過一種稱爲委派的模式。

所以讓我們一塊一塊地看看。爲了得到你想要的,你需要做以下事情:

首先:創建一個TestView的實例,並將其添加爲視圖控制器視圖的子視圖。

現在該視圖存在,並且當您點擊它時,您會看到登錄到控制檯的"Touch detected on TestViewDelegate"。但它實際上不會對委託做任何事情(甚至還沒有委託人!)。

其次:將新創建的TestViewdelegate屬性設置爲視圖控制器。在創建TestView實例之後但在將其添加到視圖層次結構之前執行此操作。

現在他們已經迷上了一些,但視圖永遠不會與其委託對話(這不會自動發生;當您創建委託協議時,您必須指定視圖能夠發送的消息)。

第三:將方法添加到TestViewDelegate協議並在視圖控制器中實現該方法。這可能類似於touchesBeganOnTestView:(TestView *)sender,或者您希望視圖在觸摸時告訴委託人的任何其他內容。這看起來是這樣的:

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

您必須添加@class線,因爲該協議聲明自帶的TestView聲明之前 - 在該文件中,在這一點上,編譯器不知道什麼叫「TestView」的意思,所以爲了避免警告你說:「別擔心,我會在稍後宣佈。」

第四:從TestViewtouchesBegan調用該方法。這與添加行[self.delegate touchesBeganOnTestView:self];一樣簡單。

這會讓你得到你想要的。從你的問題中我收集到你對iOS/Objective-C非常陌生,如果你對基礎知識沒有充分的理解,這將會很困難。一個好的開始可能是Apple's description of delegation

+0

感謝伊恩的清晰解釋,我非常感謝。你猜對了,我是iOS/Ocjectice-C的新手:) – James 2012-04-01 21:37:47

+0

我也是第一次學習這個東西。這個解釋是我見過的最好/最清晰的解釋。非常感謝! – GangstaGraham 2013-04-07 21:02:49