Add Multiple UIButton to a ScrollView - ios

Hej guys, i'm trying to add multiple buttons in a scrollview dynamically
so far, I have this code
for (int i = 0; i < numberOfButtonInMenu; i++)
{
UIButton *aButton = [UIButton new];
UILabel *tButton = [UILabel new];
UILabel *sButton = [UILabel new];
UIImageView *iButton = [UIImageView new];
tButton = title;
sButton = subtitle;
iButton = image;
tButton.hidden = NO;
sButton.hidden = NO;
iButton.hidden = NO;
[tButton setText:Titles[i]];
[sButton setText:Subtitles[i]];
[tButton sizeToFit];
[sButton sizeToFit];
iButton.image = [UIImage imageNamed:Images[i]];
aButton.frame = CGRectMake(xCoord, yCoord, screenWidth, buttonHeight);
[aButton addTarget:self action:#selector(whatever:) forControlEvents:UIControlEventTouchUpInside];
[aButton addSubview:tButton];
[aButton addSubview:sButton];
[aButton addSubview:iButton];
[multiMenuScroll addSubview:aButton];
yCoord += buttonHeight + buffer;
}
}
I set all my design before this for.
When I display my multiMenuScrollView, I end up with only the last button displayed.
(so for numberOfButtonInMenu = 3; I'll have only the third button display)
it look like this : http://i.stack.imgur.com/5UU6S.jpg
Between the "Explore" and the "Around You" there's two others Button, but with nothing in it, it's kinda weird.
Do you guys have any ideas of what I'm doing wrong ?

because you add again tButton sButton iButton in aButton1 to aButton3. show there're will show only in last view (aButton3). If want to add tButton sButton iButton to each button like your code, you need init new tButton sButton iButton in each for loop.
Wrong code:
tButton = title;
sButton = subtitle;
iButton = image;
it must be somethings like:
UILabel *tButton = [[UILabel alloc] initWithFrame:...];
UILabel *sButton = [[UILabel alloc] initWithFrame:...];
UIImageView *iButton = [[UIImageView alloc] initWithFrame:...];

No wonder...
You are not setting the frame correctly. In the for loop, each time you are creating a new button UIButton *aButton = [UIButton new]; and adding subview to multiMenuScroll. All of them getting added but at the same place. So, in the end only 3rd button shows up.
You would need to set the frame of your buttons correctly.
UIButton *aButton = [[UIButton alloc] initWithFrame:<Set_Your_Frame>]; // Change X or Y value as per for loop iteration.
As a side note, you are naming your labels as button suffix like tButton, sButton. Nothing wrong in it programmatically but they confuse!

vwScroll = name of scroll view
tagsArray = Array of NSStrings. These strings will be the text of labels which will add to scroll view in horizontal manner
-(void)setScrollViewWithArray:(NSArray *)tagsArray{
CGFloat xAxis = 0.0f;
CGFloat gapBwLabels = 10.0f;
[vwScroll.subviews makeObjectsPerformSelector:#selector(removeFromSuperview)];
for (int i = 0; i<tagsArray.count; i++) {
NSString *tagName = [tagsArray objectAtIndex:i];
CGSize sizeOfTagString = [self getSizeOfText:tagName];
CGFloat width = sizeOfTagString.width+gapBwLabels;
CGRect tagLabelframe = CGRectMake(xAxis, 2, width, 30);
UILabel *lblTag = [[UILabel alloc]initWithFrame:tagLabelframe];
[self setLabel:lblTag withBackgroundColor:[UIColor whiteColor]];
[lblTag setText:tagName];
[vwScroll addSubview:lblTag];
xAxis = xAxis + width + gapBwLabels;
}
[vwScroll setContentSize:CGSizeMake(xAxis, vwScroll.frame.size.height)];
}

Related

How to ADD label inside infinite button?

This is my code:
-(void)scrollView
{
NSInteger buttonCount = 0;
NSInteger buttonSize = 0;
int divisible= 0;
buttonCount=[[arrFullSubCategory valueForKey:#"name"]count];
if(buttonCount==2)
{
divisible = 2;
buttonSize=self.view.frame.size.width/divisible;
}
else
{
divisible = 3;
buttonSize=self.view.frame.size.width/divisible;
}
[viewBtnScroll addSubview:self.scrollViewBtn];
for(int i=0;i<buttonCount;i++)
{
self.scrollViewBtn.scrollsToTop=YES;
self.scrollViewBtn.directionalLockEnabled=YES;
self.automaticallyAdjustsScrollViewInsets = NO;
UIButton *btn;
btn=[[UIButton alloc]initWithFrame:CGRectMake(buttonSize*i,0,buttonSize,self.scrollViewBtn.frame.size.height)];
[btn setTitle:[NSString stringWithFormat:#"%#",[[arrFullSubCategory objectAtIndex:i] valueForKey:#"name"]] forState:UIControlStateNormal];
btn.userInteractionEnabled=YES;
NSInteger tag=[[[arrFullSubCategory valueForKey:#"category"] objectAtIndex:i] integerValue];
[btn addTarget:self action:#selector(btnClicked:) forControlEvents:UIControlEventTouchUpInside];
[btn setTag:tag];
highLight=[[UILabel alloc]initWithFrame:CGRectMake(buttonSize*i,10,btn.frame.size.width,20)];
highLight.backgroundColor=[UIColor greenColor];
highLight.hidden=YES;
[btn addSubview:highLight];
[self.scrollViewBtn addSubview:btn];
length = [[arrFullSubCategory valueForKey:#"name"] count];
}
self.scrollViewBtn.contentSize=CGSizeMake(buttonSize*buttonCount, self.scrollViewBtn.frame.size.height);
}
1.That button depend up on the coming json values.
2.That button size is calculated for the screen size.
3.i have created label as globally for some reason,and added that to subview of button ,initially it is hide ,when the button pressed that particular button label hidden=NO;
4.everything i have done perfectly,but my problem is How to give x.origin for the particular label?
5.From my code the label present only at end of the button not for all.
6.If i set x.origin as 0 then its present only at the initial button[first button].
7.That button present in scrollview .....
Simplest solution for this would be
create new UIView (lets name it MyView) of the size you want.
create UILabel of size you want and x and y with respect to MyView
and add it to MyView
Add MyView to your UIScrollView.
Then create a UIButton of the same dimensions as MyView and add it to you same UIScrollView
Important here is you add button to your UIScrollView and not MyView
and you are good to go .. hope this helps...
======= EDITS ======== Use the code as you need
float width = GridScrollView.frame.size.width;
int i,k=0;
for ( i= 0; i < imageArray.count; i+=4) {
for (int j =0; j<4; j++) {
if (i+j <nameArray.count) {
NSLog(#"i = %d j = %d k = %d",i,j,k);
UIActivityIndicatorView *spinner2 = [[UIActivityIndicatorView alloc]initWithFrame:CGRectMake((width/4)*j ,(width/4)*k , width/4, width/4)];
[spinner2 startAnimating];
[GridScrollView addSubview:spinner2];
UIView *gridBox = [[UIView alloc]initWithFrame:CGRectMake((width/4)*j ,(width/4)*k , width/4, width/4)];
// gridBox.backgroundColor=[UIColor whiteColor];
[GridScrollView addSubview:gridBox];
UIView *labelBack = [[UIView alloc]initWithFrame:CGRectMake((width/4)*j ,(width/4)*k , width/4, width/16)];
labelBack.backgroundColor=[UIColor blackColor];
labelBack.alpha=0.5;
[GridScrollView addSubview:labelBack];
UILabel *nameLabel = [[UILabel alloc]initWithFrame:CGRectMake((width/4)*j ,(width/4)*k , width/4, width/16)];
nameLabel.text=nameArray[i+j];
nameLabel.textAlignment = NSTextAlignmentCenter;
nameLabel.textColor=[UIColor whiteColor];
nameLabel.font=[UIFont fontWithName:#"Arial" size:12];
[GridScrollView addSubview:nameLabel];
UIButton *gridButton = [[UIButton alloc]initWithFrame:CGRectMake((width/4)*j ,(width/4)*k , width/4, width/4)];
[gridButton addTarget:self action:#selector(gridButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
gridButton.tag=i+j;
[GridScrollView addSubview:gridButton];
}
} k++;
}
[GridScrollView setContentSize:CGSizeMake(width, (width/4)*(i/4))];
[self.view addSubview:GridScrollView];

Accessing UILabel created on run time

I have created UILabel (lblCount) and UIButton (btnAdd) on a UIButton (Add Item Button)'s action method. The new UILabel and UIButton is added to scrollview. The UILabel (lblCount) shows count of UIButton (btnAdd) tapped. Here, addBtnClickCount is an integer which counts the number of click.
UILabel * lblCount = [[UILabel alloc] initWithFrame:CGRectMake( 50, 100*addBtnClickCount, 25, 25)];
lblCount.text = [NSString stringWithFormat:#"%d",count];
lblCount.tag = addBtnClickCount;
lblCount.textColor = [UIColor whiteColor];
lblCount.textAlignment = NSTextAlignmentCenter;
[self.scrollView addSubview:lblCount];
addBtnClickCount = addBtnClickCount+1;
There will be multiple label (lblCount) and button (btnAdd) when user taps Add Item Button. I want to access particular label for particular add button and display the count.
You have already set tag on your label. Create a mutable array labelArray and add label to it. To access the particular label do following code on add button's action.
-(void)addItem:(UIButton*)button{
UILabel* lblShowCount = [_labelArray objectAtIndex:[button tag]];
lblShowCount.text = [NSString stringWithFormat:#"%d", [lblShowCount.text integerValue]+1];
}
Here i understand that #Hem Poudyal, know's that with help of viewWithTag.he will get output. but don't know how to achieved that. so i am describing over here.
Step 1: Here i am adding UILabel and UIButton to self.view instead of UIScrollView. i hope you can convert it as UIScrollView. here i applied some relation between UILabel tag and UIButton tag. that you can see in below code.
for (int i=0; i<10; i++) {
UILabel * lblCount = [[UILabel alloc] initWithFrame:CGRectMake( 50, (i*50)+((i+1)*5), 100, 50)];
lblCount.text = [NSString stringWithFormat:#"%d",0];
lblCount.tag = [[NSString stringWithFormat:#"%d%d",i,i] integerValue];
lblCount.backgroundColor = [UIColor yellowColor];
lblCount.textAlignment = NSTextAlignmentCenter;
[self.view addSubview:lblCount];
UIButton* btnTemp = [UIButton buttonWithType:UIButtonTypeCustom];
btnTemp.tag = i;
btnTemp.backgroundColor = [UIColor redColor];
[btnTemp addTarget:self action:#selector(btnTempClick:) forControlEvents:UIControlEventTouchUpInside];
btnTemp.frame = CGRectMake( 150, (i*50)+((i+1)*5), 100, 50);
[btnTemp setTitle:[NSString stringWithFormat:#"Button : %d",i] forState:UIControlStateNormal];
[self.view addSubview:btnTemp];
}
Step 2: In UIButton selector method, Do the following things.
-(IBAction)btnTempClick:(id)sender{
UIButton* btnInner = sender;
NSInteger lblTagbaseOnButtonTag = [[NSString stringWithFormat:#"%ld%ld",btnInner.tag,btnInner.tag] integerValue];
UILabel* lblReceived = (UILabel*)[self.view viewWithTag:lblTagbaseOnButtonTag];
lblReceived.text = [NSString stringWithFormat:#"%ld",[lblReceived.text integerValue]+1];
}
And Output is :
You should have an array that you add the labels and buttons too (this could be one array containing a dictionary or custom class or multiple arrays). Now, when a button is tapped you can find where it is in the array and get the corresponding label to update.
The cheat way is to set the tag of the buttons and labels so you can find one from the other using viewWithTag:.
You need to set unique tag value while creating the labels and buttons and by using viewWithTag: you can access the respective ui container.

iOS system button click frame issue

Problem:
Some system UIButton Types are getting clickable outside its defined frame/bounds.
The below two buttons types are getting selected within their defined frame region properly.
UIButtonTypeCustom [width:160, height:44.0]
UIButtonTypeSystem [width:50, height:44.0]
The below button types are even selectable outside of its frame rectangle from all sides by 10~15points.[Background color is drawn/displaying with in the defined frame for all these buttons]
UIButtonTypeDetailDisclosure,[width:50, height:44.0]
UIButtonTypeInfoLight, [width:50, height:44.0]
UIButtonTypeInfoDark, [width:50, height:44.0]
UIButtonTypeContactAdd [width:50, height:44.0]
I expecting the clickable/selectable area should be with in the button frame.
I am creating the buttons using following method:
- (UIButton*)createButton:(UIButtonType)style withFrame:(CGRect)frame {
UIButton *button = nil;
UILabel *label = nil;
switch(style)
{
case UIButtonTypeCustom: // frame: {x,y,160.0,44.0}
button = [[UIButton alloc] initWithFrame:frame];
button.layer.cornerRadius = 10;
label = [[UILabel alloc] initWithFrame:CGRectMake(0.0, 0.0, 160.0, 44.0)];
label.text = #"Custom";
label.textAlignment = NSTextAlignmentCenter;
[button addSubview:label];
break;
case UIButtonTypeSystem: // frame: {x,y,50.0,44.0}
button = [UIButton buttonWithType:style];
[button setTitle:#"Button" forState:UIControlStateNormal];
button.frame = frame;
break;
default: // frame: {x,y,50.0,44.0}
button = [UIButton buttonWithType:style];
button.frame = frame;
break;
}
// Background whitecolor is displaying properly for all buttons.
button.backgroundColor = [UIColor whiteColor];
return button;
}
The createButton method is called as below
for (int i=0, y=10, x=15; i<6; ++i) {
if(i == 5)
{
y += 90;
x = ([[UIScreen mainScreen] bounds].size.width - 160.0)/2.0;
}
UIButton *btn = [self createButton:5-i withFrame:CGRectMake(x, y, ( i<5 ? 50.0 : 160.0), 44.0)];
[btn setTag: i+1];
[btn addTarget:self action:#selector(settingsView:) forControlEvents:UIControlEventTouchUpInside];
[_subView addSubview:btn];
x += 60;
}
The iOS typically expands the touchable area of buttons according to its own internal rules.
My guess: it makes the buttons easier for users to touch.

iOS Calc X position to place elements on a View

I want to add a Label and an Image in titleView of my NavigationItem. I am adding UILabel and UIImageView to a UIView and setting it as titleView of the navigation Item. Things are being added, but I am not able to calculate the length of label and place image next to it.
My code is :-
// Title Name + Image
UIView *titView = [[UIView alloc] initWithFrame:self.navigationItem.titleView.bounds];
self.navigationItem.titleView = titView;
UILabel *title = [[UILabel alloc] initWithFrame:CGRectMake(-10, -20, 150, 30)];
title.text = #"Bunny ";
[title setTextColor:[UIColor orangeColor]];
[titView addSubview:title];
float x2 = 30; //+ title.bounds.size.width;
UIImageView *img = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"return" ]];
img.frame = CGRectMake(x2, -20, img.bounds.size.width, 30);
[titView addSubview:img];
I am looking for some way to calc the width text and set accordingly the width of the label. Right now I have set the width of the label as 150. And secondly, calc the x position to place the image just next to the label.
Tried many ways, but nothing works as expected. How can I achieve this ? Can you he give some guidelines such that regardless of length of text of label, things works as expected and UIView gets placed in the center of navigation item.
Any help is highly appreciated. Thanks.
You can call
[title sizeToFit];
after setting its properties and it will size itself to match the contained string.
Set the imageViews x origin to
CGRectGetMaxX(title.frame) + desiredSpacing;
And it could help to subclass UIView to achieve the final results by overwriting layoutSubviews and placing your views there, since the titleView's frame can be adjusted by the navigationBar...basically like this:
#implementation TitleView{
UILabel *_titleLabel;
UIImageView *_img;
}
- (id)initWithTitle:(NSString *)title andImage:(UIImage *)image
{
self = [super init];
if (self) {
_titleLabel = [[UILabel alloc] init];
_titleLabel.text = title;
[_titleLabel setTextColor:[UIColor orangeColor]];
[_titleLabel sizeToFit];
[self addSubview:_titleLabel];
_img = [[UIImageView alloc] initWithImage:image];
[self addSubview:_img];
}
return self;
}
- (void)layoutSubviews{
CGFloat spacingBetweenTextAndImage = 0;
CGFloat width = CGRectGetWidth(_titleLabel.frame)+CGRectGetWidth(_img.frame)+spacingBetweenTextAndImage;
CGFloat x = (CGRectGetWidth(self.bounds)-width)/2;
_titleLabel.frame = CGRectMake(x, (CGRectGetHeight(self.bounds)-CGRectGetHeight(_titleLabel.bounds))/2, CGRectGetWidth(_titleLabel.bounds), CGRectGetHeight(_titleLabel.bounds));
x+=CGRectGetWidth(_titleLabel.bounds)+spacingBetweenTextAndImage;
_img.frame = CGRectMake(x, (CGRectGetHeight(self.bounds)-CGRectGetHeight(_img.bounds))/2, CGRectGetWidth(_img.bounds), CGRectGetHeight(_img.bounds));
}
#end
use in your viewController:
UIView *titleView = [[TitleView alloc] initWithTitle:#"Bunny" andImage:[UIImage imageNamed:#"return" ]];
self.navigationItem.titleView = titleView;

IOS UIButton Target doesnot working

here is my code
for (NSString *message in self.messages) {
label = [[UIButton alloc] initWithFrame:CGRectZero];
[label setTitle:message forState:UIControlStateNormal];
//label.titleLabel.text = message;
label.tag = i;
[label addTarget:self action:#selector(gototest:) forControlEvents:UIControlEventTouchDown];
CGSize size = [message sizeWithFont:label.titleLabel.font];
CGFloat width = size.width + kPADDING;
label.frame = CGRectMake(xPos, 0.0, width, self.frame.size.height);
[self addSubview:label];
i++;
xPos += width;
}
-(void)gototest:(UIButton*)sender
{
int tag = sender.tag;
NSLog(#"test %#",#"ccc ");
}
So nothing happen when I click on the buttons.
Note that the class is extend from UIScrollView and also I have to create a marquee with different news and when I click in any of this news, I have to go to the detail of the chosen new.
Please help me
UIControlEventTouchDown should not be the problem, it works too. Can you try the following
label = [UIButton buttonWithType:UIButtonTypeCustom];
instead of
label = [[UIButton alloc] initWithFrame:CGRectZero];
Too I suspect the following line too
label.frame = CGRectMake(xPos, 0.0, width, self.frame.size.height);
the frame you are setting confirm it is correct, in normal usage it may appear that your UIButton is visible, but it may not. Try put
label.clipsToBounds=YES;
and check, if your UIButton is actually visible, that might be the reason your action not working..
UPDATE
Ok, As per my understanding, as you are saying, you are trying to create Marquee, and the original implementation had UILabel and you are trying to change that to UIButton. Let change few things as the code below,
for (NSString *message in self.messages) {
label = [[UILabel alloc] initWithFrame:CGRectZero];
label.text = message;
label.tag = i;
UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(gototest:)];
tapGestureRecognizer.numberOfTapsRequired = 1;
[label addGestureRecognizer:tapGestureRecognizer];
label.userInteractionEnabled = YES;
CGSize size = [message sizeWithFont:label.font];
CGFloat width = size.width + kPADDING;
label.frame = CGRectMake(xPos, 0.0, width, self.frame.size.height);
[self addSubview:label];
i++;
xPos += width;
}
And your action
-(void)gototest:(UITapGestureRecognizer*)sender
{
int tag = sender.view.tag;
NSLog(#"test %#",#"ccc ");
}
Use touch event "UIControlEventTouchUpInside" intends of "UIControlEventTouchDown".
It will works fine :
[label addTarget:self action:#selector(grottiest:)
forControlEvents:UIControlEventTouchUpInside];
Edit :
label = [[UIButton alloc] initWithFrame:CGRectMake(xPos, 0.0, 100, 100)];
[label setTitle:message forState:UIControlStateNormal];
//label.titleLabel.text = message;
label.tag = i;
[label addTarget:self action:#selector(gototest:) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:label];
Your code is working fine with single button. The problem is somewhere else..
UIButton *label = [[UIButton alloc] initWithFrame:CGRectZero];
[label setTitle:#"Click" forState:UIControlStateNormal];
//label.titleLabel.text = message;
label.tag = 0;
[label addTarget:self action:#selector(gototest:) forControlEvents:UIControlEventTouchDown];
label.frame = CGRectMake(0,0,100,50);
[self addSubview:label];
Replace:
label = [[UIButton alloc] initWithFrame:CGRectZero];
with
UIButton *label = [[UIButton alloc] initWithFrame:CGRectZero];

Resources