Пользовательский делегат UIView не обнаруживает прикосновения - PullRequest
3 голосов
/ 02 апреля 2012

Я провел исследование, но не нашел ответа на следующую проблему: у меня есть пользовательский делегат - подкласс 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

Чего мне не хватает, чтобы убедиться, что touchesBegan из TestView.m вызывается при касаниях в ViewController.m?

1 Ответ

8 голосов
/ 02 апреля 2012

Ваша последняя строка указывает на фундаментальное недопонимание представлений и контроллеров представлений. Прикосновения не происходят в контроллерах представления; прикосновения происходят во взглядах. После прикосновения к представлению оно сообщает контроллеру, что к нему прикоснулись, и контроллер что-то делает с этой информацией. Для этого он использует шаблон, называемый делегированием.

Итак, давайте пройдемся по этой части за частью. Чтобы получить то, что вы хотите, вам нужно будет сделать следующее:

Сначала: создайте экземпляр TestView и добавьте его как подпредставление представления контроллера представления.

Теперь представление существует, и когда вы нажмете на него, вы увидите, что ваш "Touch detected on TestViewDelegate" зарегистрирован в консоли. Но на самом деле он ничего не сделает с делегатом (еще нет делегата!).

Второе: установите вновь созданное свойство TestView delegate для контроллера представления. Сделайте это после создания экземпляра TestView, но до его добавления в иерархию представления.

Теперь они немного подключены, но представление никогда не общается со своим делегатом (это не происходит автоматически; когда вы создаете протокол делегата, вы должны указать, какие сообщения представление сможет отправлять). .

Третье: добавить метод к протоколу TestViewDelegate и реализовать этот метод в контроллере представления. Это может быть что-то вроде touchesBeganOnTestView:(TestView *)sender, или что-то еще, что вы хотите, чтобы представление сообщало делегату, когда оно коснулось. Это выглядит так:

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

Вы должны добавить строку @class, потому что объявление протокола предшествует объявлению TestView - в этот момент в файле компилятор не знает, что означает "TestView", поэтому, чтобы избежать предупреждение, которое вы говорите: «Не волнуйтесь, я собираюсь объявить об этом позже».

Четвертый: вызовите этот метод из TestView touchesBegan. Это так же просто, как добавление строки [self.delegate touchesBeganOnTestView:self];.

Это даст вам то, что вы хотите. Из вашего вопроса я понимаю, что вы довольно плохо знакомы с iOS / Objective-C, и это будет сложно, если у вас нет четкого понимания основ. Хорошее место для начала может быть Описание Apple делегирования .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...