The view with no name (Xcode for...in statement)

Let's suppose that you've dragged out a random number of UIView objects onto your View Controller in your app's Storyboard. Now we want to change their attributes but we don't necessarily want to bother giving each one a named pointer.

Here's what we'd do in the corresponding ViewController.m file. First we'd gather an array of subviews for the current view:

NSArray *subviews = [self.view subviews];


Next we'd do something like set all the backgrounds to blue with a for...in loop


    for (UIView* v in subviews) {
        
            v.backgroundColor=[UIColor blueColor];};
  
}

The v is an arbitrary variable name, and on each run through the loop it iterates to become one greater, just as if we'd written:

  
    int i;

 for (i=0; i<subviews.count; i++) {

        

     [[subviews objectAtIndex:i] setBackgroundColor:[UIColor blueColor]];};




The latter just takes longer to type and creates more code to read.

So here we have the whole thing in the viewDidLoad: method of our ViewController.m file:

- (void)viewDidLoad
{
    [super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
    
    NSArray *subviews = [self.view subviews];
    

    for (UIView* v in subviews) {
            v.backgroundColor=[UIColor blueColor];}
  
}

It is a very short amount of code. If we didn't want the same background colour for every UIView we could add an if...else statement:

- (void)viewDidLoad
{
    [super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
    
    NSArray *subviews = [self.view subviews];
    
   int i = 0;
    for (UIView* v in subviews) {
        
        if (i%2==0){
            v.backgroundColor=[UIColor blueColor];
    

        }
        else {
            v.backgroundColor=[UIColor redColor];}
        i++;};

  
}

Or add in a UIImageView and picture:

NSArray *subviews = [self.view subviews];
    
    for (UIView* v in subviews) {
        
                    UIImageView *picture = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"picture1.jpg"]];
            picture.bounds = v.bounds;
            [v addSubview:picture];
            };


And with a little imagination we could move from here to include a range of sequentially numbered pictures:

- (void)viewDidLoad

{

    [super viewDidLoad];
    


NSArray *subviews = [self.view subviews];

    

   int i = 0;
    for (UIView* v in subviews) {
        

            UIImageView *picture = [[UIImageView alloc] initWithImage:[UIImage imageNamed:[NSString stringWithFormat:@"%@%d%@", @"picture",i,@".jpg"]]];
            picture.bounds = v.bounds;
            [v addSubview:picture];
   

        i++;};

}
  

As long as you have enough pictures with the filenames picture0.jpg, picture1.jpg, picture2.jpg.... to fill the number of views you have the app will work. (To add pictures to your project drag and drop from Finder and make sure you tick the top box to copy items in the dialogue window that appears.)


Remember there is nothing stopping you from accessing the views manually from the subviews array with 

[subviews objectAtIndex:0], [subviews objectAtIndex:2]... 

instead of using a loop.


Comments