adding buttons below the other - objective-c

I want to add buttons one below the other. I have this simple code:
- (void)viewDidLoad
{
[super viewDidLoad];
for(int i=0 ; i<9 ; i++)
{
UIButton *myButton = [[UIButton alloc] init];
myButton.frame = CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y, self.view.frame.size.width, self.view.frame.size.height/10); //this "10" i want also dynamically
myButton.backgroundColor = [UIColor blackColor];
[self.view addSubview:myButton];
}
}
Of course i know that it will be draw one on another. But can i do it in the loop without knowing the height (becouse high will depends on how many buttons will be in the loop).
What i want to achieve:

Try This:
- (void)viewDidLoad
{
[super viewDidLoad];
int number = 10;
for(int i=0 ; i<9 ; i++)
{
UIButton *myButton = [[UIButton alloc] init];
myButton.frame = CGRectMake(self.view.frame.origin.x, (self.view.frame.size.height/number)*i + number, self.view.frame.size.width, self.view.frame.size.height/number);
myButton.backgroundColor = [UIColor blackColor];
[self.view addSubview:myButton];
}
}

you need to define the size of the buttons for the correct show, unfortunately without the size of the buttons you cannot achieve you wished because how else does the system know what sized button you'd like to show...?
- (void)viewDidLoad
{
[super viewDidLoad];
Float32 _spaceBetweenButtons = 8.f;
Float32 _offsetY = 32.f;
Float32 _buttonWidth = 300.f; // width fo button
Float32 _buttonHeight = 32.f; // height of the button
for (int i = 0 ; i < 9 ; i++) {
UIButton *_myButton = [[UIButton alloc] initWithFrame:CGRectMake(0.f, 0.f, _buttonWidth, _buttonHeight)];
[_myButton setBackgroundColor:[UIColor blackColor]];
[_myButton setTitle:[NSString stringWithFormat:#"button #%d", i] forState:UIControlStateNormal]; // just add some text as title
[self.view addSubview:_myButton];
[_mybutton setCenter:CGPointMake(self.view.frame.size.width / 2.f, _offsetY + i * (myButton.frame.size.height + _spaceBetweenButtons))];
}
}
if you want to calculate the size of the buttons dynamically and you want to align the button's height to the view's height, here would be one way:
NSInteger _numberOfButtons = 20;
Float32 _spaceBetweenButtons = 8.f;
Float32 _calculatedHeight = (self.view.frame.size.height - (_numberOfButtons + 1 * _spaceBetweenButtons)) / _numberOfButtons;
and the method is same as above, but I'm not sure you will get good UI in case of hundreds buttons. :)

Perhaps this might work? Sorry I haven't used self.view.frame in ages, but you get the general idea.
- (void)viewDidLoad
{
[super viewDidLoad];
int number;
for(int i=0 ; i<9 ; i++)
{
UIButton *myButton = [[UIButton alloc] init];
myButton.frame = CGRectMake(i * self.view.frame.origin.x / number,
self.view.frame.origin.y,
self.view.frame.size.width,
self.view.frame.size.height / number); //this "10" i want also dynamically
myButton.backgroundColor = [UIColor blackColor];
[self.view addSubview:myButton];
}
}

Related

UIButton is not setting text

I seem to have a problem in my Objective C iOS app where I am creating multiple buttons depending on the amount of objects in an array. I know Swift, so I replicated the logic into Swift, and it worked. Yet in Objective C, I am unable to see the text of the button (after I remove the for loop) or create multiple buttons. For example, I have an array full of three names. I would like to create a button for each name with the title set to the corresponding name. So far, I have this:
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSMutableArray *ages = [[NSMutableArray alloc] init];
for (int i = 0; i > 10; i++) {
[ages addObject:[NSString stringWithFormat:#"%i", i]];
}
UIScrollView *scrollView= [[UIScrollView alloc]initWithFrame:self.view.frame];
scrollView.delegate= self;
self.automaticallyAdjustsScrollViewInsets= NO;
scrollView.backgroundColor= [UIColor clearColor];
scrollView.scrollEnabled= YES;
scrollView.userInteractionEnabled= YES;
[scrollView setShowsHorizontalScrollIndicator:NO];
[scrollView setShowsVerticalScrollIndicator:NO];
CGFloat xValue = 0;
for(int x=0; x > ages.count; x++){
UIButton *button= [[UIButton alloc] initWithFrame:CGRectMake(xValue ,0 , 172 ,65)];
UIColor *buttonOutline = [[UIColor redColor] CGColor];
button.layer.borderColor = [buttonOutline CGColor];
button.layer.backgroundColor = [[UIColor clearColor] CGColor];
button.layer.borderWidth = 1.0;
button.layer.cornerRadius = 6.0;
[button.titleLabel setFont:[UIFont fontWithName:#"Helvetica" size:13.0]];
button.titleLabel.text = [ages objectAtIndex:x];
[button addTarget:self action:#selector(test:) forControlEvents:UIControlEventTouchUpInside];
[scrollView addSubview:button];
NSLog(#"Button Added");
xValue = button.frame.size.width + 40;
}
scrollView.contentSize = CGSizeMake(xValue, 65);
[self.view addSubview:scrollView];
}
- (void)test:(UIButton*)sender{
NSLog(#"Clicked %#", sender.titleLabel.text);
}
#end
If anyone sees anything wrong with this code, please point it out!
Thanks,
Arnav K.
I found four problems (there may be others) that stop this working correctly:
1) The for loop bound when setting up the ages array is incorrect.
2) The for loop bound when creating the buttons is incorrect.
3) You are setting the buttonOutline colour incorrectly.
4) xValue is being updated incorrectly.
Here is the viewDidLoad method after the changes have been made:
- (void)viewDidLoad {
[super viewDidLoad];
NSMutableArray *ages = [[NSMutableArray alloc] init];
for (int i = 0; i < 10; i++) { // UPDATED
[ages addObject:[NSString stringWithFormat:#"%i", i]];
}
UIScrollView *scrollView= [[UIScrollView alloc]initWithFrame:self.view.frame];
scrollView.delegate= self;
self.automaticallyAdjustsScrollViewInsets= NO;
scrollView.backgroundColor= [UIColor clearColor];
scrollView.scrollEnabled= YES;
scrollView.userInteractionEnabled= YES;
[scrollView setShowsHorizontalScrollIndicator:NO];
[scrollView setShowsVerticalScrollIndicator:NO];
CGFloat xValue = 0;
for(int x=0; x < ages.count; x++){ // UPDATED
UIButton *button= [[UIButton alloc] initWithFrame:CGRectMake(xValue ,0 , 172 ,65)];
UIColor *buttonOutline = [UIColor redColor]; // UPDATED
button.layer.borderColor = [buttonOutline CGColor];
button.layer.backgroundColor = [[UIColor clearColor] CGColor];
button.layer.borderWidth = 1.0;
button.layer.cornerRadius = 6.0;
[button.titleLabel setFont:[UIFont fontWithName:#"Helvetica" size:13.0]];
button.titleLabel.text = [ages objectAtIndex:x];
[button addTarget:self action:#selector(test:) forControlEvents:UIControlEventTouchUpInside];
[scrollView addSubview:button];
NSLog(#"Button Added");
xValue += button.frame.size.width + 40; // UPDATED
}
scrollView.contentSize = CGSizeMake(xValue, 65);
[self.view addSubview:scrollView];
}
I have marked the four lines I changed with a UPDATED comment so you can compare them to the original.
EDIT
To change the text and text colour use the following:
[button setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
[button setTitle:[ages objectAtIndex:x] forState:UIControlStateNormal];
and remove this:
button.titleLabel.text = [ages objectAtIndex:x];
You need to do this because you can set different text for the different states of the button and this is all handled automatically for you.

Horizontal UIScrollView with multiple textfields to display

I'm new to Xcode. I want to make a UIScrollView with multiple pages and each page having multiple UITextFields which vary on each page. I made UIScrollView with paging enabled. Now I'm stuck at displaying textfield's on scroll pages.
Here is my code so far:
//set the paging to yes
self.scrollview.pagingEnabled = YES;
// create 5 pages
NSUInteger numberOfViews = 5;
for (int i = 0; i < numberOfViews; i++)
{
//set the origin of the sub view
CGFloat myOrigin = i * self.view.frame.size.width;
//create the sub view and allocate memory
myView = [[UIView alloc] initWithFrame:CGRectMake(myOrigin, 0, self.view.frame.size.width, self.view.frame.size.height)];
//create a label and add to the sub view
CGRect myFrame = CGRectMake(10.0f, 10.0f, 200.0f, 25.0f);
textLabel = [[UILabel alloc] initWithFrame:myFrame];
textLabel.font = [UIFont boldSystemFontOfSize:16.0f];
textLabel.textAlignment = NSTextAlignmentLeft;
[myView addSubview:textLabel];
//create a text field and add to the sub view
myFrame.origin.y += myFrame.size.height + 10.0f;
textField = [[UITextField alloc] initWithFrame:myFrame];
textField.borderStyle = UITextBorderStyleRoundedRect;
textField.tag = i+1;
[myView addSubview:textField];
//set the background to different color
//set the scroll view delegate to self so that we can listen for changes
self.scrollview.delegate = self;
//add the subview to the scroll view
[self.scrollview addSubview:myView];
}
//scroll horizontally
self.scrollview.contentSize = CGSizeMake(self.view.frame.size.width * numberOfViews,
self.scrollview.frame.size.height);
//we set the origin to the 1rd page
CGPoint scrollPoint = CGPointMake(self.view.frame.size.width * 0, 0);
//change the scroll view offset the the 1rd page so it will start from there
[scrollview setContentOffset:scrollPoint animated:YES];
[self.view addSubview:self.scrollview];
}
Use This code here textfieldCount is
for (int j=0; j < textFieldCount; j++)
{
myFrame.origin.y += myFrame.size.height + 10.0f*(j+1);
UITextField *textField = [[UITextField alloc] initWithFrame:myFrame];
textField.borderStyle = UITextBorderStyleRoundedRect;
textField.tag = j+1;
[myView addSubview:textField];
}
Hope you got your answer.

Issue with scroll view and accessing its subviews

I have a scroll view that contains image view sized 68x78:
As you could see, all that images except from the centered one have a shadow. It changes when user scrolls, center image is always clear. It goes perfect until for the left edge image:
Here is the code:
-(void) buildSlideView{
fotosJugadores = [[NSArray alloc] initWithObjects:#"cara5.png", #"cara7.png", #"cara8.png", #"cara9.png", #"cara11.png", #"cara13.png", #"cara14.png", #"cara15.png", #"cara18.png",#"cara19.png", #"cara20.png", #"cara32.png",#"cara44.png",#"cara51.png", #"cara100.png", #"cara101.png", #"cara102.png",#"cara103.png", #"cara104.png", #"cara105.png",#"cara106.png",#"cara107.png", nil];
numberOfViews = [fotosJugadores count];
for (int i = 0; i < [fotosJugadores count]; i++) {
UIImage *myImage = [UIImage imageNamed:[fotosJugadores objectAtIndex:i]];
CGFloat yOrigin = i * (myImage.size.width+3) + 120;
UIImageView *awesomeView = [[UIImageView alloc] initWithFrame:CGRectMake(yOrigin, 0, myImage.size.width, myImage.size.height)];
awesomeView.tag = i;
awesomeView.image = myImage;
awesomeView.alpha = 0.5f;
awesomeView.backgroundColor = [UIColor blackColor];
[self.jugadorSlide addSubview:awesomeView];
awesomeView=nil;
}
[jugadorSlide setBackgroundColor:[UIColor blackColor]];
jugadorSlide.contentSize = CGSizeMake(68 * numberOfViews+240,78);
jugadorSlide.layer.cornerRadius = 11;
jugadorSlide.layer.masksToBounds = YES;
[jugadorSlide setContentOffset:CGPointMake(((68 * numberOfViews)/2), 0)];
//jugadorSlide.decelerationRate = UIScrollViewDecelerationRateNormal;
[self scrollViewDidEndDragging:jugadorSlide willDecelerate:NO];
}
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
currentIndex = roundf(scrollView.contentOffset.x / 68);
NSLog(#"current end %d", currentIndex);
UIImageView *currentImage = [scrollView viewWithTag:currentIndex];
if (currentIndex>0&&currentIndex<=21){
if (currentIndex==currentImage.tag){
currentImage.alpha=1.0f;
[self changePerfilImage:currentImage.tag];}
CGPoint pointZero= CGPointMake(scrollView.contentOffset.x, currentImage.frame.origin.y);
[jugadorSlide setContentOffset:pointZero animated:YES];
}else {
UIImageView *currentImage = [scrollView viewWithTag:0];
NSLog(#"end dragging image tag %d", currentImage.tag);
currentImage.alpha=1.0f;
[self changePerfilImage:currentImage.tag];}
CGPoint pointZero= CGPointMake(currentImage.frame.origin.x+15, 0);
//[jugadorSlide setContentOffset:pointZero animated:YES];
}
As you can see, in the scrollViewDidEndDragging: "else" , I forced the tag as a desesperate solution, but images doesn't get clear.
You are incrementing the tag twice...
awesomeView.tag = i++;
Should just be:
awesomeView.tag = i+1;
I use i+1 because I never use a tag of 0 since any subview that hasn't been assigned a tag will have a tag of 0.
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
NSInteger currentIndex = roundf(scrollView.contentOffset.x / 68.0) + 1;
UIImageView *currentImage = [scrollView viewWithTag:currentIndex];
...
}
If this doesn't work you should NSLog the currentIndex each time you land on a new image and see what is happening when you land on the first one.

Why is each line of code giving me "invalid context"?

This is my code in which every line is giving me an "invalid context" error when running the app in the iPad Simulator. Every statement after "self.Frame = frame; gives the error. How do I fix it?
- (void)makeFrame:(CGRect)frame number:(NSInteger) number color:(UIColor *) color {
float rd1 = 225.00/255.00;
float gr1 = 102.00/255.00;
float bl1 = 0.00/255.00;
float rd2 = 225.00/255.00;
float gr2 = 153.00/255.00;
float bl2 = 0.00/255.00;
self.frame = frame;
self.backgroundColor = [UIColor colorWithRed:rd1 green:gr1 blue:bl1 alpha:1.0];
[[self layer] setBorderColor:[[UIColor blackColor] CGColor]];
[[self layer] setBorderWidth:0.5];
[[self layer] setCornerRadius:10];
self.tag = number; // set each button's tag
[self setClipsToBounds: YES];
// do date label
date = [[UILabel alloc]initWithFrame:CGRectMake(10, 2, 65, 40 )];
date.backgroundColor = [UIColor clearColor]; // x y w h
date.textColor = [UIColor colorWithRed:rd2 green:gr2 blue:bl2 alpha:1.0];
date.text = [NSString stringWithFormat:#"%d", number];
date.font = [UIFont boldSystemFontOfSize:40];
// date.alpha = 0.2;
[self addSubview:date];
}
And this is the code which calls makeFrame:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
allButtons = [NSMutableArray array];
for(int k = 40, m = 0; m < 6; m++, k+= 42) // this controls the vertical distance between rows
for(int i = 0, j=32; i < 7; i++, j+=102) { // this controls the size and horizontal distance
calendarButton *cb= [calendarButton buttonWithType:UIButtonTypeCustom];
[cb makeFrame:CGRectMake(j, k, 100, 40) number: allButtons.count+1 color:[UIColor orangeColor]];
// x y w h
[self.view addSubview:cb];
[allButtons addObject:cb]; // put it in the array
}
calendarButton *cb= [calendarButton buttonWithType:UIButtonTypeCustom];
[cb drawRect:CGRectMake(0,0, 100, 40)]; // 150
You're manually calling drawRect, which I suspect is causing this problem. From the docs:
You should never call this method directly yourself. To invalidate part of your view, and thus cause that portion to be redrawn, call the setNeedsDisplay or setNeedsDisplayInRect: method instead.
This doesn't look necessary in this case, though. The view has been added as a subview of your view; it will automatically draw itself when your view renders.
You are trying to access view properties in view controller. In your case self is UIViewController (or sublcass), change it to self.view in order to access to view
E.g.
self.view.frame = frame;

UIScrollView only works if the child views aren't hit

I have a scroll view that doesn't scroll right, I've simplified the code for below.
It draws the view and some horizontal buttons that i add more stuff to in the real code.
If you drag the whitespace between the buttons the view scrolls. If you happen to put your finger on a button, it won't scroll.
After a related suggestion, I tried to add the delaysContentTouches = YES line, but it doesn't seem to make a difference.
UIScrollview with UIButtons - how to recreate springboard?
What am I doing wrong?
TIA,
Rob
Updated the code
- (void)viewDidLoad {
l = [self landscapeView];
[self.view addSubview:l];
[l release];
}
- (UIScrollView *) landscapeView {
// LANDSCAPE VIEW
UIScrollView *landscapeView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 320, 325)];
landscapeView.backgroundColor = [UIColor whiteColor];
landscapeView.delaysContentTouches = YES;
NSInteger iMargin, runningY, n;
iMargin = 3;
runningY = iMargin;
for (n = 1; n <= 38; n++) {
//add day labels
UIButton *templabel = [[UIButton alloc] initWithFrame:CGRectMake(iMargin,runningY,320 - ( 2 * iMargin),20)];
templabel.backgroundColor = [UIColor grayColor];
[landscapeView addSubview:templabel];
[templabel release];
runningY = runningY + 30;
}
landscapeView.contentSize = CGSizeMake( 320, runningY);
return landscapeView;
}
I can't duplicate your results; when I create a scrollView and add buttons, scrolling is still active even when doing a touch-down on the button. Are you setting any other UIScrollView properties, or subclassing any methods, that aren't showing up in your simplified code?
It looks like one thing that's going on is that the getter for landScapeView is a complicated constructor...so every time you do [self landscapeView] or self.landscapeView, you're creating a whole new UIScrollView and operating on that.
I'd try something like this in your .h file:
#interface MyClass: MyParent {
UIScrollView *landscapeView;
}
#property (retain) UIScrollView *landscapeView;
...and this in your .m file:
#implementation MyClass
#synthesize landscapeView;
(void)viewDidLoad
{ l = [[[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 320, 325)] autorelease];
[self.view addSubview:self.landscapeView]; [l release];
landscapeView.backgroundColor = [UIColor whiteColor];
landscapeView.delaysContentTouches = YES;
NSInteger iMargin, runningY, n;
iMargin = 3;
runningY = iMargin;
for (n = 1; n <= 38; n++) { //add day labels
UIButton *templabel = [[UIButton alloc] initWithFrame:CGRectMake(iMargin,runningY,320 - ( 2 * iMargin),20)];
templabel.backgroundColor = [UIColor grayColor];
[landscapeView addSubview:templabel];
[templabel release]; runningY = runningY + 30;
}
landscapeView.contentSize = CGSizeMake( 320, runningY);
}