Auto Fill scrollview with UIButtons from NSArray - ios

I need to fill a view becoming the contents of a NSArray object in a UIButtons and if the number of buttons does not fit the view to scroll. For example, if the array.count is 25 and only fit 20 buttons, 4 columns of 5 rows, the 5 remaining buttons are to be displayed by scrolling.
I'm currently testing it so:
UIScrollView *sv = [[UIScrollView alloc] initWithFrame:CGRectMake(20, 20, 728, 984)];
sv.backgroundColor = [UIColor greenColor];
sv.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
sv.contentSize = CGSizeMake(PAGE_WIDTH, sv.frame.size.height);
sv.pagingEnabled = YES;
[self.view addSubview:sv]; // assuming a view controller
NSMutableArray *freeHoursList = [NSMutableArray arrayWithObjects:
[NSString stringWithFormat:#"10"],
[NSString stringWithFormat:#"11"],
[NSString stringWithFormat:#"12"],
[NSString stringWithFormat:#"17"],
[NSString stringWithFormat:#"18"],
[NSString stringWithFormat:#"19"],
[NSString stringWithFormat:#"10"],
[NSString stringWithFormat:#"11"],
[NSString stringWithFormat:#"12"],
[NSString stringWithFormat:#"17"],
[NSString stringWithFormat:#"18"],
[NSString stringWithFormat:#"19"],nil];
for (int i = 0; i < freeHoursList.count; i++)
{
UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
btn.backgroundColor = [UIColor redColor];
btn.frame = CGRectMake(i * (BUTTON_WIDTH + BUTTON_PADDING), 10, BUTTON_WIDTH, BUTTON_HEIGHT);
btn.tag = i + MAGIC_BUTTON_TAG_OFFSET; // to relate to the array index
NSString *numero = [freeHoursList objectAtIndex:i];
[btn setTitle:[NSString stringWithFormat:#"%#",numero] forState:UIControlStateNormal];
//[btn addTarget:self action:#selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
[sv addSubview:btn];
}
And this is what I get:

I would go with adding variable that keeps track of an actual Y position and an actual column. So you would check if the next button fits the width of the scroll and if its not - set column to 0 and add X to the button Y position. It would looks like this:
int BUTTON_Y = 10;
int column = 0;
for (int i = 0; i < freeHoursList.count; i++, column++)
{
if(column*(BUTTON_WIDTH + BUTTON_PADDING) + BUTTON_WIDTH > sv.contentSize.width) {
BUTTON_Y += BUTTON_HEIGHT;
column = 0;
}
UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
btn.backgroundColor = [UIColor redColor];
btn.frame = CGRectMake(column * (BUTTON_WIDTH + BUTTON_PADDING), BUTTON_Y, BUTTON_WIDTH, BUTTON_HEIGHT);
btn.tag = column + MAGIC_BUTTON_TAG_OFFSET; // to relate to the array index
NSString *numero = [freeHoursList objectAtIndex:i];
[btn setTitle:[NSString stringWithFormat:#"%#",numero] forState:UIControlStateNormal];
//[btn addTarget:self action:#selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
[sv addSubview:btn];
}

Related

Custom UIView subClass with UIScrollView

I am creating a class, that creates an option bar with multiple scroll views accessible by buttons.
This is how I add the subview with its content:
NSArray *scroll1 = [NSArray arrayWithObjects:#"normal",#"tiltshift",#"zoom",#"normal",#"blur",#"outline",#"coming soon", nil];
NSArray *scroll2 = [NSArray arrayWithObjects:#"Emoji Natur-01",#"Emoji Natur-02",#"Emoji Natur-03",#"Emoji Natur-04",#"Emoji Natur-05",#"Emoji Natur-06",#"Emoji Natur-07",#"Emoji Natur-08",#"Emoji Natur-09",#"Emoji Natur-10",#"Emoji Natur-11",#"Emoji Natur-12", nil];
NSArray *scroll3 = [NSArray arrayWithObjects:#"Linear",#"Parallel",#"Parallel 2",#"Crescendo",#"Dubstep",#"Blackhole",#"coming soon", nil];
NSArray *content = [NSArray arrayWithObjects:scroll1,scroll2,scroll3, nil];
[self.view addSubview:[self.bottomOptionView initWithFrame:self.view.frame withContent:content]];
The Subclass then generate a scrollview for each Array, with the buttons based on the content of the array:
-(void)addScrollViewOfContent:(NSArray*)array{
int viewNumber = array.count;
for (int i = 0 ; i < viewNumber; i++) {
//create the main buttons
NSArray *content = array[i];
UIButton *buttonAccess = [UIButton buttonWithType:UIButtonTypeRoundedRect];
CGFloat buttonEdge = 40;
CGFloat buttonSpace = self.frame.size.width /viewNumber;
int placeOfButton = i+1;
CGFloat buttonAnchor = ((placeOfButton*(buttonSpace)) - (buttonSpace /2+ buttonEdge/2));
buttonAccess.frame = CGRectMake(buttonAnchor, 0 , buttonEdge, buttonEdge);
[buttonAccess setBackgroundColor:[UIColor redColor]];
buttonAccess.tag = i;
[buttonAccess addTarget:self action:#selector(buttonAccess:) forControlEvents:UIControlEventTouchDown];
[self addSubview:buttonAccess];
UIScrollView *ScrollView = [[UIScrollView alloc]init];
ScrollView.frame = CGRectMake(0, 50, self.frame.size.width, self.frame.size.height);
ScrollView.showsHorizontalScrollIndicator = YES;
ScrollView.tag = i;
ScrollView.backgroundColor =[UIColor colorWithRed:0 green:0.0 blue:0.0 alpha:0.0];
ScrollView.indicatorStyle = UIScrollViewDecelerationRateNormal ;
//UIImageView *selector = [[UIImageView alloc]initWithImage:[UIImage imageNamed:#"FILTER_SELECT.png"]];
CGFloat btnX = 0;
for (int i = 0 ; i < content.count; i++)
{
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button.frame = CGRectMake(btnX, 2 , 65, 65);
UIImage *img = [UIImage imageNamed:[content objectAtIndex:i]];
[button setBackgroundImage:img forState:UIControlStateNormal];
[button addTarget:self action:#selector(subButtonTarget:) forControlEvents:UIControlEventTouchDown];
button.tag = i;
[button setTitle:[content objectAtIndex:i] forState:UIControlStateNormal];
button.titleLabel.font = [UIFont fontWithName:#"MyriadPro-Cond" size:15];
button.titleLabel.textColor = [UIColor whiteColor];
button.titleLabel.textAlignment = UIBaselineAdjustmentAlignBaselines ;
button.showsTouchWhenHighlighted = YES;
[ScrollView addSubview:button];
btnX = btnX + 100;
}
btnX = btnX - 80;
ScrollView.contentSize = CGSizeMake(btnX + 50, 80);
ScrollView.hidden = YES;
[self.scrollViewArray addObject:ScrollView];
[self addSubview:ScrollView];
}
This gives me exactly what I want.
Then I detect which button, of which scroll view is pressed to trigger the action.
-(void)subButtonTarget:(UIButton *)sender{
int button = sender.tag;
int scrollview = self.selectedScrollView;
[self.videoEditor subAction:button ofScrollView:scrollview];
}
-(void)buttonAccess:(UIButton *)sender{
// self.selectedScrollView = sender.tag;
for (int i=0; i< self.scrollViewArray.count; i++) {
UIScrollView *scrollview= [self.scrollViewArray objectAtIndex:i];
scrollview.hidden= YES;
}
int scrollIndex = sender.tag;
UIScrollView *scrollview= [self.scrollViewArray objectAtIndex:scrollIndex];
scrollview.hidden = NO;
}
Basically when one of the button is touched, it calls a function in the view controller in which the sublclass was initially called.
The problem is that, on touchevent nothing happens, except for NSLog. Would that be because of the dependency relation of the subClass and the VC that uses it?
You should set this one for each UIScrollView
ScrollView.delaysContentTouches = NO;
And try to subclass UIScrollView with override method
-(BOOL)touchesShouldCancelInContentView:(UIView *)view
{
return YES;
}

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];

Get selected button value from the UIButton

From the array I am creating button with the array values inside each button, Here I want to place a radio button before each button. while clicking the radio button i want to get it selected or not. In the below code I can display the button and the radio button image but cannot get the selected button value. How can i get the radio button selected or not for each button
//My Array
labelArrays = [NSMutableArray arrayWithObjects:#"one", #"two", #"three",#"four",#"five",#"six", nil];
//Creating button with placing a radio button image inside
-(void) createbutton:(CGRect) frame {
CGFloat xCoordinate = frame.origin.x;
CGFloat yCoordinate = frame.origin.y;
CGFloat buttonHeight = frame.size.height;
CGFloat buttonWidth = frame.size.width;
CGFloat gapBetweenTwoButton = 2;
for(int counter = 0; counter < [labelArrays count]; counter++) {
button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button =[UIColor clearcolor];
[button setFrame:CGRectMake(xCoordinate,yCoordinate, 100, 40)];
NSString* titre = [labelArrays objectAtIndex:counter];
[button setImage:[UIImage imageNamed:#"radio_selected.png"] forState:UIControlStateNormal];
button.titleEdgeInsets = UIEdgeInsetsMake(0,10,0,0);
[button setTitle:[NSString stringWithFormat:#"%#",titre] forState:UIControlStateNormal];
[button setUserInteractionEnabled:YES];
[self. button addTarget: self action: #selector(buttonAction:)forControlEvents: UIControlEventTouchUpInside];
[self addSubview: button];
if((counter+1)%3 == 0) {
xCoordinate = 0;
yCoordinate = yCoordinate + buttonHeight + gapBetweenTwobutton;
xCoordinate = xCoordinate + buttonWidth + gapBetweenTwoLabels;
}
}
//my frame
[self createbutton:CGRectMake(32,20,220,40)];
It's very simple to get selected button value by using its tag value. See here and try below code.
Put these line in viewDidLoad()
labelArrays = [NSMutableArray arrayWithObjects:#"one", #"two", #"three", #"four", #"five", #"six", nil];
[self createButtons];
And then define these methods.
- (void)createButtons
{
int x = 30, y = 20;
for (int i = 0; i<labelArrays.count; i++)
{
UIButton *btnImage = [UIButton buttonWithType:UIButtonTypeCustom];
btnImage.frame = CGRectMake(x, y, 100, 40);
btnImage.backgroundColor = [UIColor redColor];
btnImage.tag = 700+i;
[btnImage setImage:[UIImage imageNamed:#"radio_unselect.png"] forState:UIControlStateNormal];
btnImage.titleEdgeInsets = UIEdgeInsetsMake(0, 10, 0, 0);
[btnImage setTitle:[NSString stringWithFormat:#"%#", [labelArrays objectAtIndex:i]] forState:UIControlStateNormal];
[btnImage addTarget: self action: #selector(changeValue:)forControlEvents: UIControlEventTouchUpInside];
[self.view addSubview:btnImage];
if ((i+1)%2 == 0)
{
x = 30;
y = y+btnImage.frame.size.height+10;
}
else
{
x = x+btnImage.frame.size.width+30;
}
}
}
- (IBAction)changeValue:(UIButton *)sender
{
UIButton *btn = (UIButton *)[self.view viewWithTag:sender.tag];
if (btn.selected == TRUE)
{
[btn setImage:[UIImage imageNamed:#"radio_unselect.png"] forState:UIControlStateNormal];
btn.selected = FALSE;
}
else
{
[btn setImage:[UIImage imageNamed:#"radio_select.png"] forState:UIControlStateNormal];
btn.selected = TRUE;
NSLog(#"%#", btn.titleLabel.text);
}
}

get tag of UIButton and those with smaller tags

I'm not understanding if what I'm trying to do is possible or not.
I am creating buttons in for loop:
CGRect rect2 = CGRectMake(50, 230, 40, 40);
for (int i = 0; i<5; i++) {
NSString *stringI = [NSString stringWithFormat:#"%d",i+1];
NSString *stringItouch = [NSString stringWithFormat:#"%dselected",i+1];
UIButton *button = [[UIButton alloc] init];
[button setBackgroundImage:[UIImage imageNamed:stringI] forState:UIControlStateNormal];
[button setBackgroundImage:[UIImage imageNamed:stringItouch] forState:UIControlStateSelected];
[button addTarget:self action:#selector(touchButton:) forControlEvents:UIControlEventTouchUpInside];
button.tag = i+1;
button.frame = rect2;
rect2.origin.x = rect2.origin.x + 45;
[scrollView addSubview:button];
}
and after in method touchButton i get the tag of touched button
-(void)touchButton:(id)sender {
UIButton *buttonSender = sender;
buttonSender.selected = YES;
NSLog(#"button tag %#",buttonSender.tag);
for (int i = buttonSender.tag-1; i>0; i--) {
NSLog(#"int = %d",i);
//for example if buttonSender.tag is 4, in this way i have 3,2,1
}
}
in the last loop i want to select the buttons that have the tag less than that touched (in this case 3,2,1)
is it possible or not???
thanks everybody
All you need is viewWithTag: like so:
-(void)touchButton:(id)sender {
UIButton *buttonSender = sender;
buttonSender.selected = YES;
NSLog(#"button tag %#",buttonSender.tag);
for (int i = buttonSender.tag-1; i>0; i--) {
NSLog(#"int = %d",i);
//for example if buttonSender.tag is 4, in this way i have 3,2,1
/* Add this line */
UIButton *tempButton = (UIButton *)[scrollView viewWithTag:i];
}
}

where are the labels among the buttons

In the image below I am attempting to put a single-character label between each button, but as the second image shows, when I do insert the labels, the buttons disappear and (if you look closely) the last button's text moves to the right.
Can you help me get the desired result, please?
buttons without labels
buttons with labels
ViewController.h
#property(nonatomic,assign) UILabel* theSuit;
ViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
NSString* cards = #"AKQJT98765432";
NSInteger yPipsOrigin = 100;
NSInteger xPipsOrigin = 100;
NSInteger xPipsStep = 40.0;
NSInteger xPipsCurrent = xPipsOrigin;
// Do any additional setup after loading the view.
for( int x=0;x<[cards length]; x++ ){
[cards substringWithRange:NSMakeRange(x,1)];
UIButton *b= [UIButton buttonWithType:UIButtonTypeRoundedRect];
xPipsCurrent += xPipsStep;
[b setTitle:[cards substringWithRange:NSMakeRange(x,1)] forState:UIControlStateNormal];
[b setTitle:#" " forState:UIControlStateDisabled];
[b setFrame:CGRectMake(xPipsCurrent, yPipsOrigin, 20, 20)];
[b setEnabled:YES];
[b setUserInteractionEnabled:YES];
[self.view addSubview:b];
[b addTarget:self action:#selector(spadeButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
xPipsCurrent = xPipsOrigin + xPipsStep/2;
for( int x=0;x<[cards length]-1; x++ ){
xPipsCurrent += xPipsStep;
UILabel *lab = self.theSuit;
lab.text = #"Z";
lab.backgroundColor = [UIColor clearColor];
lab.center = CGPointMake(xPipsCurrent, yPipsOrigin);
[self.view addSubview:lab];
}
}
}
NSString* cards = #"AKQJT98765432";
NSInteger yPipsOrigin = 100;
NSInteger xPipsOrigin = 100;
NSInteger xPipsStep = 40.0;
NSInteger xPipsCurrent = xPipsOrigin;
for( int x=0;x<[cards length]; x++ )
{
[cards substringWithRange:NSMakeRange(x,1)];
UIButton *b= [UIButton buttonWithType:UIButtonTypeRoundedRect];
xPipsCurrent += xPipsStep;
[b setTitle:[cards substringWithRange:NSMakeRange(x,1)] forState:UIControlStateNormal];
[b setTitle:#" " forState:UIControlStateDisabled];
[b setFrame:CGRectMake(xPipsCurrent, yPipsOrigin, 20, 20)];
[b setEnabled:YES];
[b setUserInteractionEnabled:YES];
[self.view addSubview:b];
[b addTarget:self action:#selector(spadeButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
UILabel *lab = [[UILabel alloc] initWithFrame:CGRectMake(xPipsCurrent+b.frame.size.width, yPipsOrigin, 20, 20)];
lab.text = #"Z";
lab.textAlignment = NSTextAlignmentCenter;
lab.backgroundColor = [UIColor clearColor];
[self.view addSubview:lab];
}

Resources