How do I add a method to a button I made programmatically? - objective-c

I'm working with a pre-existing xcode project for an iPhone app that retrieves flickr pictures. I want to add a favorite button so that a user can add a photo to an array of favorites, but I'm stumped because I've never made UI objects programmatically before.
Here is the code for my button, but how would I add a method do it? Also, where would this method definition go?
// Create favorites button
UIButton *favButton = [[UIButton buttonWithType:UIButtonTypeRoundedRect] retain];
favButton.frame = CGRectMake(200, 50, 100, 50);
[favButton setTitle:#"Favorite" forState:UIControlStateNormal];
favButton.backgroundColor = [UIColor clearColor];
[favButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal ];
UIImage *buttonImageNormal = [UIImage imageNamed:#"blueButton.png"];
UIImage *strechableButtonImageNormal = [buttonImageNormal stretchableImageWithLeftCapWidth:12 topCapHeight:0];
[favButton setBackgroundImage:strechableButtonImageNormal forState:UIControlStateNormal];
UIImage *buttonImagePressed = [UIImage imageNamed:#"whiteButton.png"];
UIImage *strechableButtonImagePressed = [buttonImagePressed stretchableImageWithLeftCapWidth:12 topCapHeight:0];
[favButton setBackgroundImage:strechableButtonImagePressed forState:UIControlStateHighlighted];
[favButton addTarget:self action:#selector(playAction:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:favButton];
Is the addTarget method the way to add a method? Because whenever I click the button, it sends me back to xcode and shows me the main.m file and highlights this line of code:
int retVal = UIApplicationMain(argc, argv, nil, nil);
Sorry, I'm totally new to this. The project has the following files:
JSONFlickrAppDelegate.h
JSONFlickrAppDelege.m
JSONFlickrViewController.h
JSONFlickrViewController.m
ZoomedImageView.h
ZoomedImageView.m
Here is the xcode project that I am working off of:
http://compsci.cis.uncw.edu/~pattersone/courses/275/resources/JSONFlickrPart3.zip

Yes, this is the method that adds the method:
[favButton addTarget:self action:#selector(playAction:) forControlEvents:UIControlEventTouchUpInside];
The method, however, that will be called is playAction:. Whatever is located after addTarget is simply the object that will call the method, in the case of self, it is the object where this button is being created that it rests inside.

Looks like there are some confusions with how you need to add a target to a method.
Is the addTarget method the way to add a method?
Yes, you are correct. addTarget method is the way to add a method associated with the button and the method definition should be written on the class which is mentioned as addTarget param(In this case self, which is an object of current class).
When you use this line,
[favButton addTarget:self action:#selector(playAction:) forControlEvents:UIControlEventTouchUpInside];
It means that you are adding a method named playAction: to button which should be executed in target self on the event of UIControlEventTouchUpInside i.e, when an event occurs as user taps inside the button. So the action playAction should be inside the class which is represented by the object self i.e, the class in which you have written the above [favButton addTarget:... line. You can add any number of targets to this same button using similar addTarget lines.
but how would I add a method do it? Also, where would this method
definition go?
In this scenario, you need to define the method playAction: in the same class since you added target as self. This can be changed to any object of any class and the method can be written in that class.
for eg:-
- (void)playAction:(id)button {
//write the required code here, button is same as the favbutton which is written above.
}
Because whenever I click the button, it sends me back to xcode and shows me the main.m
file and highlights this line of code:
The reason why it is going back to xcode and shows the main.m is because it is a crashing since you haven't provided any playAction: method in your class. Since it cannot find any such method in the target self, it will crash and sometimes it just point to the main.m class.
You can also add target as follows,
[favButton addTarget:self action:#selector(playAction) forControlEvents:UIControlEventTouchUpInside];//notice that it is 'playAction' and not 'playAction:' with a colon at the end.
In this case your method will look like,
- (void)playAction {
//write the required code here
}
These are just different ways to do this.
For more details, please check this apple documentation.

Related

UIButton added to subview in separate class where to store the method

In a program, I have a class called PullLeftMenu.h/.m.
In ViewController.m I am calling the PullLeftMenu like so:
PullLeftMenu *openMenu = [[PullLeftMenu alloc] init];
[openMenu classMethodHere];
So, simply runs a method with arguments. However, a part of this method of class PullLeftMenu is adding buttons to a subview that appears. Each button is assigned its own method to be called. Say for examples sake, button 1 calls method btnUsefulStuff.
I have put btnUsefulStuff method code in both the PullLeftMenu class and in the ViewController.m, and neither are being triggered - instead causing a memory crash.
Code for a button in PullLeftMenu.m
UIButton *btnUsefulStuff = [UIButton buttonWithType:UIButtonTypeRoundedRect];
btnUsefulStuff.frame = CGRectMake(10.0, 180.0, 160.0, 10.0);
[btnUsefulStuff setTitle:#"Useful Stuff" forState:UIControlStateNormal];
[btnUsefulStuff addTarget:self action:#selector(btnUsefulStuff) forControlEvents:UIControlEventTouchUpInside];
btnUsefulStuff.titleLabel.font = [UIFont fontWithName:#"KhmerUI" size:16];
btnUsefulStuff.titleLabel.textColor = [UIColor colorWithHexString:#"3a589b"];
[secondView addSubview:btnUsefulStuff];
And below this is the method:
-(void)btnUsefulStuff{
NSLog(#"button");
}
Problem is, I dont know where to place the method -(void)btnUsefulStuff as wherever I place it, it doesnt seem to get triggered and the app crashes with a memory warning. Error is:
Thread 1: EXC_BAD_ACCESS
Since this line [btnUsefulStuff addTarget:self action:#selector(btnUsefulStuff) forControlEvents:UIControlEventTouchUpInside]; is in PullLeftMenu and you're saying the target is self, that's where your method needs to be.
I suspect your problem is that you've made openMenu a local variable. Change it to a strong property inside ViewController so that it's still in memory when someone taps the button.

How to add an action to a UIButton

I've been searching online for this answer, and every single post skips over the part of where to actually write the code for an action. I have a simple Interactive UIButton. And If i could just see a template of code that says "\write code for action here", that would be super helpful!!! ( it's for iPad IOS7 )
This is as far as I can get...
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button addTarget:self
action:#selector(aMethod:)forControlEvents:UIControlEventTouchDown];
[button setTitle:#"Show View" forState:UIControlStateNormal];
button.frame = CGRectMake(80.0, 210.0, 160.0, 40.0);
[view addSubview:button];
I think I understand that this is how to set up a potential action, but where do I write the actual code for the action itself?
I want to kind of expand more on what was answered here already, Both responses are correct but i want to explain why/how this all works.
[button addTarget:self
action:#selector(aMethod:)forControlEvents:UIControlEventTouchDown];
The first thing to look at; The target.
The target is the instance of a class, any class. The only requirement for this class is that it has to implement the action.
action is the method you wish to invoke when the user presses the button.
#selector(aMethod:) Basically think of this as a method signature. Because Objective-c is a dynamic language, aMethod: does not need to exist, but will crash your program if it does not.
So if we put this all together, Whenever I want to press this button:
The system will invoke the action method, on the target instance.
and for the method itself, it can look like this
- (void) aMethod:(id)sender { }
You would put the action related code in a method, in that class, named aMethod:
- (void)aMethod:(id)sender {
// your code for the action goes here
}
You perhaps might also want to use UIControlEventTouchUpInside for the control event.
Since you've set the target as self, the aMethod: method should be added to the same class.
- (IBAction)aMethod:(id)sender
{
// do something here
}

Trying to add UIButton on top of vrf-reader ContentView

I am trying to insert some buttons in the PDF page rendered by the open source iOs reader vfr-reader https://github.com/vfr/Reader
Basically this is the code I am trying to implement in the initWithFrame method of ReaderContentView:
if (theContentView != nil) // Must have a valid and initialized content view
{
UIButton *myButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[myButton setFrame:CGRectMake(269, 262, 100, 100)];
[myButton addTarget:self action:#selector(links) forControlEvents:UIControlEventTouchUpInside];
[myButton setTitle:#"asdasd" forState:UIControlStateNormal];
[theContentView addSubview:myButton];
The button doesn't work, and I can see that it is rendered and flattened in some way so it doesn't seem to be a button anymore as you can see here at full zoom.
However running DCInspector, despite warning that
2013-05-24 12:27:34.560 Reader[45333:c07] DCIntrospect: *** WARNING: One or more values of this view's frame are non-integer values. This view will likely look blurry. ***
seems to identify the button properly when inspected.
To test this case, just download the reader project and put my code in ReaderContentView at line 113. I am pretty sure I am doing something totally wrong. Thank you for help!
it was a bit tricky but I discovered that userInteractionEnabled was not set properly on the container view. I should have supposed that :)

How to move an image with a button?

I have an image(clubcow.png) that is passed from an nsarray string to make a picture. Then facedowncow represents the picture. I was wondering how to make a button that will move facedowncow to position (100,100) when button is tapped. Any tips will be appreciated. Also, there is more to this code, I just posted the important parts to give an idea on what is going on.
cardKeys = [[NSArray alloc] initWithObjects:#"clubcow", nil];
currentName = [NSMutableString stringWithFormat:#"%#.png", [cowsShuffled objectAtIndex:currentcow]];
faceDowncow = (UIImageView *)[self.view viewWithTag:1];
faceDowncow.userInteractionEnabled = YES;
I would start by creating a UIButton and adding it to your view controller's view.
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button.frame = CGRectMake(0, 0, 100, 20);
[button setTitle:#"Tap Me" forState:UIControlStateNormal];
[button addTarget:self action:#selector(animateImage:)
forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:button];
Then, link this button to a function that will animate your faceDowncow object. You could add your faceDowncow as a property of the view controller so the following function can easily reference it:
- (void)animateImage:(UIButton *)sender {
[UIView animateWithDuration:0.2
animations:^{
// change origin of frame
faceDowncow.frame = CGRectMake(100, 100, faceDowncow.frame.size.width, faceDowncow.frame.size.height);
} completion:^(BOOL finished){
// do something after animation
}];
}
First of all, it looks like this code is from a view controller subclass, and the cow is a subview. In that case, you should probably have a property for it rather than obtaining it by its tag all the time. If it's instantiated in a storyboard scene/nib then you can hook up an outlet to a property/ivar in your subclass fairly easily.
The easiest way to do what you want is to create the button and use target action so that when it is tapped, it calls a method in your view controller. In the method body, obtain a reference to your cow and set it's frame property, like so:
[faceDowncow setFrame: CGRectMake(100,100,faceDowncow.bounds.size.width,faceDowncow.bounds.size.height)];
If you don't know how target action works, I suggest reading Apple's documentation on the matter. It's as simple as getting a button, calling one method to tell it what events should make a certain method get called, and then implementing that method.

Creating/Displaying Interface Objects with Code for the iPhone [Objective-C]

I'm currently designing an app that calls for dynamically creating objects and then displaying them in a ViewController. My problem is wading through the documentation to try and create the objects I need. I've done some searching and even tried to just sit down and figure it out, but alas, I've got nothing to show for it. I already know how to dynamically create the ViewController but I can't seem to get any objects in it.
Does anyone know how I could go about creating objects (Say a button and a slider) dynamically with Objective-C in XCode?
Creating a button in code is simple
- (void)addButton {
// Create button
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
// Set the frame (location and size)
[button setFrame:CGRectMake(0, 0, 40, 30)];
// Set what happens when you touch the button
[button addTarget:self action:#selector(buttonPressed) forControlEvents:UIControlEventTouchUpInside];
// Set button text
[button.titleLabel setText:#"Button"];
// Add button to view
[self.view addSubview:button];
}
A lot of interface elements follow a similar patter- alloc and init the object, set the frame and add it to a view.