OutOfBoundsException
OutOfBoundsException

Reputation: 766

Programmatically created button doesn't response to user's click

I know that this kind of issue discussed several times here but, I have already searched and tried without success. I am trying to create a simple login view on the top of general menu. This login page contains 2 textfields(username & password) and 1 button(login). My problem is that while everything appears perfectly when I click on Login button, is not responding.

*The login view animated from start to end point using moveTo method. Comment that part but still not responding.

Main.m

- (void)viewDidLoad
{

    prefs = [NSUserDefaults standardUserDefaults];

    if (![prefs objectForKey:@"userName"]) {
        LoginScreen *login = [[LoginScreen alloc] initWithFrame:CGRectMake(35, 400, 250, 350)];
        [self.view addSubview:login];
        [login moveTo:CGPointMake(35.0, 65.0) duration:0.6 option:UIViewAnimationOptionCurveEaseOut];  
    }        

    [super viewDidLoad];
}

LoginScreen.m

@synthesize login;

    - (id)initWithFrame:(CGRect)frame
    {
         self = [super initWithFrame:frame];
         if (self) {

             self.layer.masksToBounds = YES;
             self.userInteractionEnabled = YES;

             [self addButton:login withTitle:@"Login" andSize:CGRectMake(85, 200, 90, 35)];
             [login addTarget:self action:@selector(attemptLogin)
                   forControlEvents:UIControlEventTouchUpInside];

         }

         return self;
    }

        - (void) addButton: (UIButton*) button withTitle: (NSString*) title andSize: (CGRect) size{

            button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
            button.frame = size;
            [button setTitle:title forState:UIControlStateNormal];
            button.userInteractionEnabled = YES;
            [self addSubview:button];
        }


        - (void)attemptLogin{

            NSString *user = usernameTxt.text;
            NSString *pass = passwordTxt.text;
            NSString *url = [[NSString alloc] initWithFormat:@"http://domain.com/login.php?username=%@&password=%@", user, pass];

            NSLog(@"%@", url);

        }

Nothing print on screen.

Thanks in advance

Upvotes: 2

Views: 1485

Answers (3)

perrohunter
perrohunter

Reputation: 3526

The problem is mainly you are allocting a new button, therefore not working with your login button, I commented the allocation on your code and this should work:

//Old version of code removed, please check edit

Edit

  - (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {

        self.layer.masksToBounds = YES;
        self.userInteractionEnabled = YES;

        login = [self addButtonWithTitle:@"Login" andSize:CGRectMake(85, 200, 90, 35)];
        [login addTarget:self action:@selector(attemptLogin)
        forControlEvents:UIControlEventTouchUpInside];

    }

    return self;
}

- (UIButton) addButtonWithTitle: (NSString*) title andSize: (CGRect) size{

    button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    button.frame = size;
    [button setTitle:title forState:UIControlStateNormal];
    button.userInteractionEnabled = YES;
    [self addSubview:button];
    return button;
}


- (void)attemptLogin{

    NSString *user = usernameTxt.text;
    NSString *pass = passwordTxt.text;
    NSString *url = [[NSString alloc] initWithFormat:@"http://domain.com/login.php?username=%@&password=%@", user, pass];

    NSLog(@"%@", url);

}

Upvotes: 2

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726579

This is because you created a button without specifying what selector to call when the button is clicked. Adding this line to your addButton method will fix the problem:

[button addTarget:self action:@selector(attemptLogin) forControlEvents:UIControlEventTouchUpInside];

When you try doing the same through the synthesized login property, the code does not work, because you never set login. When you pass it to the addButton function, the value gets ignored (you re-assign it right away). The assignment never changes the value of login, though, because Objective C passes parameters by value.

An alternative way to fix your code is to pass a pointer to login, rather than login itself, like this:

- (void) addButton: (UIButton**) button withTitle: (NSString*) title andSize: (CGRect) size {
    *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    (*button).frame = size;
    [*button setTitle:title forState:UIControlStateNormal];
    (*button).userInteractionEnabled = YES;
    [self addSubview:*button];
}

I would recommend against this way of fixing your code: using login directly inside addButton would probably be a better choice.

Upvotes: 2

sergio
sergio

Reputation: 69027

I think that you meant:

- (void) addButton: (UIButton*) button withTitle: (NSString*) title andSize: (CGRect) size{

    button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    button.frame = size;
    [button setTitle:title forState:UIControlStateNormal];
    button.userInteractionEnabled = YES;
     [button addTarget:self action:@selector(attemptLogin)
           forControlEvents:UIControlEventTouchUpInside];
    [self addSubview:button];
}

You should also remove that:

     [login addTarget:self action:@selector(attemptLogin)
           forControlEvents:UIControlEventTouchUpInside];

from the init method.

Upvotes: 1

Related Questions