Create textfields based on user input - objective-c

I want to create textfields based on user input. Let's say 5 textfield are needed
for (int x = 0; x < self.howMany; x++)
{
NSLog(#"%i", x_position);
self.textFieldRounded = [[UITextField alloc] initWithFrame:CGRectMake(10, x_position, 300, 25)];
self.textFieldRounded.borderStyle = UITextBorderStyleRoundedRect;
self.textFieldRounded.textColor = [UIColor blackColor]; //text color
self.textFieldRounded.font = [UIFont systemFontOfSize:17.0]; //font size
[self.view addSubview:self.textFieldRounded];
x_position += 30;
}
So far, so good. That code create five textfields. The problem is that these textfields are not "unique". Each of these textfield can contain different information. What to do so that I can gather information of each of these fields ?

Add a tag to them.
int i = 1;
for (int x = 0; x < self.howMany; x++)
{
NSLog(#"%i", x_position);
self.textFieldRounded = [[UITextField alloc] initWithFrame:CGRectMake(10, x_position, 300, 25)];
textFieldRounded.tag = i++;
...
And then, when you need to find textfield 3 for example, do:
UITextField *textField = (UITextField *)[self.view viewWithTag:3];

You could set a tag for each text field.
self.textFieldRounded.tag = x;
Then you can use the tag to identify your text fields. You can iterate through self.view to find all subviews (text fields) using this technique.

I think you should take different TextField for each information so that everything should be clear and if you still want to use one text field then you can set the tag for each info.

You could add a reference to each TextField in an NSMutableArray and then iterate through the array using something like
for (UITextField *tmp in myArray) {
//do stuff with the textfield
}

Related

Adjust content in UIScrollView

Hello to all I created a UIScrollView that shows a series of UIView that represent graifici according to your entry ...
The multiplication of view was performed using a FOR loop
for (NSInteger i = 0; i < value.count; i ++) {
UILabel *valueX_label = [[UILabel alloc] initWithFrame:CGRectMake(xPadding, self.scrollChart.frame.size.height-30, 50, 30)];
NSString *valueText = [value objectAtIndex:i];
valueX_label.text = [NSString stringWithFormat:#"%#", valueText];
valueX_label.textColor = [UIColor whiteColor];
valueX_label.font = [UIFont fontWithName:#"HelveticaNeue" size:9];
valueX_label.textAlignment = NSTextAlignmentCenter;
valueX_label.numberOfLines = 2;
[self.scrollChart addSubview:valueX_label];
xPadding += valueX_label.frame.size.width;
self.scrollChart.contentSize = CGSizeMake(xPadding, self.scrollChart.frame.size.height);
_backgroundBar = [[UIView alloc] initWithFrame:CGRectMake(valueX_label.center.x - 20 , 13, 40, (self.scrollChart.frame.size.height - valueX_label.frame.size.height) -10)];
_backgroundBar.backgroundColor = [UIColor grayColor];
_backgroundBar.layer.cornerRadius = 2;
_backgroundBar.alpha = .1;
[self.scrollChart addSubview:_backgroundBar];}
  Now I have a problem ... After entering the paging of ScrollView I have some display problems, ie each size page a few columns as you can see from the pictures ...
I need each page displays only six columns at a time ... you can help me in any way?
Wrong pagination
Ok pagination

Objective C - How to create a set of sub views to update

Perhaps I am thinking about this incorrectly, so please point me in the right direction..
I want to make many UIViews as a property so I can update them with different methods. Something like this:
#property UIView *view1
#property UIView *view2
...
#property UIView *view200
-(void)updateViews{
for (i=0; i <200; i++){
//Update view here
}
So my questions are:
How can I easily make multiple views?
How can I easily pass a message to each individual view?
So many great responses, I think I need to add a little more info.
Have tried putting my UIViews into an array to index them but I struggle to access them to update their positions within the UIViewController. I thought making them a property is the correct way to since I need to update them with the device heading. Looks like using a tag might be best. Can someone further comment on this approach:
for (i = 0 ; i < 144; i++) {
UIView *sunView =[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"sun.png"]];
sunView.tag = i;
}
//then later, in a separate method do the following:
for (i = 0 ; i < 144; i++) {
CGFloat CGx = self.acceleration.X;
CGFloat CGy = self.acceleration.Y
[sunView.tag.i setFrame:CGRectMake(CGx, CGy, 20, 20)]
}
Im not sure how to access the UView with the corresponding indexed tag. Can someone help me there too?
When they are really subviews then you could iterate through the superview's subviews array.
You could do that recursievely in order to apply it on all subivews of your subviews, if you have multiple hierarchy levels.
If you don't want to apply this to each of your superview's subviews, then tag your subviews with something like view.tag = 6502 and use that to identify those views to which you want to apply it.
Or maintain your own array or set (iterable collection) of views and iterate through them.
Create your views in a loop and store them in an NSMutableArray. That way you will have access to all of them in your view controller.
Create a property.
#property (monatomic) NSMutableArray *arrayOfViews;
self.arrayOfViews = [[NSMutableArray alloc] init];
UIView *view;
for (int i = 0; i < 10; i++)
{
view = [[UIView alloc] init];
[self.arrayOfViews addObject:view];
}
Run a loop over this array and access the views one by one and call the method you need to call.
On a side note: Why are you creating 200 UIViews? That's a lot :)
I think you need something like that:
-(void)updateViews
{
UIView *views;
UILabel *label;
for(int i = 0 ; i < numberOfViews ; i++)
{
views = [[UIView alloc] initWithFrame:CGRectMake(...)];
label = [[UILabel alloc] initWithFrame:CGRectMake(0,0,views.frame.size.width,views.frame.size.height)];
[label setText:[NSString stringWithFormat:#"%d",i]];
[views addSubview:label];
[self.view addSubview:views];
}
}
How can I easily make multiple views?
Do you want to create it in IB?
1) You can use tags in Xcode
UILabel * label = (UILabel*)[self.view viewWithTag:19];
UIView * view = (UIView*)[self.view viewWithTag:20];
2) You can use property that you also do
How can I easily pass a message to each individual view?
if your views inside another view(currentView) you can use that
for (UIView *yourView in self.currentView.subviews) {
//Update view here
}
Or if you want to create it in the code
for (int i = 0; i < 10; i++)
{
UIView * myView = [[UIView alloc]initWithFrame:CGRectMake(10*i, 10*i, 25, 25)];
int r = arc4random() % 255;
int g = arc4random() % 255;
int b = arc4random() % 255;
myView.backgroundColor = [UIColor colorWithRed:r/255.0 green:g/255.0 blue:b/255.0 alpha:1];
[self.view addSubview: myView];
}
That's what you can see
And to call all these views you can use
for (UIView *yourView in self.view.subviews) {
[yourView removeFromSuperview];
}
And that's what you'll see
If you want to call own view you can use tags like this
for (int i = 0; i < 10; i++)
{
UIView * myView = [[UIView alloc]initWithFrame:CGRectMake(10*i, 10*i, 25, 25)];
myView.tag = i + 21;
int r = arc4random() % 255;
int g = arc4random() % 255;
int b = arc4random() % 255;
myView.backgroundColor = [UIColor colorWithRed:r/255.0 green:g/255.0 blue:b/255.0 alpha:1];
[self.view addSubview: myView];
}
for (UIView *yourView in self.view.subviews) {
if (yourView.tag == 21) {
[yourView removeFromSuperview];
}
}

How do I save a UILabel's properties in a NSMutableArray?

For example,
-(void)drawHypnoticMessage:(NSString *)message{
....
UILabel messageLabel = [[UILabel alloc]init];
messageLabel.backgroundColor = [UIColor clearColor];
messageLabel.textColor = [UIColor whiteColor];
messageLabel.text = message;
[messageLabel sizeToFit];
int width = (int)(self.view.bounds.size.width - messageLabel.bounds.size.width);
int x = arc4random() % width;
int height = (int)(self.view.bounds.size.height - messageLabel.bounds.size.height);
int y = arc4random() % height;
CGRect frame = messageLabel.frame;
frame.origin = CGPointMake(x,y);
messageLabel.frame = frame;
[self.view addSubview:messageLabel];
...}
I want to be able to add this label "messageLabel" to a NSMutable array like this:
NSMutableArray *thisArray;
[thisArray addObject:messageLabel];
and then access it later after STATE RESTORATION like this:
UILabel *thisLabel = [thisArray objectAtIndex:0];
[self.view addSubview: thisLabel];
For some reason, when I try to access the UILabel stored inside the NSMutableArray, the text in ---> thisLabel.text <--- shows up empty. In Addition, all the properties in the --->thisLabel<--- also shows up empty when I try to access it again after STATE RESTORATION.
such as:
--->thisLabel.textColor<---- shows up empty.
--->thisLabel.frame <---- shows up empty.
Can anybody help me solve this quirk? It's really frustrating.
I want to be able to add this label "messageLabel" to a NSMutable
array like this:
NSMutableArray *thisArray;
[thisArray addObject:messageLabel];
Did you remember to first say
thisArray = [[NSMutableArray alloc]init];

adding buttons below the other

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

How to place "x" number of objects on the view

If the user provides a number, such as 8, how exactly would I place eight labels onto the view?
For example:
int userGivenNumber = textfield.text;
for (int labelNumber=1; i<=userGivenNumber; i++) {
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(50, *previousLabel*.frame.origin.y + 20)];
}
How would you get the location of previousLabel? Additionally, if the user wanted to edit a label, such as label 3, how would I edit this label?
The problem is that I don't know how many labels they want to place while coding, and I have no way of keeping track of the labels, since they are called label. Do you have any ideas? Do you understand what I am asking? Thanks for your help.
- (void)addLabels {
CGFloat offset = 0;
// labels is NSMutableArray property
labels = [[NSMutableArray alloc] initWithCapacity:8];
for (int i = 0; i < 8; i++) {
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, offset, 320, 20)];
[self.view addSubview:label];
[labels addObject:label];
offset += label.frame.size.height;
}
}
Edit: Like jerrylroberts said, to access the label array from elsewhere in your code, you should declare it as a property.
So you could add the views like so:
int userGivenNumber = [textfield.text intValue];
for (int labelNumber=1; i<=userGivenNumber; i++) {
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(50, *previousLabel*.frame.origin.y + 20)];
[self.view addSubview:label];
[label release];
}
If you wanted to keep track of them you could just create a mutable array as a property and then add each label to the array before you add to the subview;
Interface
#property (nonatomic, retain) NSMutableArray *addedLabels;
Implementation
#synthesize addedLabels=_addedLabels;
- (void)viewDidLoad
[super viewDidLoad];
// Create your array to hold labels
NSMutableArray *addedLabels = [[NSMutableArray alloc] initWithCapacity:0];
self.addedLabels = addedLabels;
[addedLabels release];
// NOW put your code
int userGivenNumber = [textfield.text intValue];
for (int labelNumber=1; i<=userGivenNumber; i++) {
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(50, *previousLabel*.frame.origin.y + 20)];
[self.view addSubview:label];
[addedLabels addObject:label];
[label release];
}
}
Now you can easily access any label you have added if you have the index. Hope this helps
Just keep a reference to the location (CGPoint) outside the loop, but update it inside the loop to the current label's location. When you assign the next frame do your operation depending on width and size of the label, and don't forget to update the reference of CGPoint.