1

I have an NSMutableArray that contains objects of type Person. The Person object contains parameters of NSString *name, NSString *dateStamp, and NSString *testScore. What I would like to do using fast enumeration, is display the parameters of each object as UILabels on a row in a view, with each object being displayed on each row.

The problem is that the NSMutableArray may hold any number of objects, and therefore there may be one or two rows of labels on the view, or several rows on the view. I want to create a for loop that will dynamically populate the view with each object on a line (and consistently spaced), as well as allow the user to scroll down to see any rows that are further down and cannot be seen initially on the screen.

My for loop looks like this:

for (Person *checkPerson in personList) {
    UILabel *label1 =  [[UILabel alloc] initWithFrame: CGRectMake(10, 10, 50, 20)];
    label1.text = Person.name;

    UILabel *label2 =  [[UILabel alloc] initWithFrame: CGRectMake(70, 10, 50, 20)];
    label2.text = Person.dateStamp;

    UILabel *label3 =  [[UILabel alloc] initWithFrame: CGRectMake(130, 10, 50, 20)];
    label3.text = Person.testScore;

    [self.view addSubView:label1];
    [self.view addSubView:label2]; 
    [self.view addSubView:label3];
 }

What I need to do is dynamically adjust the "y" value in the CGRectMake field such that each object is sequentially moved down on another line as the NSMutableArray is iterated, and such that the user is able to scroll down to further see additional rows if necessary. Is the scrolling feature added automatically?

halfer
  • 19,824
  • 17
  • 99
  • 186
syedfa
  • 2,801
  • 1
  • 41
  • 74
  • 1
    Why dont you use [UITableView](http://developer.apple.com/library/ios/#documentation/uikit/reference/UITableView_Class/Reference/Reference.html) if you want to show labels in different rows? – iDev Dec 17 '12 at 20:22

2 Answers2

2

you should do block enumeration, as this gives you also an index, that you can use to calculate y

[personList enumerateObjectsUsingBlock:^(Person *person, NSUInteger idx, BOOL *stop) {
    UILabel *label1 =  [[UILabel alloc] initWithFrame: CGRectMake(10, 10+20*idx , 50, 20)];
    label1.text = person.name;
    UILabel *label2 =  [[UILabel alloc] initWithFrame: CGRectMake(70, 10+20 *idx, 50, 20)];
    label2.text = person.dateStamp;

    UILabel *label3 =  [[UILabel alloc] initWithFrame: CGRectMake(130, 10+20*idx, 50, 20)];
    label3.text = person.testScore;

    [self.view addSubView:label1];
    [self.view addSubView:label2]; 
    [self.view addSubView:label3];
}];

You should place them on an UIScrollView, where you set the contentSize according to the number of elements in the array.

scrollView.contentSize = CGSizeMake(<width>, [personList count] / 3 *30);

You also should consider using an UITableView. It might be easier and cell re-use keeps the memory usage low.

vikingosegundo
  • 52,040
  • 14
  • 137
  • 178
  • Thanks very much for your reply. Does the value of idx represent each index of the NSMutableArray? With respect to the value of do I leave that as it is, or do I actually have to specify it? – syedfa Dec 17 '12 at 20:22
  • idx is passed to the block while the elements are enumerated – vikingosegundo Dec 17 '12 at 20:24
  • 2
    you also should consider using an UITableView. It might be easier and cell re-use keeps the memory usage low. – vikingosegundo Dec 17 '12 at 20:26
  • Thanks again for your detailed solution. I guess I am going to have to look into using UITableView as a better alternative. :-) – syedfa Dec 17 '12 at 20:38
  • [«WWDC 2011, Session 309 — Introducing Interface Builder Storyboarding»](https://developer.apple.com/videos/wwdc/2011/?id=309) might be interesting for you. it shows, how you can easily populate custom cells with subviews. – vikingosegundo Dec 17 '12 at 22:13
0

just add an y variable to you code and increase it after each iteration

CGFloat y = 10;
for (Person *checkPerson in personList) {
    UILabel *label1 =  [[UILabel alloc] initWithFrame: CGRectMake(10, y, 50, 20)];
    label1.text = Person.name;

    UILabel *label2 =  [[UILabel alloc] initWithFrame: CGRectMake(70, y, 50, 20)];
    label2.text = Person.dateStamp;

    UILabel *label3 =  [[UILabel alloc] initWithFrame: CGRectMake(130, y, 50, 20)];
    label3.text = Person.testScore;

    [self.view addSubView:label1];
    [self.view addSubView:label2]; 
    [self.view addSubView:label3];

    y+=80;
 }

but as other said, a UITableView is destined for tasks like these :D

Daij-Djan
  • 49,552
  • 17
  • 113
  • 135