UIButton and selectors iOS - ios

I have a button constructor class and in that class i have this method to design my buttons
- (void)setupWithPosition:(CGPoint)point withImage:(UIImage *)image withImageFloat:(NSString *)imageFloat withTitle:(NSString *)title withLineWidth:(CGFloat)lineWidth respondsToSelector:(NSString*)selector
{
// create button
ButtonWithImage* button = [[ButtonWithImage alloc] initWithFrame:CGRectMake(0, 0, 200, 40)];
//[button setTitle:[title uppercaseString] forState:UIControlStateNormal];
[button setupViewWithText:title andImage:image andImageFloat:imageFloat];
[button addTarget:self
action:NSSelectorFromString(selector)
forControlEvents:UIControlEventTouchUpInside];
CGRect buttonFrame = button.frame;
CGFloat lineX = 0.0f;
// setup image
if ([[imageFloat lowercaseString] isEqualToString:#"right"]) {
lineX = buttonFrame.origin.x + buttonFrame.size.width;
} else {
lineX = 0.0f;
buttonFrame.origin.x = lineWidth;
button.frame = buttonFrame;
}
self.line = [[UIView alloc] initWithFrame:CGRectMake(lineX, buttonFrame.size.height/2, lineWidth, LINE_HEIGHT)];
self.line.backgroundColor = [UIColor lineNormalColor];
[self addSubview:self.line];
[self addSubview:button];
}
and i'm calling that using:
homepageButtons = [[NSMutableArray alloc] init];
CategoryButtonView* za = [[CategoryButtonView alloc] initWithFrame:CGRectMake(200, 250, 300, 46)];
[za setupWithPosition:CGPointMake(100, 100) withImage:[UIImage imageNamed:#"zas.png"] withImageFloat:#"right" withTitle:#"za" withLineWidth:80.0f respondsToSelector:#"buttonClicked"];
the buttons are placed correctly but when i click on them i get that error
CategoryButtonView buttonClicked]: unrecognized selector sent to instance 0xa1a46a0
2012-11-02 17:53:43.844 Man[3432:14c03] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[CategoryButtonView buttonClicked]: unrecognized selector sent to instance 0xa1a46a0'
i guess its a SEL problem how can i solve that?

You have this line:
[button addTarget:self
action:NSSelectorFromString(selector)
forControlEvents:UIControlEventTouchUpInside];
Do you really want 'self' here? This means that whatever selector you pass in must be a method in the CategoryButtonView class, not whatever class is used to create the CategoryButtonView.
Most likely you want to add a target parameter along with the selector parameter.

had to add that to make it work
NSString *temp = [NSString stringWithFormat:#"%#:",selector];
[button addTarget:sender
action:NSSelectorFromString(temp)
forControlEvents:UIControlEventTouchUpInside];

Related

iOS click on dynamic UIButton crashes

I'm creating programmatically a UIButton with an Image.
UIButton * bericht = [[UIButton alloc] initWithFrame:CGRectMake(tableView.bounds.size.width- height, 0, height, height)];
[bericht setBackgroundImage:[UIImage imageNamed:#"bericht.png"] forState:UIControlStateNormal];
[bericht addTarget:self action:#selector(imageClicked:) forControlEvents:UIControlEventTouchUpInside];
[cell.contentView addSubview:bericht];
- (void) imageClicked:(UIButton *) sender {
NSLog(#"test message");
}
When I click on this button I got the following error code:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason:
'-[__NSSetM goToFirstTrailer:]: unrecognized selector sent to instance 0x7fdaf1e73fe0'
Does anyone know a solution?
Change your selector method to imageClicked.
UIButton * bericht = [[UIButton alloc] initWithFrame:CGRectMake(tableView.bounds.size.width- height, 0, height, height)];
[bericht setBackgroundImage:[UIImage imageNamed:#"bericht.png"] forState:UIControlStateNormal];
[bericht addTarget:self action:#selector(imageClicked:) forControlEvents:UIControlEventTouchUpInside];
[cell.contentView addSubview:bericht];
- (void) imageClicked:(UIButton *) sender {
NSLog(#"iaksdkjas");
}

How to pass target parameter for UIButton?

I write one category method in UIView+Extensions.m:
#interface UIView (Extensions)
+ (UIView*)configureMoreViewWithBtns:(NSArray*)btnsConf;
#end
+ (UIView*)configureMoreViewWithBtns:(NSArray*)btnsConf
{
UIView* moreView = [[self alloc] initWithFrame:CGRectMake(195, 180, 120, 100)];
[moreView setBackgroundColor:[UIColor lightGrayColor]];
for (int i = 0; i < btns.count; i++) {
NSDictionary* confDict = btnsConf[i];
UIButton* btn = [[UIButton alloc] initWithFrame:CGRectMake(0, i*30 + 10, 120, 20)];
btn.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
[btn setTitle:confDict[#"title"] forState:UIControlStateNormal];
[btn addTarget:self
action:NSSelectorFromString(confDict[#"selector"]
forControlEvents:UIControlEventTouchUpInside];
[moreView addSubView:btn];
}
return moreView;
}
But this implement is wrong, because i don't know how pass target parameter from my ViewController?
In my viewController, i called this method like this:
- (void)handleMoreImageTapped:(UITapGestureRecognizer*)gestureRecognizer
{
NSLog(#"%s", __FUNCTION__);
UITableViewCell* tappedCell = [UIView tableViewCellFromTapGestture:gestureRecognizer];
NSArray* btnsConf = #[
#{#"title": #"分享", #"selector": NSStringFromSelector(#selector(handleShare:))},
#{#"title": #"私信", #"selector": NSStringFromSelector(#selector(handleSiXin:))},
#{#"title": #"举报或屏蔽", #"selector": NSStringFromSelector(#selector(handleJuBao:))}
];
UIView* moreView = [UIView configureMoreViewWithBtns:btnsConf];
}
You need to also pass the target (the object the selector would be called on, in this case the viewcontroller from which you call the configuremoreviewwithbtns method) in the dictionairies.
So a dictionairy you add to the array would become
#{#"title": #"thetitle", #"selector": NSStringFromSelector(#selector(theselector:)), #"target": self},
and you'd have to change the UIView extension to this:
[btn addTarget:confDict[#"target"]
action:NSSelectorFromString(confDict[#"selector"]
forControlEvents:UIControlEventTouchUpInside];

Creating UIButtons Programmatically - unrecognized selector sent to instance

Relevant code:
- (void) createButtons {
NSMutableArray *buttonTitleArray = [[NSMutableArray alloc] init];
[buttonTitleArray addObject:#"Website"];
[buttonTitleArray addObject:#"Blah"];
[buttonTitleArray addObject:#"Blah"];
int xPosition = 20;
for (int i = 0; i <= buttonTitleArray.count-1; i++) {
UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(xPosition, 25, 90, 40)];
button.userInteractionEnabled = TRUE;
[button setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[button setTitle:[buttonTitleArray objectAtIndex:i] forState:UIControlStateNormal];
button.backgroundColor = [UIColor colorWithRed:1 green:200.0/255.0 blue:0 alpha:1];
button.titleLabel.font = [UIFont systemFontOfSize:17];
[self.buttonArray addObject:button];
xPosition += 91;
}
for (UIButton *button in self.buttonArray) {
[button addTarget:self action:#selector(showWebsite:) forControlEvents:UIControlEventTouchDown];
[self.view addSubview:button];
}
}
- (void)showWebsite:(UIButton *)sender {
NSLog(#"Website");
}
In init:
NSMutableArray *tempArray = [[NSMutableArray alloc] init];
self.buttonArray = tempArray;
For testing purposes I made all the buttons have the same target.
When I click the button, I get unrecognized selector sent to instance.
Any thoughts here?
For some reason your self in your posted code gets released and the pointer location gets re-used by the OS as a UIGestureDelayedTouch.
Make sure the object that you are creating these buttons in does not get released by the OS before you want to use the showWebsite function.
Sometimes people use code like:
-(void)function
{
UIViewController *controller = [[UIViewController alloc] init];
[someOtherView addSubview:controller.view];
}
In this case at the end of the function the controller gets released (as there are no further references to it) and anything that could point to it in the future will point to an invalid (deallocated and possibly re-used) object.
UIButton does not retain objects set as targets, so the OS thinks the objects are valid for release if they are not retained by anything else in the program.

Button #selector not working if button defined in NSObject

I have the following problem: I am trying to define a button in an NSObject (in a separate file) and add it to my ViewController:
NSObject method:
in obj.h:
+(void)NewButtonInView:(UIView *)view withAction:(SEL)actionbutton;
in obj.m
+(void)NewButtonInView:(UIView *)view withAction:(SEL)actionbutton {
UIButton *button = [[UIButton alloc] init];
button.frame = CGRectMake(0, 0, 50, 50);
[button addTarget:self action:actionbutton forControlEvents:UIControlEventTouchUpInside];
}
in my ViewCotroller I import the obj.h and:
[obj NewButtonInView:[self view] withAction:#selector(actionB:)];
and:
-(void)actionB:(UIButton *)button {
//some code
}
The button looks fine but when I click it I get the following error:
"[obj actionB:]: unrecognized selector sent to class"
Any help is appreciated.
Thank you.
the problem is this line
[button addTarget:self action:actionbutton forControlEvents:UIControlEventTouchUpInside];
specifically, the use of self. You put the actionB: method in the viewController, but because the NewButtonInView:withAction: method is in a class method of obj self refers to the class obj. To fix it pass in the view controller as a parameter to the method like this
+(void)NewButtonInView:(UIView *)view withAction:(SEL)actionbutton target: (id) target {
UIButton *button = [[UIButton alloc] init];
button.frame = CGRectMake(0, 0, 50, 50);
[button addTarget: target action:actionbutton forControlEvents:UIControlEventTouchUpInside];
}
Try defining it with a return value, as follows:
+(UIButton *)NewButtonInView:(UIView *)view withAction:(SEL)actionbutton withTarget:(id)target{
UIButton *button = [[UIButton alloc] init];
button.frame = CGRectMake(0, 0, 50, 50);
[button addTarget:target action:actionbutton forControlEvents:UIControlEventTouchUpInside];
return button;
}
Then when you call it:
UIButton *button = [obj NewButtonInView:[self view] withAction:#selector(actionB:) withTarget:self];
Not sure why you're doing it in an NSObject instead of in your view controller, but that's the way to go about it if you do.

Can't pass UIButton image with viewWithTag

I don't understand why I'm getting "[UIScrollView imageView]: unrecognized selector sent to instance"
for (int i=0;i<[imagesForGame count];i++)
{
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake(i*310, 0, 310, 200);
[button setImageWithURL:[NSURL URLWithString:[imagesForGame objectAtIndex:i]] forState:UIControlStateNormal];
[button addTarget:self action:#selector(openFullPic:) forControlEvents:UIControlEventTouchUpInside];
[_myScroller addSubview:button];
}
-(void)openFullPic:(UIButton *)sender
{
UIButton *random = (UIButton *)[_myScroller viewWithTag:sender.tag];
UIImageView *test = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 300, 300)];
test.image = random.imageView.image; // <-- Error
...
}
The sender will be a button anyway, so use it instead.
-(void)openFullPic:(UIButton *)sender
{
UIButton *random = (UIButton *)sender;
UIImageView *test = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 300, 300)];
test.image = random.imageView.image; // <-- No more error.
...
}
Because you never set the tag for the button.
Do in the first loop, button.tag = i;
You have UIButtons instance in sender variable so you don't need to use viewWithTag at all ;-)

Resources