Adding multiple UIButtons to an UIView - iphone

I've added some buttons to an UIView (via addSubview) programmatically. However, they appear as overlays (so that I always see the last button only). How do I add new buttons below existing buttons?
Regards

you can offset the button like this
int newX = previousButton.frame.origin.x + previousButton.frame.size.width ;
int newY = previousButton.frame.origin.y ;
and either set the frame for new button when you create it:
[[UIButton alloc] initWithFrame:CGRectMake(newX,newY,100,100)];
or set the frame later
newButton.frame = CGRectMake(newX,newY,100,100);

Set the UIView's frame origin to layout the UIButtons in the locations you wish:
CGRect buttonFrame = button.frame;
buttonFrame.origin = CGPointMake(100.0f, 100.0f);
button.frame = buttonFrame;
view.addSubview(button);

You can either use the insertSubview:atIndex method or insertSubview:belowSubview of your view.
UIButton *myButton = [[UIButton alloc] initWithFrame:CGRectMake(0,0,100,100)];
[myView insertSubview:myButton belowSubview:previousButton];
OR
[myView insertSubview:myButton atIndex:0];

Thanks for your answers guys.
I did the (horizontal) align with this code:
if([myContainer.subviews lastObject] == nil){
NSLog(#"NIL");
[myContainer insertSubview:roundedButton atIndex:0];
}else{
[myContainer insertSubview:roundedButton belowSubview:[tagsContainer.subviews lastObject]];
}
It works technically, but still overlays the buttons. I have to find a way, how to not overlay them...

Related

Hide programmatically created UISlider

I've programmatically created a UISlider in viewDidLoad using the following code and when a button is pressed I want to hide the object and maybe use it again. I can't seem to get it to work. I've tried a number of approaches which all build correctly but none of which have the desired effect.
CGRect frame1 = CGRectMake(-5.0, 290.0, 100.0, 10.0);
UISlider *sliderSaveurFloral = [[UISlider alloc] initWithFrame:frame1];
[sliderSaveurFloral addTarget:self action:#selector(sliderAction:) forControlEvents:UIControlEventValueChanged];
[sliderSaveurFloral setBackgroundColor:[UIColor clearColor]];
sliderSaveurFloral.minimumValue = 0.0;
sliderSaveurFloral.maximumValue = 50.0;
sliderSaveurFloral.continuous = YES;
sliderSaveurFloral.value = 0.0;
[self.view addSubview:sliderSaveurFloral];
CGAffineTransform trans2 = CGAffineTransformMakeRotation(M_PI * -0.5);
sliderSaveurFloral.transform = trans2;
[sliderSaveurFloral setValue:0];
UISlider inherits from UIView. I believe you can set the hidden property to make it invisible.
sliderSaveurFloral.hidden = YES; //Set it back to NO when you want it appear again
You may also have to make it not interactive when hidden,
sliderSaveurFloral.userInteractionEnabled = NO; //Set it back to YES later when you need

How to add View below other view in ViewController in iOS?

In my app i am creating view controller with mixed of UILabel and UITextview which want to be scrollable because the text are dynamic and also exceeds vertical screen size.
I am currently having Scrollview which has subviews as below. Views are created in Xcode 4.3 Storyboard.
UILabel1(Say Heading)
UITextView1(Dynamic text which can be any size)
UILabel2(Second Heading)
UITextView2(Dynamic text which can be any size)
and so on.
The problem is
When the UITextView1 has more content then it overlaps with UILabel2 which i don't want.
I would like to have UILabel1 on top of scrollView and UITextView1 below the UILabel1. UILabel2 below UITextView1 and so on.
What i have to do to achieve this?
EDIT
In Storyboard
![enter image description here][1]
In Simulator
![enter image description here][2]
Thanks for your help guys. Much appreciated.
Code
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
[scrollView setScrollEnabled:YES];
[self.view addSubview:cockTailNameLabel];
[self.view insertSubview:txtIngredients belowSubview:cockTailNameLabel];
[self.view insertSubview:scrollView belowSubview:cockTailNameLabel];
//[scrollView]
[self.cockTailNameLabel setText:self.passcockTailName];
[_txtUse setText:self.passUse];
[_txtUse setEditable:NO];
[_txtUse setUserInteractionEnabled:NO];
CGRect useFrame = _txtUse.frame;
useFrame.size.height = _txtUse.contentSize.height;
_txtUse.frame = useFrame;
[txtIngredients setText:self.passIngredients];
[txtIngredients setEditable:NO];
[txtIngredients setUserInteractionEnabled:NO];
CGRect ingredientFrame = txtIngredients.frame;
ingredientFrame.size.height = txtIngredients.contentSize.height;
txtIngredients.frame = ingredientFrame;
[txtRecipe setText:self.passReceipe];
[txtRecipe setEditable:NO];
[txtRecipe setUserInteractionEnabled:NO];
CGRect recipeFrame = txtIngredients.frame;
recipeFrame.size.height = txtRecipe.contentSize.height;
txtRecipe.frame = recipeFrame;
[scrollView insertSubview:_txtUse belowSubview:cockTailNameLabel];
[scrollView insertSubview:titleIngredients belowSubview:_txtUse];
[scrollView insertSubview:txtIngredients belowSubview:titleIngredients];
[scrollView insertSubview:btnReceipe belowSubview:txtIngredients];
[scrollView insertSubview:btnHome belowSubview:txtIngredients];
[scrollView insertSubview:txtRecipe belowSubview:btnHome];
[scrollView insertSubview:btnfacebookShare belowSubview:txtRecipe];
[scrollView insertSubview:btnTwitterShare belowSubview:txtRecipe];
/*[scrollView addSubview:_txtUse];
[scrollView addSubview:titleIngredients];
[scrollView addSubview:txtIngredients];
[scrollView addSubview:btnReceipe];
[scrollView addSubview:btnHome];
[scrollView addSubview:txtRecipe];
[scrollView addSubview:btnfacebookShare];
[scrollView addSubview:btnTwitterShare];*/
[scrollView setContentSize:CGSizeMake(320, 1000)];
NSLog(#"RecipeName :%# ",passcockTailName);
}
In Storyboard or IB you can rearrange them freely.
In code you do - (void)insertSubview:(UIView *)view belowSubview:(UIView *)siblingSubview.
In code (in viewDidLoad):
UIScrollView *scroll =[[UIScrollView alloc] initWithFrame:CGrectMake(0,0 320, 480)];
[self.view addSubview:scroll];
// code to init your UI object
UILabel *uilabel1 = [[UIlabel alloc] initWithFrame:CGrectMake(10,10, 100, 40)]; // example
uilabel1.font = [UIFont systemFontOfSize:10];
uilabel1.text = #"UILabel1";
uilabel1.backgroundColor = [UIColor clearColor];
//
//
UILabel *uilabel2 = [[UIlabel alloc] initWithFrame:CGrectMake(10, 10 + 10 + uilabel1.frame.origin.y, 100, 40)]; // example
uilabel2.font = [UIFont systemFontOfSize:10];
uilabel2.text = #"UILabel2";
uilabel2.backgroundColor = [UIColor clearColor];
//
//
[scroll addSubview:uilabel1];
[uilabel1 releale];
[scroll addSubview:uilabel2];
[uilabel2 releale];
//
//
// in end
float offset = 10.0 * 2; // offset between uiobjects, N - number of objects
scroll.contentSize = CGSizeMake (0, 0, uilabel1.frame.size.height + uilabel2.frame.size.height + offset, 320);
Note that you may set frame (and other properties) of yours uiobjects and adds it in order to descend.
You can tell next view to start from the end of the first view like so:
startYOfNextView = firstView.frame.origin.y position + firstView.frame.size.height;
Do the same for the rest of the other view. If your view has variable text length, you may need to precaculate the height of the string based on a specific font e.g.:
CGSize maxSize = CGSizeMake(widthOfView, 9999999);
CGSize expectedSize = CGSizeMake(stringVar sizeWithFont:[UIFont fontWithName:#"Arial"] withMaxSize:maxSize lineBreakMode:UILineBreakModeWordWrap);
then tell your dynamic view to use the height of expectedSize variable like so:
myDynamicView = [[UILabel alloc] initWithFrame:CGRectMake(..., expectedSize.height)];
Your issue is labels are coming on top of the textview (Overlapped), right?
In This case, you are modifying the height of the textview dynamically. If its just for display purpose you can set the text to a UILabel with numberOfLines = 0 instead of UITextview; As its added to scrollview adding a label will be fine.
Also you need to modify the origin.y of the remaining views so that it will be properly aligned. ie, secondView.origin.y = firstView.origin.y + firstView.size.height + offset. Likewise modify the origin of the remaining views wrt the just above view. So that its origin will lie outside the previous view frame.
In my case I had to project it over the parent view, so remember there is also something,
- (void)insertSubview:(UIView *)view aboveSubview:(UIView *)siblingSubview
I think adding a transparent UI button is the fastest solution. You could add it once and then show / hide whenever you need to disable all views below the current one (assuming the "current" view, say a popup, was added last to your superview).
Declare an instance variable UIButton* _parentDisablingOverlay; in your popup view, then add this in its init or layoutSubviews method:
_parentDisablingOverlay = [[UIButton alloc] initWithFrame:CGRectMake(0,0, self.superview.frame.size.width, self.superview.frame.size.height)];
[self.superview insertSubview:_parentDisablingOverlay belowSubview:self];
_parentDisablingOverlay.hidden = true;
Later on, when you want to show the popup and disable everything below:
- (void) open {
self.hidden = false;
_parentDisablingOverlay.hidden = false;
}
Similarly to close and re-enable everything:
- (void) close {
self.hidden = true;
_parentDisablingOverlay.hidden = true;
}

Setting the position of setImage and setTitle of UIButton

I want to have a large button the spans the length of my table cells that contains a setImage icon on the right and a setTitle on the left. However, what happens by default is that everything is aligned to the left.
Is there a way to change the position of the UIButton image and title views? I want everything to be in one button so that if someone clicks the title the icon will change its state as well.
Make your image the same size as the button (i.e. pad it out with transparency) so things go where you want them to be. Say you have an image that 40 x 40, but you want it on the right side of a button 300 x 40. Just increase the size of the image with transparency to have 260 pixels of nothing on the left. For your text, you can use the alignment icons in Interface builder to put the title where you want it.
What I did was subclass UIButton and set [self titleLabel] and [self imageView] in the layoutSubview method.
#import "CustomDetailTableButton.h"
#implementation CustomDetailTableButton
- (void)layoutSubviews
{
[super layoutSubviews];
UILabel *titleLabel = [self titleLabel];
CGRect fr = [titleLabel frame];
fr.origin.x = 10.0;
fr.origin.y = 5.0;
[[self titleLabel] setFrame:fr];
UIImageView *imageView = [self imageView];
CGRect iFrame = [imageView frame];
iFrame.origin.x = 300.0;
iFrame.origin.y = 7.0;
[[self imageView] setFrame:iFrame];
}
#end

UIButton - changing frame alters response to touches

I have a UIButton. I found that when I moved it, it no longer responded to touches. Let me explain in detail how I determined this: when I shift a 100pixel width button by 50 pixels to the right, only the left half responded to my finger tapping it.
How do I tell the button "update your touches checker" when I dynamically change the frame of it? I am changing the frame in code, NOT in xib.
Initialization:
MATCGlossyButton *repeat = [[MATCGlossyButton alloc] init];
[repeat addTarget:self action:#selector(repeatPressed:) forControlEvents:UIControlEventTouchUpInside];
[repeat setTitle:#"Repeat" forState:UIControlStateNormal];
repeat.buttonColor = [UIColor brownColor];
repeat.backgroundColor = [UIColor clearColor];
repeat.cornerRadius = 20;
repeat.frame = CGRectMake(200,208,105,50);
And then later on:
repeat.frame = CGRectMake(265, 208, 105, 50);
Is it possible you are moving the button beyond the bounds of its parent view? Even if clipping is off, touches aren't propagated outside of a view.
An easy way to visualise the borders of your views is to do the folowing:
#import <QuartzCore/QuartzCore.h>
[...]
view.layer.borderWidth = 1;
view.layer.borderColor = [UIColor redColor].CGColor;

Dynamic Button Layout without hard coding positions

I would like to implement a view (it will actually be going into the footer of a UITableView) that implements 1-3 buttons. I would like the layout of these buttons (and the size of the buttons themselves) to change depending on which ones are showing. An example of almost the exact behavior I would want is at the bottom of the Info screen in the Contacts application when you are looking at a specific contact ("Add to Favorites" disappears when it is clicked, and the other buttons expand to take up the available space in a nice animation).
As I'm running through the different layout scenarios, I'm hard coding all these values and I just think... "this is NOT the way I'm supposed to be doing this."
It even APPEARS that Interface Builder has some features that may do this for me in the ruler tab, but I'll be darned if I can figure out how they work (if they work) on the phone.
Does anyone have any suggestions, or a tutorial online that I could look at to point me in the right direction?
Thanks much.
You could take a look at
Stanford cs193p classes
I think there is a demo in one of the lessons/example where they programaticaly set the autoresize of the buttons and some other where they animate the view.
you can also make the view set dynamically the width of each of its subview to (ownWidth/numberofSubView),the same for the positon of each elements.
[edit] like that ? it's not "dynamic" yet, but you've got the idea
you can increase/decrease numberOfbuttons when "adding/removing" a button then reset the new frame of all the subviews
- (void)loadView
{
UIView *view = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
view.backgroundColor = [UIColor lightGrayColor];
view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
int numberOfbuttons = 2;
CGFloat buttonsLegth = (-20+view.bounds.size.width)/numberOfbuttons-20;
for(int i=0;i<numberOfbuttons;i++){
CGRect buttonFrame = CGRectMake(0, 0, buttonsLegth, 37);
buttonFrame.origin.x = (buttonFrame.size.width+20)*i + 20.0;
buttonFrame.origin.y = 20.0;
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect]; // Autoreleased
button.frame = buttonFrame;
[button setTitle:#"Done" forState:UIControlStateNormal];
[view addSubview:button];
}
self.view = view;
[view release];
}
hi remove all buttons in view and add again using this method...
you have to pass number of buttons and a UIView in which you want to add these buttons
-(void)addButtons:(int)numberOfButtons ToView:(UIView *)containerView;
{
CGRect containerRect = containerView.frame;
CGFloat padding = 5.0;
CGFloat width = (containerRect.size.width - (padding*numberOfButtons+1))/numberOfButtons;
for (int i = 1; i<=numberOfButtons; i++)
{
UIButton * btn = [[[UIButton alloc] initWithFrame:CGRectMake(i*padding+width, 0, width, containerRect.size.height)]autorelease];
//set Button Properties like Target,backColor,Title,,,,etc MUST SET TAG TO ACCESS THEM IN CLICK METHOD IF YOU ARE USING SAME SELECTOR FOR ALL BUTTONS.
[containerView addSubview:btn];
}
}
Try this and have fun......