iOS - addSubview without overlap - ios

In a for loop, I'm trying to add Labels to a ScrollView based on a number given by the user. Here is the code in Objective-C:
NSInteger numberOfViews = [self.textfieldNumViews.text intValue];
for (int i = 0; i < numberOfViews ; i++){
UILabel *label = [[UILabel alloc] initWithFrame: CGRectMake(0, 0, 300, 12)];
label.text = [NSString stringWithFormat:#"%d",i];
label.backgroundColor = [UIColor lightGrayColor];
[self.scrollviewViewContainer addSubview:label];
}
The problem is that the labels are overlapping each other inside the ScrollView, when I really want them to just display one after the other.
Image I understand that this is due to how addSubview behaves, placing views on top of other views, but is there any way I can prevent that? Or some other function I could use? I feel like this should be an easy task but I can't seem to figure it out. Is there something like a vertical layout property I can add to the ScrollView? Or add margins to the labels?

You need to set the y lower for each subview. Check the third line:
NSInteger numberOfViews = [self.textfieldNumViews.text intValue];
for (int i = 0; i < numberOfViews ; i++){
UILabel *label = [[UILabel alloc] initWithFrame: CGRectMake(0, (i*20), 300, 12];
label.text = [NSString stringWithFormat:#"%d",i];
label.backgroundColor = [UIColor lightGrayColor];
[self.scrollviewViewContainer addSubview:label];
}

Related

Create controls in UIView at runtime?

I have one UITextField and a button in a view.
Once a button is pressed, value in text field need to be searched fieldID column in core data table and get value[comma separated].
Separate the string by comma and assign values to array.
A new UIView needs to be inserted in the main screen and place N number[count of array] of labels and textfields and align.
I am able to do 1, 2 and UIView creation.
Can anybody help me to create N number of controls in sub UIView at runtime?
for(int i=0;i<self.yourArray.count; i++)
{
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(10,80*i+60,self.view.frame.size.width-20,60)];
label.text = [yourArray objectAtIndex:i];
[self.view addSubview:label];
}
Please Explain your problem more clearly !
May be your array count is very large so take a scroll view also in your view
UIScrollView* yourScrollView = [[UIScrollView alloc]initWithFrame:CGRectMake(yourView.frame.origin.x, yourView.frame.origin.y,yourView.frame.size.width,yourView.frame.size.height)];
for(int i= 0; i< 10;i++)
{
UILabel* lbl = [[UILabel alloc]initWithFrame:CGRectMake(10, y, 50, 21)];
lbl.text = #"";
UITextField* txtField = [[UITextField alloc]initWithFrame:CGRectMake(lbl.frame.origin.x+10 , y, 200, 21)];
txtField.text = #"";
[yourScrollView addSubview:lbl];
[yourScrollView addSubview:txtField];
y = y+30;
}
[yourView addSubview:yourScrollView];

How to customze UISlider to get stepps visible

I want to customize my UISlider to be able to show steps like in photo attached (BTW this is a font size selector, native control from my iPhone settings). I able to set images for min and max but I can't show steps. I don't need 3rd party libraries to do this, I'm sure that it's possible to customize UISlider to have this.
Please help.
Thanks in advance.
You can add some subviews behind the slider to display the steps:
int numSteps = 5;
for(int i=0; i<numSteps; i++){
CGFloat x = i*CGRectGetWidth(slider.frame)/(numSteps-1);
UIView *v = [[UIView alloc] initWithFrame:CGRectMake(x, CGRectGetMidY(slider.frame)-5, 1, 10)];
v.backgroundColor = [UIColor lightGrayColor];
[slider.superview insertSubView:v belowSubview:slider];
UILabel numberLabel = [[UILabel alloc] init];
numberLabel.text = [NSString stringWithFormat:#"%i",i];
numberLabel.font = [UIFont systemFontOfSize:13];
[numberLabel sizeToFit];
numberLabel.center = CGPointMake(x, CGRectGetMidY(slider.frame)+CGRectGetHeight(numberLabel.frame)/2+7);
[slider.superview insertSubView:numberLabel belowSubview:slider];
}

Insert NSArray of strings into UILabel and count by 1.

How Would I insert an array of strings into UILabel, and have them load or count by 1?
I'm trying to load the following array into the UILabel:
self.array = [NSArray arrayWithObjects:#"Testing 1",#"Testing 2",#"Testing 3", nil];
Here I am using an UIScrollView that automatically changes from each slide to each slide:
for (int i=1; i<=3; i++) {
// create label
UILabel *text = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width,30)];
text.text = [NSString stringWithFormat:#"%#", self.array];
text.font=[UIFont fontWithName:#"HelveticaNeueLTStd-LtCn" size:15];
text.textColor = [UIColor darkGrayColor];
text.textAlignment =NSTextAlignmentCenter;
// create imageView
UIImageView *lblView = [[UIImageView alloc] initWithFrame:CGRectMake((i-1)*scrMain.frame.size.width, 325, 280, 240)];
// set label
[lblView addSubview:text];
// apply tag to access in future
lblView.tag=i+1;
// add to scrollView
[scrMain addSubview:lblView];
}
I have an example of how to do it with UIImageView:
for (int i=1; i<=3; i++) {
// create image
UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:#"sti%02i.png",i]];
// create imageView
UIImageView *imgV = [[UIImageView alloc] initWithFrame:CGRectMake((i-1)*scrMain.frame.size.width + 23, 60, 280, 260)];
// set scale to fill
imgV.contentMode=UIViewContentModeScaleToFill;
// set image
[imgV setImage:image];
// apply tag to access in future
imgV.tag=i+1;
// add to scrollView
[scrMain addSubview:imgV];
}
The images are in my project and are numbered sti01, sti02, and so on... It then counts by one for each images and then loads them into the scrollview. I hope this helps!
The y-position of the label should be adjusted according to the index.
You can use the array count instead of a fixed '3'.
You don't need an UIImageView in between.
You can try this:
for (int i = 0; i < self.array.count; i++) {
// create label
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, i*30, self.view.frame.size.width,30)];
label.text = [self.array objectAtIndex:i];
label.font = [UIFont fontWithName:#"HelveticaNeueLTStd-LtCn" size:15];
label.textColor = [UIColor darkGrayColor];
label.textAlignment = NSTextAlignmentCenter;
// add to scrollView
[scrMain addSubview:label];
}
If I'm understanding you correctly, you need to make the following change:
text.text = [NSString stringWithFormat:#"%#", [self.array objectAtIndex:i]];
This will pull out the ith object from your array of strings and set that as the text of your UILabel.
Why don't you loop through the array instead of trying to assign the text to the whole array like this:
for (int i=0; i<3; i++) {
// create label
UILabel *text = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width,30)];
text.text = [NSString stringWithFormat:#"%#", [self.array objectAtIndex:i]];
text.font=[UIFont fontWithName:#"HelveticaNeueLTStd-LtCn" size:15];
text.textColor = [UIColor darkGrayColor];
text.textAlignment =NSTextAlignmentCenter;
// create imageView
UIImageView *lblView = [[UIImageView alloc] initWithFrame:CGRectMake((i-1)*scrMain.frame.size.width, 325, 280, 240)];
// set label
[lblView addSubview:text];
// apply tag to access in future
lblView.tag=i+1;
// add to scrollView
[scrMain addSubview:lblView];
}
That way you're just pulling that one string out, assigning it as the UILabel's text, then adding it as a subview to the appropriate imageView.

How to arrange dynamically created UILabels inside UIView? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Closed 9 years ago.
Improve this question
I am dynamically creating UILabels from an array using a for loop.
Each UILabel has a different length. When I created the UILabels, they are overlapping one another.
I want to arrange those UILabels properly inside the UIView without any overlapping. Any help?
You can find how it works here: arrange labels sources link
Download sources using appropriate button on site
Open ArrangeLabels project
Open ViewController.m file
Check -createElements -fitElements methods from the sources.
If you want you can view sources here immediately in your browser: link to code
You can do it using sizeToFit and numberOfLines=0
int y=0;
for (int k=0; k<[array count]; k++)
{
UILabel *lb=[[UILabel alloc]initWithFrame:CGRectMake(5 , y, 100,60)];
lb.textAlignment=UITextAlignmentLeft;
lb.text=[array objejectAtIndex:k];
lb.numberOfLines=0;
[lb sizeToFit];
[self.view addSubview:lb];
y+=lb.frame.size.height;
}
Try to implement this logic:
-(void)adjustLabel1Text1:(NSString *)text1
{
UILabel *lbl_first = [UIFont fontWithName:#"Helvetica" size:12];
text1 = [text1 stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
float hedingLblHeight = [self calculateHeightOfTextFromWidth:text1 : [UIFont fontWithName:#"Helvetica" size:12] :118 :UILineBreakModeWordWrap];
lbl_first.text=text1;
[lbl_first setFrame:CGRectMake(lbl_first.frame.origin.x, lbl_first.frame.origin.y, 118, hedingLblHeight)];
lbl_first.lineBreakMode = UILineBreakModeWordWrap;
lbl_first.numberOfLines = 0;
[lbl_first sizeToFit];
//////////Adjust the lable or any UIControl below this label accordingly.
float endResultHeight=[self calculateHeightOfTextFromWidth:text2 : [UIFont fontWithName:#"Helvetica" size:15] :299 :UILineBreakModeWordWrap];
if(hedingLblHeight>secondImgTitleHeight)
{
[lbl_endResult setFrame:CGRectMake(lbl_endResult.frame.origin.x, lbl_first.frame.origin.y+lbl_first.frame.size.height+5, 299, endResultHeight)];
}
else
{
[lbl_endResult setFrame:CGRectMake(lbl_endResult.frame.origin.x, lbl_first.frame.origin.y+lbl_first.frame.size.height+5, 299, endResultHeight)];
}
lbl_endResult.lineBreakMode=UILineBreakModeWordWrap;
lbl_endResult.numberOfLines = 0;
[lbl_endResult sizeToFit];
}
-(float) calculateHeightOfTextFromWidth:(NSString*)text : (UIFont*) withFont:(float)width :(UILineBreakMode)lineBreakMode
{
CGSize suggestedSize = [text sizeWithFont:withFont constrainedToSize:CGSizeMake(width, FLT_MAX) lineBreakMode:lineBreakMode];
return suggestedSize.height;
}
It has helped me a lot.Hope it works for you.
You need to change y coordinate of your label like this
UILabel *hiLbl = [[UILabel alloc] initWithFrame:CGRectMake(0,10,50,20)];
hiLbl.text = #"Hi";
[self.view addSubview:hiLbl];
UILabel *hellolbl = [[UILabel alloc] initWithFrame:CGRectMake(0,30,50,20)];
hellolbl.text = #"Hi";
[self.view addSubview:hellolbl];
or
UILabel *lbl;
for(int i = 1 ; i < 3 ; i++)
{
lbl = [[UILabel alloc] initWithFrame:CGRectMake(0,i*10+10,50,20)];
[self.view addSubview:lbl];
lbl.text = i;
}
Without any screenshot it is difficult to guess what type of overlapping you are referring to. And length of UILabel does not help, either specify- width or height.
But if you are talking about width of UILabel, then this piece of code may help you.
Lets you have three labels of different widths, which are in an array of widths array:{ 10, 20, 30}.
float width = [array objectAtIndex:0];
float x = 0.of;
float padding = 10.0f;
for(int i =0; i<3; i++){
UILabel *label = [UILabel alloc]initWithFrame:CGRectMake(x, y, width, height)];
[self.view addSubview: label];
x = x + width + paddng;
width = [array objectAtIndex:i + 1];
}

how to access dynamically created uilabel in iphone

I have created dynamic UILabel with tag value and i have similar kind of other labels without tag values.
Now i want access only tag values labels but i was not able to acces the label text value.
Here is my code.
Dynamic created Label
for (int i= 0; i < [array count]; i++) {
UILabel *defaultLbl = [[UILabel alloc] initWithFrame:CGRectMake(30, 70, 60, 21)];
defaultLbl.text = #"Default";
defaultLbl.backgroundColor = [UIColor clearColor];
defaultLbl.textColor = [UIColor colorWithRed:51.0/255.0 green:51.0/255.0 blue:51.0/255.0 alpha:1.0];
[defaultLbl setFont:[UIFont fontWithName:#"Helvetica" size:12]];
defaultLbl.textAlignment = NSTextAlignmentCenter;
defaultLbl.tag = i+1;
[myButton addSubview:defaultLbl];
[defaultLbl release];
UILabel *masterProName = [[UILabel alloc] initWithFrame:CGRectMake(28, 20, 200, 21)];
masterProName.text = [masterProjListArray objectAtIndex:i];//#"Lorem Ipusum";
masterProName.backgroundColor = [UIColor clearColor];
masterProName.textColor = [UIColor colorWithRed:51.0/255.0 green:153.0/255.0 blue:204.0/255.0 alpha:1.0];
[masterProName setFont:[UIFont fontWithName:#"Helvetica-Bold" size:17]];
masterProName.lineBreakMode = NSLineBreakByCharWrapping;
[myButton addSubview:masterProName];
[masterProName release];
UILabel *masterProID = [[UILabel alloc] initWithFrame:CGRectMake(28, 45, 200, 21)];
masterProID.text = [masterProjIDArray objectAtIndex:i];//#"133 FS";
masterProID.backgroundColor = [UIColor clearColor];
masterProID.textColor = [UIColor colorWithRed:51.0/255.0 green:51.0/255.0 blue:51.0/255.0 alpha:1.0];;
[masterProID setFont:[UIFont fontWithName:#"Helvetica" size:17]];
masterProID.lineBreakMode = NSLineBreakByCharWrapping;
[myButton addSubview:masterProID];
[masterProID release];
}
And UILabel access method after user press the long press button
- (void)longPressTap:(UILongPressGestureRecognizer *)sender
{
if ([recognizer.view tag]) {
UILabel *view = (UILabel *)recognizer.view;
NSLog(#"---%#", view.subviews);
for (UILabel *lbl in view.subviews) {
if (recognizer.view.tag == view.tag) {
NSString *text = view.text;
NSLog(#"---%#", text);
}
}
}
}
here am putting the log
"<UIImageView: 0x75b9510; frame = (0 0; 379 100); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x75acef0>>",
"<UILabel: 0x88c4e50; frame = (28 20; 200 21); text = 'Aux Water Waste Trtmnt'; clipsToBounds = YES; userInteractionEnabled = NO; layer = <CALayer: 0x88c49c0>>",
"<UILabel: 0x88c52f0; frame = (28 45; 200 21); text = 'M10000'; clipsToBounds = YES; userInteractionEnabled = NO; layer = <CALayer: 0x88c5380>>",
"<UILabel: 0x88c56c0; frame = (30 70; 60 21); text = '**Default**'; clipsToBounds = YES; userInteractionEnabled = NO; tag = 1; layer = <CALayer: 0x88c5750>>",
"<UIButton: 0x88c6440; frame = (240 10; 70 80); opaque = NO; userInteractionEnabled = NO; tag = 1; layer = <CALayer: 0x88c6500>>"
In this log i want to access only "Default" text label
Please give me any suggestion on this.
Well, you need to know which value the tag has of the lable with "Default" in its text. Let's assume it is 42. Then
UILabel *label = [view viewWithTag:42];
would do the trick.
Anyway your solution should work too. Have a look at the actual tag values that you are dealing with. i've got a guts feeling that recognizer.view.tag does not have the same value as the tag of the label with "Default" in it.
You can also create outlets of those at runtime.
Create an array, and go on to add outlets of each label.
Once you are done and need to retrieve them you can easily access by index of arrays.
Even you can create a dictionary for storing outlets, here you can access labels by keys.
As you are assigning tag to UILabel, we can get label from tag (if it known to us, in your case we know).
So give it a try this way
for (int i = 0 ; i <[array count]; i++)
{
UILabel *lbl = (UILabel*)[self.view viewWithTag:i+1];
NSLog(#"--- %#", lbl.text);
}
for get UILabel base on its Tag.
Take int i; in .h file,
And put i=1; in above for Loop
for (NSObject *view in self.View.subviews)
{
if ([view isKindOfClass:[UILabel class]])
{
label = (UILabel *)[[self view] viewWithTag:i];
NSLof(#"%#".label.text);
// break;
}
i++;
}
Firstly, you should be checking
if (lbl.tag == view.tag)
not
if (recognizer.view.tag == view.tag)
Secondly, it won't work anyway. All that does is identify the view that has been touched which you know. How about setting the tag value in the label you want to a unique number and testing
if (lbl.tag == <unique tag number>)

Resources