I have custom button class "EHCheckBox". There are many buttons in my app, so i try to optimize my code and create button in one line instead of 10. In my view, in viewDidLoad I call method witch call method which create my buttons.
-(void)viewDidLoad
{
.....
[self buttons];
.....
}
-(void)buttons
{
[self addNewBut:pcswitch Title:#" Switch" Column:3 Position:5 Dropable:NO Hide:NO]
}
-(void)addNewBut:(EHCheckBox*)checkBoxName Title:(NSString*)checkBoxTitle Column:(int)checkBoxColumn Position:(int)checkBoxPosition Dropable:(BOOL)checkBoxDropable Hide:(BOOL)hide
{
checkBoxName = [EHCheckBox buttonWithType:UIButtonTypeCustom];
[checkBoxName setTitle:NSLocalizedString(checkBoxTitle, #"") forState:UIControlStateNormal];
checkBoxName.hidden = hide;
if (checkBoxDropable) {
[checkBoxName setBackgroundImage:[UIImage imageNamed:#"CheckButton1.png"] forState:UIControlStateNormal];
[checkBoxName setBackgroundImage:[UIImage imageNamed:#"CheckButtonSelect1.png"] forState:UIControlStateSelected];
}else{
[checkBoxName setBackgroundImage:[UIImage imageNamed:#"CheckButton.png"] forState:UIControlStateNormal];
[checkBoxName setBackgroundImage:[UIImage imageNamed:#"CheckButtonSelect.png"] forState:UIControlStateSelected];
}
int firstColX = 45;
int firstColY = 125;
int width = 140;
int height = 36;
int widhtTwo = 18;
int x = firstColX + (checkBoxColumn - 1)*(width+widhtTwo);
int y = firstColY + (checkBoxPosition - 1)*(height);
checkBoxName.frame = CGRectMake(x, y, 140, 50);
[self.view addSubview:checkBoxName];
}
hide = YES because i have other methods which unhides and hides buttons, but they doesn't works because in view my button is nil, and i don't understand why? Maybe my method should return these button? Thank you.
I cannot understand what's your goal and code here but I really suggest to use categories. In this case the could should look better and more organized.
So, for example, you can follow this approach.
#import <UIKit/UIKit.h>
#interface UIButton (Factory)
+ (UIButton*)buttonWithTitle:(NSString*)title column:(int)column position:(int)position dropable:(BOOL)dropable hide:(BOOL)hide;
#end
and
#import "UIButton+Factory.h"
#implementation UIButton (Factory)
+ (UIButton*)buttonWithTitle:(NSString*)title column:(int)column position:(int)position dropable:(BOOL)dropable hide:(BOOL)hide {
UIButton* button = [UIButton buttonWithType:UIButtonTypeCustom];
//[button setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[button setTitle:NSLocalizedString(title, #"") forState:UIControlStateNormal];
[button setHidden:hide];
if (dropable) {
[button setBackgroundImage:[UIImage imageNamed:#"CheckButton1.png"] forState:UIControlStateNormal];
[button setBackgroundImage:[UIImage imageNamed:#"CheckButtonSelect1.png"] forState:UIControlStateSelected];
} else {
[button setBackgroundImage:[UIImage imageNamed:#"CheckButton.png"] forState:UIControlStateNormal];
[button setBackgroundImage:[UIImage imageNamed:#"CheckButtonSelect.png"] forState:UIControlStateSelected];
}
int firstColX = 45;
int firstColY = 125;
int width = 140;
int height = 36;
int widhtTwo = 18;
int x = firstColX + (column - 1)*(width+widhtTwo);
int y = firstColY + (position - 1)*(height);
button.frame = CGRectMake(x, y, 140, 50);
return button;
}
#end
You can use this category like the following. You need to import #import "UIButton+Factory.h".
UIButton* button = [UIButton buttonWithTitle:#"test" column:1 position:1 dropable:YES hide:NO];
[viewWhereYouWantToAddTheButton addSubview:button];
A note. If you pass 0 to both column and position, your button will assume negative x and y. Hence, you won't see it.
Related
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;
Today I'm creating a custom segmented control. The appearance of the control as follow:
I tried two methods:
- (void)setBackgroundImage:(UIImage *)backgroundImage
forState:(UIControlState)state
barMetrics:(UIBarMetrics)barMetrics
- (void)setDividerImage:(UIImage *)dividerImage
forLeftSegmentState:(UIControlState)leftState
rightSegmentState:(UIControlState)rightState
barMetrics:(UIBarMetrics)barMetrics
However, here is the result I got:
I extracted the border image and the divider line (vertical line) from the design, but the result looks bad. Please help me if you have any idea.
I have always found it too much work to customize the UISegmentedControl and it is not really fully customizable.
I suggest you create yourself a custom UIView inheriting 3 buttons. They are fully customizable and fully controllable:
#define BASE_TAG 123
NSArray *titles = [NSArray arrayWithObjects:#"MAP", #"LOCATIONS", #"BUS", nil];
double y = 0.0;
double x = 0.0;
double width = (frame.size.width / [titles count]);
double height = frame.size.height;
for (int i = 0; i < [titles count]; i++)
{
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setFrame:CGRectMake(x, y, width, height)];
[button.titleLabel setTextAlignment:NSTextAlignmentCenter];
[button setBackgroundColor:[UIColor clearColor]];
[button setTag:(BASE_TAG + ([titles count] - i - 1))];
[button addTarget:self action:#selector(buttonAction:) forControlEvents:UIControlEventTouchUpInside];
[_buttons addObject:button];
x += width;
}
This is your button action. Here the button clicked will be selected and all others unselected:
- (void)buttonAction:(id)sender
{
UIButton *button = (UIButton *)sender;
NSInteger index = 0;
for (UIButton *btn in self.subviews)
{
if (btn == button)
{
index = (btn.tag - BASE_TAG);
[btn setBackgroundColor:[UIColor colorFromHexString:#"#5ac8f5" alpha:1.0]];
[btn setSelected:YES];
}
else
{
[btn setBackgroundColor:[UIColor clearColor]];
[btn setSelected:NO];
}
}
/* Trigger a delegate here if you like
if ([_delegate respondsToSelector:#selector(didSelectedIndex:)])
{
[_delegate didSelectedIndex:index];
}
*/
}
This lets you pre set a selected index:
- (void)setSelectedIndex:(NSInteger)index
{
for (UIButton *button in self.subviews)
{
if (button.tag == (BASE_TAG + index))
{
[button setBackgroundColor:[UIColor colorFromHexString:#"#5ac8f5" alpha:1.0]];
[button setSelected:YES];
}
else
{
[button setBackgroundColor:[UIColor clearColor]];
[button setSelected:NO];
}
}
}
This is just a suggestion code I pulled from an old project. You will have to customize it for your needs.
Here is a very good article how to do custom segmented control.
Looks like you have tried similar approach but you have messed up something with images (probably you misunderstand the API so this article should do the job for you).
I have programmatically generated buttons like this:
- (void)viewDidLoad
{
[super viewDidLoad];
int y = 127;
for (int i=0; i<=6; i++) {
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button addTarget:self action:#selector(aMethod:) forControlEvents:UIControlEventTouchDown];
//[button setTitle:#"Show View" forState:UIControlStateNormal];
button.frame = CGRectMake(26, y, 268, 41);
[button setTitle:[NSString stringWithFormat:#"Button-%i", i] forState:UIControlStateNormal];
[button setBackgroundImage:[UIImage imageNamed:#"cys_button.png"] forState:UIControlStateNormal];
[button.titleLabel setFont:[UIFont fontWithName:#"HelveticaNeueLTPro-Cn" size:21]];
[button setTitleColor:[UIColor colorWithRed:60/255.0 green:60/255.0 blue:60/255.0 alpha:1] forState:UIControlStateNormal];
button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
button.contentEdgeInsets = UIEdgeInsetsMake(8, 15, 0, 0);
[scrollViewContent addSubview:button];
y=y+43;
}
}
and method which shows text after click:
-(void)aMethod:(id)sender{
UIButton *button = sender;
int y = 127;
int i = 6;
for (int x=0; x<=i; x++) {
NSString *frameString = [NSString stringWithFormat:#"{{26, %i}, {268, 41}}", y];
if ([NSStringFromCGRect(button.frame) isEqualToString:frameString]) {
NSLog(#"button %i clicked..", x);
}
y= y+43;
}
}
How to do that after click the button transfer occurred to the next view?
use:
button.tag=i;
set tag to the button while creating button in viewDidLoad so that you can identify your button by using the tag above.
UIButton *button=(UIButton *)[self.view viewWithTag:i];
I have 42 custom button on one View. How can I by pressing any of them edit of the created buttons that i want.
int a=0; int b=1;
int otstup=10;
for (int i=1; i<=42; i++) {
CGRect frameBtn = CGRectMake(a+60+otstup, b+otstup, 45, 45);
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setFrame:frameBtn];
[button setBackgroundImage:[UIImage imageNamed:#"EmptyCoin.png"] forState:UIControlStateNormal];
[button addTarget:self action:#selector(pressBtn:) forControlEvents:UIControlEventTouchUpInside];
[button setTag:i];
[self.view addSubview:button];
a=a+50;
if (i%7 == 0)
{
a=0;
b=b+45;
}
}
-(void)pressBtn:(id)sender{
UIButton *btn = (UIButton*)sender;
if (btn.tag == 1){
1st button tapped
}
else if(btn.tag == 2)
{
2nd button tapped
}
}
By using above code you can differentiate different buttons
Update
You have to create one mutable array store all the buttons in that array. you can access that array in pressBtn method
int a=0; int b=1;
int otstup=10;
for (int i=1; i<=42; i++) {
CGRect frameBtn = CGRectMake(a+60+otstup, b+otstup, 45, 45);
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setFrame:frameBtn];
[button setBackgroundImage:[UIImage imageNamed:#"EmptyCoin.png"] forState:UIControlStateNormal];
[button addTarget:self action:#selector(pressBtn:) forControlEvents:UIControlEventTouchUpInside];
[button setTag:i];
[buttonAry addObject:button];
[self.view addSubview:button];
a=a+50;
if (i%7 == 0)
{
a=0;
b=b+45;
}
}
Button action method
-(void)pressBtn:(id)sender{
UIButton *btn = (UIButton*)sender;
if (btn.tag == 7){
UIButton *editButton = [buttonAry objectAtIndex:btn.tag+1];
[editButton setImage:[UIImage imageNamed:#"image.png"] forState:UIControlStateNormal];
}
}
I am trying to add an action to buttons which I am creating programmatically:
[btn addTarget:self
action:#selector(indexAction)
forControlEvents:UIControlEventTouchUpInside];
This works fine. However, I now want to pass a variable (int k) to the indexAction method. I couldn't get this to work:
[btn addTarget:self
action:#selector([self indexAction:k])
forControlEvents:UIControlEventTouchUpInside];
I am sure I'm doing something wrong. This is the context of the above code:
-(void) initIndexButtons {
float buttonPadding = -8;
float buttonWidth = 23;
float buttonHeight = 80;
CGRect frame = CGRectMake(0,0,0,0);
for (int k=0;k<5;k++)
{
UIButton* btn = [[UIButton alloc] initWithFrame:frame];; btn.tag = k;
btn.frame = CGRectMake(0, k*(buttonPadding+buttonHeight), buttonWidth, buttonHeight);
UIImage *newImage = [UIImage imageNamed:#"index.png"];
[btn setBackgroundImage:newImage forState:UIControlStateNormal];
[btn addTarget:self
action:#selector(self indexAction:k)
forControlEvents:UIControlEventTouchUpInside];
}
}
-(void)indexAction:(int *)buttonTag
{
NSLog(#"buttonTag: %i", buttonTag);
}
EDIT:
I changed my code to:
// ...
[btn addTarget:self
action:#selector(indexAction:)
forControlEvents:UIControlEventTouchUpInside];
//[self indexAction:k];
[indexView addSubview:btn];
[indexView sendSubviewToBack:btn];
}
}
-(void)indexAction:(id)sender
{
NSInteger *tid = ((UIControl *) sender).tag;
NSLog(#"buttonTag: %i", tid);
}
But now I get the warning message that "Initialisation makes pointer from integer without a cast for the line NSInteger *tid = ((UIControl *) sender).tag;
EDIT:
This is the right line of code:
NSInteger tid = ((UIControl*)sender).tag;
Normally the method that a button calls takes one parameter:
(id)sender
Take a look at the question - how to pass a variable to a UIButton action
tag is an NSInteger not NSInteger*
change to
NSInteger tid = ((UIControl*)sender).tag;
The way to do it is to set:
-(void)indexAction:(id)sender
{
NSLog(#"Tag=%#"[(UIButton*)sender tag]);
}
and the call:
[btn addTarget:self
action:#selector(self indexAction:)
forControlEvents:UIControlEventTouchUpInside];
}
not really sure about my casting, haven't tested that, but I think it should work!
Best of luck.