Правильное выполнение делегата и протокола - PullRequest
3 голосов
/ 22 ноября 2010

Я создал этот тестовый пример как простой пример моей проблемы.

  • AppDelegate инициализирует TestViewController и добавляет его в окно
  • TestViewController инициализирует TestView и делает его представлением
  • TestView инициализирует TestSubView и добавляет его как подпредставление

Моя цель - предоставить TestSubView через делегата доступ к методам и переменным TestViewController. В этом примере TestSubView обращается к методам через touchesBegan или touchesMoved.

Пожалуйста, помогите. Спасибо.

РЕДАКТИРОВАТЬ: по-прежнему не работает, хотя ошибок больше нет. Что я сделал: переместил определение протокола в отдельный файл и импортировал его, сохранил для назначения и удалил объявление @protocol TestDelegate в начале заголовка.

Я думаю, что моя проблема в том, что я не назначаю делегата в TestViewController.m, если это проблема, как бы я это сделал?

TestViewController.h

#import <UIKit/UIKit.h>

@interface TestViewController : UIViewController <TestDelegate> {

    int number;
}

-(void)assignNumber:(int)value;
-(void)displayNumber;

@property int number;

@end

Перемещено в protocol.h и импортировано, где необходимо

@protocol TestDelegate

-(void)assignNumber:(int)value;
-(void)displayNumber;

@end

TestViewController.m

#import "TestViewController.h"
#import "TestView.h"

@implementation TestViewController

@synthesize number;

- (void)loadView {
    TestView *myView = [[TestView alloc] initWithFrame:CGRectMake(0,0,320,480)];
    self.view = myView;
    [myView release];
}

-(void)assignNumber:(int)value {
    NSLog(@"Number Assigned");
    number = value;
}

-(void)displayNumber {
    NSLog(@"%i",number);
}

TestSubView.h

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


@interface TestSubView : UIView {

    id<TestDelegate> delegate;
}

@property (nonatomic, retain) id<TestDelegate> delegate;

@end

TestSubView.m

#import "TestSubView.h"
#import "TestViewController.h"

@implementation TestSubView

@synthesize delegate;

- (id)initWithFrame:(CGRect)frame {
    if ((self = [super initWithFrame:frame])) {
        // Initialization code
        [self setBackgroundColor:[UIColor redColor]];
        [self setUserInteractionEnabled:YES];
    }
    return self;
}


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

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

    [self.delegate assignNumber:5];
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {

    [self.delegate displayNumber];  
}

Ответы [ 2 ]

0 голосов
/ 12 февраля 2012

Вы имеете в виду TestView, когда ваш класс называется TestSubView, если только у вас не определены 2 класса.

TestView *myView = [[TestView alloc] initWithFrame:CGRectMake(0,0,320,480)];

Вы правы, что выеще не назначил делегата.
Вы должны сделать это в следующей строке:

myView.delegate = self;

Чтобы закончить с этим:

- (void)loadView {
    TestSubView *myView = [[TestSubView alloc] initWithFrame:CGRectMake(0,0,320,480)];
    myView.delegate = self; // Set Delegate Here
    self.view = myView;
    [myView release];
}
0 голосов
/ 22 ноября 2010

Прежде всего, вы объявляете протокол, а затем назначаете тот же объект, что и для реализации этого протокола.Вероятно, вам нужно объявить протокол TestDelegate в TestSubView.Кроме того, при настройке свойства для делегата обязательно используйте ключевое слово assign, а не retain.

Наконец, все это можно значительно упростить с помощью UIGestureRecognizer.Вы можете настроить его в своем контроллере и добавить в свой testSubView.Таким образом, когда представление распознает, что соответствующий жест произошел в его пределах, на контроллер будет отправлено сообщение, позволяющее вам делать то, что вам нужно, например, присваивать или отображать номер.

...