0

I have been trying to code something that has a for loop from 0 through 3 that changes 3 different UIImageView's using their row number.

The first one would be called "c1", the second would be called "c2", the third "c3" etc..

These UIImageView's have already been defined in my .h file as well as accessible in my .m file. I have previously simply called it by the variable, but I need to iterate through the for loop to make the process more smooth instead of hardcoding a bunch of lines.

Current code:

 for (int i = 0; i < 3; i++){ 


                NSString *id = [NSString stringWithFormat:@"c%i" , i];


                UIImageView *imageViewInLoop = id;

                [self.imageViewInLoop setImage:[UIImage imageNamed:@"defaultphoto.jpg"]];

            }

No errors come up with this code besides a warning on the third line about initializing a UIImageView with a string. The code executes but the image does not change and nothing is printed to console. Please note before replying that the image and variable are correct as I have successfully manually done it before.

6
  • Can you add correct code? Code that you've added is not correct. (in this code you assign NSString to UIImageView and after that call setImage: method) Commented Mar 5, 2020 at 3:47
  • Sorry. But may be I incorrectly formulated my opinion. You do not use 'imageViewInLoop' after you create it (UIImageView *imageViewInLoop is local variable, but in [self.imageViewInLoop setImage:[UIImage imageNamed:@"defaultphoto.jpg"]]; you use a property, it is different variables). To understand how you can find appropriate UIImageView we should know how you store them, or there in interface they are presented. And what is row number? Is is table, or just vertically layout if UIImageViews with UILabels? Commented Mar 5, 2020 at 3:57
  • Also assign NSString to UIImageView is not good idea. Here should be code looks like that: UIImageView imageViewInLoop = [self getImageViewById:id]; where getImageViewById: returns UIImageView Commented Mar 5, 2020 at 3:59
  • The UIImageView's are just ordered straight across the screen, nothing complex. Only 1 row, I just need to quickly set 3 UIImageViews, the order is not particular or really related to it. Commented Mar 5, 2020 at 4:01
  • I created my UIImageView's in my .h file like this: @property (strong, nonatomic) IBOutlet UIImageView *c1; Commented Mar 5, 2020 at 4:01

3 Answers 3

1

I can see that you are trying to access your three image views by constructing a string that represents their variable name at run time. You can't do this. Probably the simplest approach is to put your three image views into an NSArray; then you can access each image view by enumerating the array:

NSArray *imageViews = @[self.c1,self.c2,self.c3];
for (UIImageView *imageView in imageViews) { 
    [imageViews setImage:[UIImage imageNamed:@"defaultphoto.jpg"]];
}
Sign up to request clarification or add additional context in comments.

7 Comments

Key-Value Coding? (Access to properties by names) It is Objective-C :).
You could, but as with the tag solution you are asking for things to blow up at runtime.
@Paulw11 - this is a superior answer. (Including vs mine... I didn't understand that the OP was struggling to enumerate existing outlets). But I think your case against viewWithTag is overstated. We both would (and I bet, both have) setup a xib to give the aligned views (of homogenous type) a common parent, almost certainly a direct parent. Doing so would neither be "slow" (c'mon!) or dangerous at runtime. I'm sure you've written a substantial volume of iOS code. grep it for viewWithTag. Do you want to bet me a buck that you don't find it? :-)
For future readers, this is a much better answer than KVO, and an ever so slightly better answer than employing tags.
You owe me a dollar. There should never be a reason to go searching for a view by tag. It's 9 pm. You should know where your views are.
|
0

To access to properties by their names, use KeyValueCoding to get imageView by property name use valueForKey: method do:

     for(int i = 0; i < 3; i++){ 

         NSString *id = [NSString stringWithFormat:@"c%i" , i];

         UIImageView *imageViewInLoop = [self valueForKey:id];

         [imageViewInLoop setImage:[UIImage imageNamed:@"defaultphoto.jpg"]];

     }

4 Comments

What happens if you get a type mismatch at run time? You will get a crash with unrecognised selector.
Yes, but you can do it. I've never sad what it is very safety way.
@NMan While this answer uses your initial approach, this is not an approach that I would recommend.
@Paulw11 completely right, to make the code safe, just make some refactor, for example use IBOutlecCollection<UIImageView*> to store pointers to all imageViews. Using of key value coding is not very safety way. After that you will have array with imageViews.
0

I got it, this will work as per your requirements.

Just assign a tag for that three UIImageView like the below

c1.tag=1;
c2.tag=2;
c3.tag=3;

Then you shall assign new images like the below example

for(int i = 0; i < 3; i++){ 

         //NSString *id = [NSString stringWithFormat:@"c%i" , i];
int tagId = i+1;//just to add increment for getting tag which starts from 0, you can change it to zero as well
         //UIImageView *imageViewInLoop = [self valueForKey:id];
         //[imageViewInLoop setImage:[UIImage imageNamed:@"defaultphoto.jpg"]];
[((UIImageView*)[self.view viewWithTag:tagId])setImage:[UIImage imageNamed:@"defaultphoto.jpg"]]; 
     }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.