Create a button program programmatically in a seperate class - ios

I am developing a snake game and for that I created 3 classes: Player, Control, and Grid. For my question, I would like to create the play button programmatically in which the function of creating a button is in the Control class and this function is called in the ViewController.m
In ViewController.h, I defined
#property (nonatomic, strong) Control *control; //object of Control class
#property (weak) IBOutlet UIButton *button;
In ViewController.m:
self.control = [[Control alloc] init];
[control createButton:_viewC Button:_button]; //_viewC is the view where the button will be shown
[_button addTarget:self action:#selector(play) forControlEvents:UIControlEventTouchUpInside]; //since play method in ViewController.m
In Control class:
-(void)createButton:(UIView*)view Button:(UIButton*)button
{
button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setTitle:#"Play" forState:UIControlStateNormal];
[button setTitleColor:[UIColor blueColor] forState:UIControlStateNormal ];
button.backgroundColor = [UIColor whiteColor];
button.titleLabel.font = [UIFont fontWithName:#"Helvetica-Bold" size:10];
button.layer.cornerRadius = 10;
button.frame = CGRectMake(35, 30, 70, 40);
[view addSubview:button];
}
The problem is when I run the game and press the button, no action happens! can someone help me with this. Thanks

Assuming that the code in the 'play' method is correct you can try setting the target in the Control class by changing the declaration to:
-(void)createButton:(UIView*)view Button:(UIButton*)button Selector:(SEL)selector
Then add this within that method:
[button addTarget:self.superview action:selector forControlEvents:UIControlEventTouchUpInside];
Finally in ViewController.m change the line to this:
[control createButton:_viewC Button:_button selector:#selector(play)];
and remove the line underneath.

Related

How to reuse properties

I have many different buttons in my app, yet most of them have the same properties assigned to them:
login = [[UIButton alloc]initWithFrame:CGRectMake(8, CGRectGetMaxY(password.frame) + 16, loginView.frame.size.width - 16, 40)];
[login setTitle:#"Login" forState:UIControlStateNormal];
[login.titleLabel setFont:[UIFont fontWithName:#"Avenir Next" size:18]];
[login setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[login setTitleColor:[UIColor colorWithWhite:0.7 alpha:1] forState:UIControlStateHighlighted];
[login setTitleColor:[UIColor colorWithWhite:0.5 alpha:1] forState:UIControlStateDisabled];
Is there any way to create a class or something of a button that already has these default properties assigned? So I could simply go something like:
CustomButtom *btn = [CustomButton alloc]init];
Then the btn will have all of the above properties assigned?
Thanks.
Another way of handling this, is you can create a private method that will return the UIButton with the same properties. I think creating a subclass of UIButton is a little unnecessary.
You can do this by creating a CustomButton class
Xcode -> New File -> Cocoa Touch Class -> Next -> Name Your Button-> Select Subclass of UIButton
CustomButton.h file
#import <UIKit/UIKit.h>
#interface CustomButton : UIButton
#end
CustomButton.m file
#import "CustomButton.h"
#implementation CustomButton
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
// Drawing code
//login = [[UIButton alloc]initWithFrame:CGRectMake(8, CGRectGetMaxY(password.frame) + 16, loginView.frame.size.width - 16, 40)];
[self setTitle:#"Login" forState:UIControlStateNormal];
[self.titleLabel setFont:[UIFont fontWithName:#"Avenir Next" size:18]];
[self setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[self setTitleColor:[UIColor colorWithWhite:0.7 alpha:1] forState:UIControlStateHighlighted];
[self setTitleColor:[UIColor colorWithWhite:0.5 alpha:1] forState:UIControlStateDisabled];
}
#end
Now, Call you button
CustomButton *customButton = [[CustomButton alloc]initWithFrame:CGRectMake(8, CGRectGetMaxY(password.frame) + 16, loginView.frame.size.width - 16, 40)];
[customButton addTarget:self action:#selector(loginButtonPressed:) forControlEvents:UIControlEventTouchDown];
[YourView addSubview:customButton];
You've got two options:
Make a function that you can pass in a UIButton to that sets the properties for you
Write a Category for UIButton that does the same as the above. Categories allow you to add functionality to a class without subclassing. See https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/CustomizingExistingClasses/CustomizingExistingClasses.html
Yes. You can subclass the UIButton. When you override the init method setting the properties you could get the button's with the same properties.

UICategory - UIButtons and UITextfield

I want to create five buttons with same formats, so that i have created UICategory class for UIButton, But I don't get that category class calling, please help me on this,
My category class is as follows,
#implementation UIButton (headerBtn)
+(UIButton *)headerButtons{
UIButton *header = [[UIButton alloc]init];
[header setTitleColor:[UIColor headerBtnColor] forState:UIControlStateNormal];
header.titleLabel.font = [UIFont fontWithName:Fonts_ProximaNovaMedium size:13.0f];
return header;}
Am calling button like as below,
btn_pulse = [UIButton headerButtons];
is that correct way?
Change the line:
UIButton *header = [[UIButton alloc]init];
for
UIButton *header = [UIButton buttonWithType:UIButtonTypeCustom];
Anyway, I don't think you need a class method. I would do it this way:
#implementation UIButton (headerBtn)
-(void)headerStyle{
[self setTitleColor:[UIColor headerBtnColor] forState:UIControlStateNormal];
self.titleLabel.font = [UIFont fontWithName:Fonts_ProximaNovaMedium size:13.0f];
}
And the you just need to import your category and:
UIButton *myButton = [[UIButton buttonWithType:UIButtonTypeCustom] headerStyle];
You have to import your category wherever you need it:
#import "UIButton+headerBtn.h"

How do I change a button's color when pressed and reset to original color when a different button is pressed?

So I have two gray UIButton, button1 and button2. I want to change the color of the button when I press it to red and back to gray when I press the other button.
I used this code:
UIButton *btn = (UIButton *)sender;
[btn setBackgroundColor:[UIColor redColor]];
But it makes both buttons red.
How do I make it so that if button1 is red, it will change back to gray when I press button2?
Create two buttons btn1 & btn2 .
#property (weak, nonatomic) IBOutlet UIButton *btn1;
#property (weak, nonatomic) IBOutlet UIButton *btn2;
- (IBAction)btnClick:(id)sender;
Both btn1 & btn2 should be connected to btnClick . Below code will do the rest of your work
- (IBAction)btnClick:(id)sender {
if (self.btn1 == sender) {
[self.btn1 setBackgroundColor:[UIColor redColor]];
[self.btn2 setBackgroundColor:[UIColor grayColor]];
}else{
[self.btn1 setBackgroundColor:[UIColor grayColor]];
[self.btn2 setBackgroundColor:[UIColor redColor]];
}
}
You are going to want to make two separate buttons. By the look of your code you only declared only one button.
Declare both buttons in your interface, initialize them in the ViewDidLoad() method.
Set 2 different targets for each of the buttons so when one is clicked you can set the other buttons colour.
What I am getting from this is that both buttons are connected to the same action/method, which contains the code you gave. The easiest way to do what you specified is to have two different actions/methods, and connect each button to a different method. Connect button1 to button1Pressed and connect button2 to button2Pressed.
In .h put:
{
//connect these buttons up either via interface builder or through code
IBOutlet UIButton* button1;
IBOutlet UIButton* button2;
}
- (IBAction)button1Pressed:(id)sender;
- (IBAction)button2Pressed:(id)sender;
In .m put:
//connect this method to "touch up inside" on button1
- (IBAction)button1Pressed:(id)sender
{
//makes button1 red
[button1 setBackgroundColor:[UIColor redColor]];
}
//connect this method to "touch up inside" on button2
- (IBAction)button2Pressed:(id)sender
{
//changes button1 back to gray
[button1 setBackgroundColor:[UIColor grayColor]];
}
Hope this helps!
There is many way to solve such issue, in your case we do not really know how you are instantiating your UIButton. The following purpose you one of the possible solution using tag:
First you should define your button in your header:
#implementation _4644518ViewController {
UIButton *btn1;
UIButton *btn2;
}
Then, you should implement them in your view and attach to them the tapped method:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
btn1 = [[UIButton alloc] initWithFrame:CGRectMake(5, 5, 100, 30)];
[btn1 setTag:101];
[btn1 setTitle:#"btn1" forState:UIControlStateNormal];
btn1.backgroundColor = [UIColor lightGrayColor];
[btn1 addTarget:self action:#selector(btnTapped:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn1];
btn2 = [[UIButton alloc] initWithFrame:CGRectMake(5, 40, 100, 30)];
[btn2 setTag:102];
[btn2 setTitle:#"btn2" forState:UIControlStateNormal];
btn2.backgroundColor = [UIColor lightGrayColor];
[btn2 addTarget:self action:#selector(btnTapped:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn2];
}
The last thing to do is to implement your btnTapped method:
- (void)btnTapped:(id)sender
{
if ([sender tag] == 101) {
btn1.backgroundColor = [UIColor redColor];
btn2.backgroundColor = [UIColor lightGrayColor];
} else if([sender tag] == 102) {
btn1.backgroundColor = [UIColor lightGrayColor];
btn2.backgroundColor = [UIColor redColor];
}
}
As I mentioned earlier, there is many way to perform such algorithm, but I like this one since we don't know many things about your background application and this one will be easy to custom for you.

Change properties of programmatically created UIButton in a different IBAction

I have one method that creates a number of UIButton instances programmatically and positions them in the view. Another IBAction needs to change the background colour of one of these UIButton when fired however when I try to action it, it tells me that the Property not found on object of type UIView *
The button is created using:
UIButton * button = [UIButton buttonWithType:UIButtonTypeCustom];
[view addSubview:button];
When I try to access it from the other IBAction like:
button.backgroundColor = [UIColor blackColor];
It fails with the error noted above.
Any help is much appreciated. I saw another answer which suggested to create an array as an IBOutlet and access it that way but I'm wondering if there's another way.
Thanks!
declare this button in globally and identify each button in tag, just like or assume this
UIButton * button, *button2; // declare in your view controller.h
- (IBAction)butaction:(id)sender; //this is your color change method;
in your view controller.m wherever u add this button
button = [UIButton buttonWithType:UIButtonTypeCustom];
button.tag=10; //this is important
[self.view addSubview:button];
button1 = [UIButton buttonWithType:UIButtonTypeCustom];
button1.tag=20; //this is important
[self.view addSubview:button1];
//here ur color change method
- (IBAction) butaction:(UIButton*)sender {
switch (sender.tag)
{
case 10:
[button setBackgroundColor:[UIColor blackColor]];
break;
case 20:
[button1 setBackgroundColor:[UIColor blackColor]];
break;
default:
break;
}
}
Try this, it may be helpful
for (int index=1; index<=5; index++) {
UIButton * button = [UIButton buttonWithType:UIButtonTypeCustom];
[button addTarget:self action:#selector(ButtonClickedFunction:) forControlEvents:UIControlEventTouchUpInside];
button.tag= index;
[view addSubview:button];
};
implement this in IBAction
-(IBAction)ButtonClickedFunction:(UIButton *)button{
button.backgroundColor = [UIColor blackColor];
}
Note: In this I have created 5 buttons but not set frame. Please set frame according to your requirements.
Thanks

Cannot hide programmatically created UIButton

This issue is baffling me for a few days now.
I have 2 UIButtons, one created using the Storyboard and one created programmatically.
When I press one of the buttons, I am moved to a method that hides both the programatically built and storyboard buttons, but only the storyboard button disappears, whereas the programmatically built button remains. I have tried not only hiding but also changing the frame of the programmatically built button, but to no avail.
Here is the code used:
#property (strong, nonatomic) UIButton *catBut;
#property (weak, nonatomic) IBOutlet UIButton *whenButton;
....
....
-(void)viewDidLoad {
....
[self customizeButton:self.catBut withFrame:CGRectMake(165, 113, 135, 50)
andAction:#selector(selectedCat) andColor:[UIColor belizeHoleColor]
andTag:2 andImage:#"coffee-64.png" andText:#"Cafes" andAlignmentLeft:YES];
....
}
- (void)customizeButton:(UIButton *)but withFrame:(CGRect)rect andAction:(SEL)action
andColor:(UIColor *)col andTag:(NSUInteger)tag
andImage:(NSString *)imageName
andText:(NSString *)buttonText
andAlignmentLeft:(BOOL)alignLeft {
but = [UIButton buttonWithType:UIButtonTypeCustom];
[but setFrame:rect];
[but setTitle:buttonText forState:UIControlStateNormal];
but.tag = tag;
but.titleLabel.numberOfLines = 0;
but.titleLabel.font = [UIFont boldFlatFontOfSize:18];
[but setImage:[UIImage imageNamed:imageName] forState:UIControlStateNormal];
CGFloat spacing = 10; // the amount of spacing to appear between image and title
but.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
but.imageEdgeInsets = UIEdgeInsetsMake(0, spacing, 0, 0);
but.titleEdgeInsets = UIEdgeInsetsMake(0, spacing*2, 0, 0);
[but setTitleColor:[UIColor cloudsColor] forState:UIControlStateNormal];
[but setTitleColor:[UIColor cloudsColor] forState:UIControlStateHighlighted];
[but addTarget:self action:action forControlEvents:UIControlEventTouchUpInside];
[self.buttonsView addSubview:but];
}
....
- (void)selectedCat {
self.catBut.hidden = YES;
self.whenButton.hidden = YES;
}
Why is only the Storyboard button compliant to UI changes? Is there something I am missing? I have tried cancelling the AutoLayout but that didn't change a thing.
The issue is with the passing for argument in your method (customizeButton:(UIButton *)but).
Change your code to this and check
but = [UIButton buttonWithType:UIButtonTypeCustom];
to
self.catBut = [UIButton buttonWithType:UIButtonTypeCustom];
......
[self.buttonsView addSubview:self.catBut];
OR You should pass the address customizeButton:(UIButton **)but in the method
and while calling use &self.catBut
It is BOOL type, not an bool type.
try this
self.catBut.hidden = YES;
self.whenButton.hidden = YES;
I can see this property catBut, But I cann't see creation for this, as well I didn't give Outlet too. Check this. You've tried something but simply fix by following line.
[self.buttonsView addSubview:but];
self.catBut = but;

Resources