Question may look so stupid, just got problem in some basics of objective C. I'm aware objective C only support pass by value however my requirement needs to pass address. I have a UIButton member variable (iVar) and I'm passing these to a function and trying to alloc init inside the function using parameters like below...
Function Call:
[self create_button : ivar_btn];
Definition:
- (void) create_button : (UIButton*) button
{
// Create button
button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button setTitle:#"00/00/0000" forState:UIControlStateNormal];
[self.add_scroll_view addSubview:button];
}
So without pass by reference in objective C, how do I handle this case?
Please correct me if I understood anything wrong.
NOTE: Create button is a common code, I have been using this to create buttons at run time depend on req.
Thanx
This is useless implementation and I have not tried it but still.
UIButton *ivar_btn = nil;
[self create_button : &ivar_btn];
- (void) create_button : (UIButton**) button
{
// Create button
*button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[*button setTitle:#"00/00/0000" forState:UIControlStateNormal];
[self.add_scroll_view addSubview:*button];
}
Try this....
- (void) create_button : (UIButton*) button
{
// Create button
UIButton *tmpButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
tmpButton = button;
[self.add_scroll_view addSubview:tmpButton];
}
I tried your code, it is working fine for me. just you missing one thing. Setting its frame.
Here is how I amend your code and works fine for me. Hope it will work for you as well.
UIButton *btn = [[UIButton alloc] init];
[self create_button:btn];
and Function/Method:
- (void) create_button : (UIButton*) button
{
// Create button
button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button setTitle:#"00/00/0000" forState:UIControlStateNormal];
[button setFrame:CGRectMake(0, 0, 100,100)];
[self.view addSubview:button];
}
works fine
Related
I have a method with multiple variables:
-(void) showImg:(UIBarButtonItem *)sender string1:(NSString *) string2:(NSString *);
I want to send NSString values (As this function is used for multiple elements).
This is how I add my action when no parameters are needed:
[myButton addTarget:self action:#selector(showImg) forControlEvents: UIControlEventTouchUpInside];
I tried adding parameters within the #selector like this:
[myButton performSelector #selector(showImg:string1:string2::) withObject:#"-1" withObject:#"-1"];
But this does not work. How may I call my function with multiple parameters directly inside the #selector?
You can make your UIButton call a function in between (like a middle man), to control the next functions parameters.
UIButton *myButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[myButton addTarget:self action:#selector(buttonTapped:) forControlEvents:UIControlEventTouchUpInside];
-(void) buttonTapped:(id)sender{
if(<some logical condition>){
[self showImg:sender string1:#"-1" string2:#"-1"];
}else {
[self showImg:sender string1:#"otherVal1" string2:#"otherVal2"];
}
}
-(void) showImg:(id)sender string1:(NSString *)string1 string2:(NSString*)string2 {
//Other logic
}
The following line is wrong :
[myButton performSelector #selector(showImg:string1:string2::) withObject:#"-1" withObject:#"-1"];
You can't pass parameters like this to the selector, that's why you have an error. I don't think you can pass multiple parameters to a selector. Maybe you can try to set a tag to your button with your const value (works with integers)
For example :
//Init your button......
[myButton setTag:1];
[myButton addTarget:self action:#selector(showImg:) forControlEvents: UIControlEventTouchUpInside];
- (void)showImg:(id)sender {
UIButton *btn = (UIButton *)sender;
int value = btn.tag;
}
Just a suggestion.. :)
I am adding a button in UIScrollView in StoryBoard
Below is the code i am using.
-(void)addScrollView
{
for(int i=0;i<[array count];i++)
{
UIScrollView *subScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 400, SUBSCROLLVIEW_WIDTH, SUBSCROLLVIEW_HEIGHT)];
UITextView *txtVwDetail = [[UITextView alloc] initWithFrame:CGRectMake(342, 0, TEXTVIEW_WIDTH, TEXTVIEW_HEIGHT)];
txtVwDetail.text = SAMPLE_STRING;
[self addSubScrollView:subScrollView];
[self.view addSubview:subScrollView];
[self.view addSubview:txtVwDetail];
}
}
-(void)addSubScrollView:(UIScrollView *)aSubScrollView
{
for(int i=0;i<[array count];i++)
{
UIButton *aButton = [UIButton buttonWithType:UIButtonTypeCustom];
aButton.frame = CGRectMake(intBtnX, (aSubScrollView.frame.size.height - 80)/2, 50, 80);
[aButton setImage:[UIImage imageNamed:[self.items objectAtIndex:i]] forState:UIControlStateNormal];
**[aButton addTarget:self action:#selector(btnSubImageClicked) forControlEvents:UIControlEventTouchUpInside];**
aSubScrollView.contentSize = CGSizeMake(intScrollViewWidth, aSubScrollView.frame.size.height);
[aSubScrollView addSubview:aButton];
}
}
In addSubScrollView method I have added Button and its click event which is getting crashed.
-(void)btnSubImageClicked
{
NSLog(#"btnSubImageClicked");
}
I am having scenario as
MyMainViewController is the sourceViewController for my created customSegue which is the UIStoryboardSegue class
MyMainViewController having a UIView as PlaceHolderView in which I am adding MydestinationViewContoller's View which is this Scrollview
-(void)perform
{
BrowseScreenVC *srcObj = (BrowseScreenVC *)[self sourceViewController];
UIViewController *dstObj = (UIViewController *)[self destinationViewController];
for(UIView *vw in srcObj.viewPlaceHolder.subviews)
{
[vw removeFromSuperview];
}
NSLog(#"dest : %#",dstObj.view);
NSLog(#"destobj :%#",dstObj);
srcObj.currentViewController = dstObj;
[srcObj.viewPlaceHolder addSubview:[dstObj.view retain]];
}
UPDATE
With answer I also have to change the line
srcObj.currentViewController = dstObj;
to
srcObj.addChildViewController = dstObj;
to make it working
you have to add target as follow:
[aButton addTarget:self action:#selector(btnSubImageClicked:) forControlEvents:UIControlEventTouchUpInside];
#selector(), within these braces you have to provide the method that you want to perform. the ":" represents that the method has some argument. In this case the argument would be the button itself that is calling the method.
You have to implement your method then its signature would look like this
- (void)btnSubImageClicked:(id)sender{
// sender would be the button that is calling the method. you can use this object according to your requirements if you want.
// your code
}
if you want to call this method from somewhere else as well you can call it by passing sender argument nil. e.g [self btnSubImageClicked:nil];
Your action needs to accept an (id) sender argument, even if you are not using it:
-(void)btnSubImageClicked:(id) sender
{
NSLog(#"btnSubImageClicked");
}
In the addSubScrollView:
[aButton addTarget:self action:#selector(btnSubImageClicked:) forControlEvents:UIControlEventTouchUpInside];
Button target should like
-(void) btnSubImageClicked:(id)sender{}
try this.
Updated:-
Please correct your code,change this line
[aButton addTarget:self action:#selector(btnSubImageClicked:) forControlEvents:UIControlEventTouchUpInside];
Now working i checked.
Instead of
UIButton *aButton = [UIButton buttonWithType:UIButtonTypeCustom];
write this,
UIButton *aButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
and for better practice always write this,
-(void) btnSubImageClicked:(id)sender{}
I'm trying to use dynamic buttons created via code (no IB) in my project and they appear where and how I want them but they don't fire their actions.
UIButton *button1 = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button1.frame = CGRectMake(475, 302, 49, 58);
[button1 setTitle:#"1"
forState:(UIControlState)UIControlStateNormal];
[button1 addTarget:self
action:#selector(goToFirstTrailer)
forControlEvents:(UIControlEvents)UIControlEventTouchDown];
[myImageView addSubview:button1];
-(void)goToFirstTrailer {
[self startAnimator:#"OutsideToTrailer1_" forNumFrames:60];
}
The imageView this is placed on has buttons and User Interaction Enabled On.
Any light you can shed would be much appreciated.
I think you have the wrong signature of the action method change that line to
-(void) goToFirstTrailer:(id)sender {
and where you set the action to
[button1 addTarget:self action:#selector(goToFirstTrailer:) forControlEvents:....
Important is the colon after the message name because I changed the action method signature to include the sender.
Edit I wrote a small sample project with just an imageView in the MainWindow.xib and created a button programmatically as follows
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
UIButton *button1 = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button1.frame = CGRectMake(0.f, 0.f, 50.f, 50.f);
[button1 setTitle:#"1"
forState:(UIControlState)UIControlStateNormal];
[button1 addTarget:self
action:#selector(goToFirstTrailer:)
forControlEvents:(UIControlEvents)UIControlEventTouchDown];
imageView.userInteractionEnabled = YES; // <--- this has to be set to YES
[imageView addSubview:button1];
[self.window makeKeyAndVisible];
return YES;
}
It is quick and dirty and yes, I am misusing the application delegate as the view controller. I know it is bad.
Here is the action method
- (void) goToFirstTrailer:(id)sender {
imageView.backgroundColor = [UIColor redColor];
}
Setting the userInteractionEnabled property on the parent imageView makes the difference. With it set to NO which is the default, no events are routed to the button.
If myImageView is a UIImageView object, adding a subview to it (like UIButton) only displays the image that object is represented by. If you add that UIButton as a subview of a UIView, it should work perfectly. Try adding an auxiliary UIView to your UIImageView and then add your button to a subview of the new auxiliary UIView, that should solve your problem.
This works fine for me. Note that I changed the event to UIControlEventTouchUpInside to allow the button press down state to be visible first.
UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
btn.frame = CGRectMake(20,400,88,35); //The position and size of the button (x,y,width,height)
[btn setTitle:#"Quit" forState:UIControlStateNormal];
[btn addTarget:self
action:#selector(showAbout)
forControlEvents:(UIControlEvents)UIControlEventTouchUpInside];
[self.view addSubview:btn];
I'm currently dynamically creating UIButton objects in my view.
I have an NSMutableArray containing information about them (id - label).
I then create my view objects by doing a for iteration on my MutableArray.
I'm trying to use this code on my buttons to catch touche events :
[myButton addTarget:self action:#selector(selectedButton:) forControlEvents:UIControlEventTouchUpInside];
My selectedButton method is called with success, but I don't have any idea on knowing with button were touched.
I tried to do this :
-(void)selectedButton:(id)sender {...}
But don't know what to do with the sender object.
Thanks in advance for your help !
At the top of your .m file, put something like this:
enum {
kButtonOne,
kButtonTwo
};
When you're creating your buttons, do this
myButton.tag = kButtonOne;
Then in your selected button method, do this:
-(void)selectedButton:(id)sender {
switch (sender.tag) {
case kButtonOne:
// do something here
break;
case kButtonTwo:
// do something else here
break;
}
}
Set mybutton.tag to something, and then check for that tag in selectedButton:sender.
-(void)viewDidLoad{
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button.frame = CGRectMake(80.0, 210.0, 40.0, 30.0);
button.tag=1;
[button addTarget:self
action:#selector(aMethod:)
forControlEvents:UIControlEventTouchDown];
[button setTitle:#"raaz" forState:UIControlStateNormal];
[self.view addSubview:button];
}
-(IBAction)aMethod:(id)sender{
UIButton *btn=(UIButton *)sender;
NSLog(#"I have currently Pressed button=%d",btn.tag);
}
I have taken customview in my code for UIButton.
UIButton *button= [[UIButton buttonWithType:UIButtonTypeRoundedRect] retain];
[button addTarget:self action:#selector(checkedimage:) forControlEvents:UIControlEventTouchUpInside];
-(IBAction)checkedimage:(id)sender
{
NSLog(#"checkedimage");
if(checkImage == NO)
{
newImage = [UIImage imageNamed:#"a.png"];
checkImage=YES;
}
else if(checkImage==YES)
{
newImage = [UIImage imageNamed:#"b.png"];
checkImage=NO;
}
}
but when i click on UIButton it is not going to action checkedimage
why?
You have not set it up correctly and not really given us enough information to help you.
Have you anywhere in your code created an IBOutlet with the type of UIButton and name of button? If you have done that have you in IB assign that IBOutlet to the correct UIButton?
If you have done that as well you really should not declare a NEW UIButton in the code with the same name. It should already exist as a property in the current class you are working in.
If you have not done any of the above you need to ADD your newly created button to a view somewhere for it to be visible at all.
I advise you to read some basic tutorials on how to use IB.
There is nothing wrong with the code you posted.
Have you added this button to the view? Using interface builder?
I ran this test code based on what you sent, all works just fine:
- (void)viewDidLoad {
[super viewDidLoad];
UIButton *button= [[UIButton buttonWithType:UIButtonTypeRoundedRect] retain];
[button addTarget:self action:#selector(checkedimage:) forControlEvents:UIControlEventTouchUpInside];
button.frame = CGRectMake(100, 100, 120, 20);
[self.view addSubview:button];
}
-(IBAction)checkedimage:(id)sender {
NSLog(#"checkedimage");
}