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

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

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);
}

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.

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.

Related

Adding multiple UIButtons to an UIView with a selector action

I've added some buttons to an UIView (via addSubview) programmatically. I’ve added to this button an #selector with a function. However, they appear in the view but when I do click, the last button works only.
Into my .h:
#property (nonatomic, strong) UIButton * myButton;
Into my .m
for(int i=0;i<5;i++){
myButton = [UIButton buttonWithType: UIButtonTypeRoundedRect];
myButton.frame = CGRectMake(55, 55*i, 30, 30);
myButton.tag = i;
myButton.backgroundColor = [UIColor redColor];
[myButton addTarget:self action:#selector(myaction:) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:myButton];
}
-(void)myaction:(UIButton *)sender{
if(sender.tag == 0){
NSLog(#“uibutton clicked %ld", (long)sender.tag);
}
}
How do I add the action to all buttons? not for the last only...
This works fine:
- (void)viewDidLoad {
[super viewDidLoad];
for(int i=0;i<5;i++){
UIButton *myButton = [UIButton buttonWithType: UIButtonTypeRoundedRect];
myButton.frame = CGRectMake(55, 55*i, 30, 30);
myButton.tag = i;
myButton.backgroundColor = [UIColor redColor];
[myButton setTitle:[NSString stringWithFormat:#"%ld", (long)i] forState:UIControlStateNormal];
[myButton addTarget:self action:#selector(myaction:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:myButton];
}
}
-(void)myaction:(UIButton *)sender{
NSLog(#"uibutton clicked %ld", (long)sender.tag);
}
The code you posted in your question appears to be "this is what my code looks like" rather than your actual code. That can cause problems when people try to help.
In the future, post your actual code.
Let's make it more dynamic by calculating the height of the button and adding padding based on the number of buttons.
:
-(void)viewDidLoad {
[super viewDidLoad];
NSInteger height = self.frame.size.height - 5*20; // 5 is the button count
and 20 is the padding
NSInteger buttonHeight = height/5;
for(int i=0;i<5;i++){
UIButton *myButton = [UIButton buttonWithType: UIButtonTypeRoundedRect];
myButton.frame = CGRectMake(55, buttonHeight*i+padding*(i+1), 150,
buttonHeight);
myButton.tag = i;
myButton.backgroundColor = [UIColor redColor];
[myButton setTitle:[NSString stringWithFormat:#"%ld", (long)i]
forState:UIControlStateNormal];
[myButton addTarget:self action:#selector(myaction:)
forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:myButton];
}}
-(void)myaction:(UIButton *)sender{
NSLog(#"uibutton clicked %ld", (long)sender.tag);
}
You could make it more dynamic by calculating the height of the button like this:
NSInteger height = self.frame.size.height - 5*20;
NSInteger buttonHeight = height/5;

Clicking on username and going to profile

I am using Parse as my back end and have a home view where all user's photos will go, kind of like a stream, each cell has a header with the user's username where you can click it and go to their profile. However I can't figure out how to access the user's information and bring it to the next view.. This is my code so far.
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
static NSString *headerIdentifier = #"headerIdentifier";
UITableViewHeaderFooterView *headerView = [tableView dequeueReusableHeaderFooterViewWithIdentifier:headerIdentifier];
if (headerView == nil) {
headerView = [[UITableViewHeaderFooterView alloc] initWithFrame:CGRectMake( 0.0f, 0.0f, self.view.bounds.size.width, 44.0f)];
//Container to hold everything.
self.containerView = [[UIView alloc] initWithFrame:CGRectMake( 0.0f, 0.0f, self.view.bounds.size.width, 44)];
self.containerView.backgroundColor = [UIColor clearColor];
[headerView.contentView addSubview:containerView];
UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
[button addTarget:self
action:#selector(viewProfile: user:)
forControlEvents:UIControlEventTouchUpInside];
[button setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
button.frame = CGRectMake(8, 6, 100, 30);
//Setting the username to button.
PFObject *owner = [self.userPhotos objectAtIndex:section];
PFUser *user = [owner objectForKey:#"user"];
[user fetch];
self.usernameHolder = user.username;
[button setTitle:self.usernameHolder forState:UIControlStateNormal];
[containerView addSubview:button];
}
return headerView;
}
- (void)viewProfile:(UIButton *)button user:(PFUser *)user {
AccountView *accountView = [[AccountView alloc] init];
[accountView setUser:user];
[self.navigationController pushViewController:accountView animated:YES];
}
When I do an NSLog on the accountView it comes back as null and am very confused!
I think one issue is that the button isn't passing anything in the user parameter to the -viewProfile:user method.
As much as I hate using "magic numbers" for this sort of thing, what you probably need to do is use the .tag property on the button as an index to then lookup the user via the userPhotos. So...
Add in -tableView:viewForHeaderInSection:
button.tag = section
Change
[button addTarget:self action:#selector(viewProfile: user:) forControlEvents:UIControlEventTouchUpInside];
to
[button addTarget:self action:#selector(viewProfile:) forControlEvents:UIControlEventTouchUpInside];
And replace your -viewProfile:user: method with
- (void)viewProfile:(UIButton *)button {
AccountView *accountView = [[AccountView alloc] init];
PFObject *owner = [self.userPhotos objectAtIndex:button.tag];
PFUser *user = [owner objectForKey:#"user"];
[accountView setUser:user];
[self.navigationController pushViewController:accountView animated:YES];
}
You may or may not need to fetch the user again - I'm not sure if the Parse SDK will update the user in userPhotos when you fetch it. You could also avoid the fetch altogether if you .includeKey("user") on your query to get the userPhotos.

UIButton image does not show in Navigation Bar

I am trying to a slide menu. The only problem is that the image for the UIButton does not show at runtime. This is the code I have written.
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
}
-(NSString *)segueIdentifierForIndexPathInLeftMenu:(NSIndexPath *)indexPath
{
NSString *identifier;
switch (indexPath.row) {
case 0:
identifier=#"firstSegue";
break;
case 1:
identifier=#"secondSegue";
break;
}
return identifier;
}
-(void)configureLeftMenuButton:(UIButton *)button
{
CGRect frame = button.frame;
frame.origin=(CGPoint){0.0};
frame.size = (CGSize){40.40};
button.frame = frame;
[button setImage:[UIImage imageNamed:#"icon-menu"] forState:UIControlStateNormal];
}
I suppose you are using navigation controller. If so, implementation could look like:
- (void)viewDidLoad
{
[super viewDidLoad];
[self configureLeftMenuButton];
}
-(void)configureLeftMenuButton
{
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setImage:[UIImage imageNamed:#"icon-menu"] forState:UIControlStateNormal];
button.frame = CGRectMake(0.0f, 0.0f, 44.0f, 44.0f);
[button addTarget:self
action:#selector(yourAction:)
forControlEvents:UIControlStateNormal];
UIBarButtonItem *menuItem = [[UIBarButtonItem alloc] initWithCustomView:button];
self.navigationItem.leftBarButtonItem = menuItem;
}

UIButton not showing up in UIViewController

I have set up my button as so:
CGRect button1Frame = CGRectMake(200, 200, 100, 100);
self.button1 = [[UIButton alloc] initWithFrame:button1Frame];
[self.button1 addTarget:self action:#selector(goToController1:)
forControlEvents:UIControlEventTouchDown];
self.button1.userInteractionEnabled = YES;
self.button1.opaque = YES;
self.button1.backgroundColor = [UIColor redColor];
[self.button1 setTitle:#"B1" forState:UIControlStateNormal];
[self.view addSubview:self.button1];
with my sender:
- (void) goToController1:(id)sender {
NSLog(#"Pressed");
}
and my view controller has been initialized properly.
What would cause my button not to show up? I have checked to make sure everything is being called properly.
You could try this:
button = [UIButton buttonWithType: UIButtonTypeSystem];
And then set the frame like this:
button.frame = CGRectMake(0,0,20,20);
The UIButton buttonWithType: method fixed my problem at one point. Not sure if it will make a difference in this case though. Just something to try.

How to get index of uiimage subview of uiscrollview

I need to detect selected image of uiimage which is placed inside scrollview.
My code is here:
int newscrollviewY = 40;
for(int i = 0; i<1; i++)
{
scrollView = [[UIScrollView alloc]initWithFrame:CGRectMake(5, newscrollviewY, 310, 100)];
scrollView.showsVerticalScrollIndicator = YES;
scrollView.scrollEnabled = YES;
scrollView.userInteractionEnabled = YES;
scrollView.backgroundColor = [UIColor clearColor];
scrollView.delegate=self;
int imgx = 1;
for(int img=0; img<[images count]; img++)
{
UIImageView *imageView1 = [[UIImageView alloc]initWithFrame:CGRectMake(imgx,0,100,100)];
imageView1.backgroundColor = [UIColor whiteColor];
imageView1.image = [images objectAtIndex:img];
imageView1.contentMode = UIViewContentModeScaleAspectFit;
[imageView1 setNeedsDisplay];
[imageView1 setUserInteractionEnabled:YES];
[imageView1 setMultipleTouchEnabled:YES];
[scrollView addSubview:imageView1];
imageButton = [UIButton buttonWithType:UIButtonTypeCustom];
imageButton.frame = CGRectMake(imgx,0,100,100);
[imageButton addTarget:self action:#selector(buttonClicked) forControlEvents:UIControlEventTouchUpInside];
imageButton.tag = img;
[scrollView addSubview:imageButton];
imgx = imgx + 103;
}
Please help to detect selected image using imageButton or something else.
Replace your selector with buttonClicked:
be Sure that you are adding ":" after selector method. follow or replace the code below:
[imageButton addTarget:self action:#selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
then Add the selector definantion in .m file
- (void) buttonClicked: (id) sender
{
// here you can get the tag of button.
NSInteger tag = ((UIButton *)sender).tag;
// do your implementation after this
}
Hope this will solve your issue. Enjoy Coding..!!
They way you have set it up the tag of the 'button' is already the number of the image in your array of images. So all you need to do is get the tag from the 'button'.
Make sure the button clicked function retrieves the tag from the sender(id) that you receive.
For example a bit like this:
- (IBAction)buttonClicked:(id)sender {
UIButton *button = (UIButton *)sender;
UIImage selectedImages = [images objectForKey: [button tag]];
}
As par you question if you are using UIImageview you have to use UITapGestureRecognizer that same like Button. you just need to add UITapGestureRecognizer like:-
for(int img=0; img<[images count]; img++)
{
UIImageView *imageView1 = [[UIImageView alloc]initWithFrame:CGRectMake(imgx,0,100,100)];
imageView1.backgroundColor = [UIColor whiteColor];
UITapGestureRecognizer *frameTapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(frameTapGesture:)];
frameTapGesture.numberOfTapsRequired=1;
imageView1.image = [images objectAtIndex:img];
imageView1.contentMode = UIViewContentModeScaleAspectFit;
[imageView1 setNeedsDisplay];
[imageView1 setUserInteractionEnabled:YES];
[imageView1 setMultipleTouchEnabled:YES];
imageView1.tag=img;
[_imgView addGestureRecognizer:frameTapGesture];
[scrollView addSubview:imageView1];
}.
- (void)frameTapGesture:(UITapGestureRecognizer*)sender
{
UIView *view = sender.view; //cast pointer to the derived class if needed
NSLog(#"%d", view.tag);
}
Reduce your code There are No need to add Button with same Frame of ImageView For getting Click Event or you can also set Image of UIButton for you want to like use UIBUtton then remove UIImageview Code else you simply use UITapGestureRecognizer with getting click event using - (void)frameTapGesture:(UITapGestureRecognizer*)sender
Please try this code
for(int img=0; img<[images count]; img++)
{
imageButton = [UIButton buttonWithType:UIButtonTypeCustom];
[imageButton setImage:[UIImage imageNamed:[images objectAtIndex:i]] forState:UIControlStateNormal];
imageButton.frame = CGRectMake(imgx,0,100,100);
[imageButton addTarget:self action:#selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
imageButton.tag = img;
[scrollView addSubview:imageButton];
imgx = imgx + 103;
}
- (void) buttonClicked: (id) sender
{
UIButton *button = (UIButton *)sender;
UIImage selectedImage = button.currentImage;
}
set button target
[button addTarget:self action:#selector(buttonAction:) forControlEvents:UIControlEventTouchUpInside];
// get Button Action
-(void) buttonAction:(UIButton *)sender
{
NSLog(#"%dl",sender.tag);
// do your implementation after this
}

Resources