UIButton "addTarget" вылетает приложение - PullRequest
2 голосов
/ 08 января 2012

Просто учусь добавлять действия с кодом в мой файл .m, и моя первая попытка выдает исключение и вылетает из приложения.

Это скрипт аутентификации, который, я надеюсь, свяжется с моим веб-сервером.Вот соответствующий код (это все в файле .m, очень простой файл .h):

.h (заголовочный) файл:

#import <UIKit/UIKit.h>

@interface Login_ViewController : UIViewController <UITextFieldDelegate>

@end

.m (файл реализации):

- (void)viewDidLoad {
    UILabel *emailLabel = [[UILabel alloc] initWithFrame:CGRectMake(31.0f, 75.0f, 256.0f, 20.0f)];
    emailLabel.text = @"Email Address";
    emailLabel.backgroundColor = [UIColor grayColor];
    emailLabel.textColor = [UIColor whiteColor];
    UITextField *emailField = [[UITextField alloc] initWithFrame:CGRectMake(31.0f, 100.0f, 256.0f, 32.0f)];
    emailField.delegate = self;
    emailField.placeholder = @"Enter email address";
    emailField.borderStyle = UITextBorderStyleRoundedRect;
    [self.view addSubview:emailLabel];
    [self.view addSubview:emailField];
    UILabel *passLabel = [[UILabel alloc] initWithFrame:CGRectMake(31.0f, 175.0f, 256.0f, 20.0f)];
    passLabel.text = @"Password";
    passLabel.backgroundColor = [UIColor grayColor];
    passLabel.textColor = [UIColor whiteColor];
    UITextField *passField = [[UITextField alloc] initWithFrame:CGRectMake(31.0f, 200.0f, 256.0f, 32.0f)];
    passField.delegate = self;
    passField.placeholder = @"Enter Password";
    passField.borderStyle = UITextBorderStyleRoundedRect;
    passField.secureTextEntry = YES;
    UIButton *loginButton = [[UIButton alloc] initWithFrame:CGRectMake(31.0f, 275.0f, 256.0f, 32.0f)];
    [loginButton setTitle:@"Login" forState:UIControlStateNormal];
    [loginButton addTarget:self action:@selector(authenticate) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:passLabel];
    [self.view addSubview:passField];
    [self.view addSubview:loginButton];
    [self.view setBackgroundColor: [UIColor grayColor]];
    UIAlertView *noAccount = [[UIAlertView alloc] initWithTitle:@"Welcome to T-of-U" message:@"Please enter your TofU credentials." delegate:self cancelButtonTitle:@"continue" otherButtonTitles: nil];
    [noAccount show];
    [super viewDidLoad];
}

также в файле .m (IBAction для кнопки):

-(IBAction)authenticate:(id)sender{
    // This will be the validation code
    // if we validate we will set the default Setting with accountID here.
    UIAlertView *auth1 = [[UIAlertView alloc] initWithTitle:@"You clicked a button" message:@"Oh, do you want to login do you?" delegate:self cancelButtonTitle:@"Sure.. Why not!" otherButtonTitles: nil];
    [auth1 show];
}

Я использую раскадровку с представлением, имеющим собственный класс login_ViewController, и он загружаетсяуспешно на основе проверки локальной настройки для идентификатора учетной записи.Это окно открывается только в том случае, если они еще не вошли в систему, поэтому я могу аутентифицироваться и получить идентификатор этой учетной записи для локального хранения.Я все еще экспериментирую с программным созданием всех этих элементов, как вы можете видеть в разделе viewDidLoad.

Это сбой, потому что у меня нет ссылки на кнопку / IBAction в файле .h, или это нормально дляиспользовать метод addTarget, где все в файле .m?

Сбой информации из журнала:

2012-01-08 04:54:32.868 TofU-5[10452:10103] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Login_ViewController authenticate]: unrecognized selector sent to instance 0x6c94780'

1 Ответ

8 голосов
/ 08 января 2012

Ваше исправление может быть таким же простым, как:

[loginButton addTarget:self action:@selector(authenticate:) forControlEvents:UIControlEventTouchUpInside];

(добавьте КОЛОНА после authenticate имени в вашем @selector). Если метод принимает какой-либо параметр, после него будет двоеточие, и чтобы среда выполнения могла отправлять ему сообщение, это двоеточие необходимо включить в селектор цели действия.

Надеюсь, это имеет смысл и поможет вам!

p.s. не помешало бы добавить

-(IBAction)authenticate:(id)sender

в файл .h.

IBAction вот аббревиатура для InterfaceBuilder-Action, так что это на самом деле помогает гораздо больше, если вы строите интерфейс в файле XIB. Поскольку вы устанавливаете цель программно, вы можете просто использовать -(void) authenticate (без двоеточия, потому что ваш метод не использует или не нуждается в параметрах), но пока не делайте этого, пока не получите более общий опыт работы с кодированием Objective C и действиями.

...