Identifying the name of a class during run time - objective-c

So I have run into a fairly complex problem with my application.
I have about 40 UIImageView objects that need to be displayed at different locations when different ones are stacked (EX img 1 needs to take img 2 place if img2 ==NO).
What I am trying to do is use a "for loop" and run through all my Boolean values that check if the image is selected.
I was curious if it is at all possible to call variable like this
-(IBAction) button:(id) sender{
scrollView.hidden = YES;
NSInteger i = 1;
(#"imagenumber%d", i) = [[UIImageView alloc] initWithFrame: CGRectMake (28, 230, 86, 26)];
[[imagenumber(#"%d", i)] setImage:[UIImage imageNamed:#"csa.jpg"]];
[self.view addSubview: [imagenumber(#"%d", i)]];}
}
where #"imagenumber%d" is my NSImageView and i is a number ranging from 1-40.
I'm sorry if this is confusing, I really would appreciate any help at all on the subject because I can’t seem to get any idea and have been working on this problem for several weeks.

Put the views in a NSMutableArray - you can access elements in those by index, use fast enumeration, ... E.g.:
UIImageView *image = [[UIImageView alloc] ...
[myMutableArray addObject:image];
// ...

For the sake of hilarity you could also put them in a intrinsic array and use pointer arithmetic. (Which is probably what happens behind the scenes with faster enumeration for those interested)
UIImageView * imageArray[40];
...
for(UIImageView * this = imageArray; this; this++)
{
this = [[UIImageView alloc] initWithFrame: CGRectMake (28, 230, 86, 26)];
...
}

Related

Only last image is loading from url in scrollview

In my iOS app I have have a lots of view and image and labels are the subviews of the. view. My problem is while loading images from url or remote server only last image is loading from url . Other images are loaded with placeholders. Tried many ways but unable to solve it . My code and screenshot are provided below
catScrollView=[[UIScrollView alloc]initWithFrame:CGRectMake(0, 10, self.view.frame.size.width,300)];
catScrollView.contentSize = CGSizeMake(([popularCategoryArray count] * 90)/1.8 + 10, catScrollView.frame.size.height);
[_parentScrollView addSubview:catScrollView];
catScrollView.backgroundColor=UIColorFromRGB(0xE8F7FE);
catScrollView.userInteractionEnabled=YES;
catScrollView.scrollEnabled=YES;
catScrollView.delegate=self;
for(int i =0;i<[popularCategoryArray count];i++)
{
Category* category=[popularCategoryArray objectAtIndex:i];
UIView *catView = [[UIView alloc] init];
if(i>=[popularCategoryArray count]/2+1)
{
catView.frame = CGRectMake(10 + y * 100, 4*10+90+10, 90, 120);
y++;
}
else
{
catView.frame = CGRectMake(10 + x * 100, 10, 90, 120);
x=i;
}
imageCat=[[UIImageView alloc]initWithFrame:CGRectMake(10, 0, 70, 90)];
imageCat.backgroundColor=[UIColor clearColor];
[imageCat sd_setImageWithURL:[NSURL URLWithString:category.ImageURL]
placeholderImage:[UIImage imageNamed:#"wish_list"]];
[catView addSubview:imageCat];
UILabel *labelCat=[[UILabel alloc]initWithFrame:CGRectMake(0, 95, catView.frame.size.width, 25)];
labelCat.backgroundColor=[UIColor clearColor];
labelCat.text=category.BngTitle;
labelCat.textAlignment=NSTextAlignmentCenter;
labelCat.font=[UIFont fontWithName:#"HelveticaNeue-Thin" size:12.0];
[catView addSubview:labelCat];
catView.backgroundColor=[UIColor clearColor];
[catScrollView addSubview:catView];
}
Screenshot
What is happening is that in UIView+Webcache.m's sd_internalSetImageWithURL method, the following code is executed on every run through your loop.
NSString *validOperationKey = operationKey ?: NSStringFromClass([self class]);
[self sd_cancelImageLoadOperationWithKey:validOperationKey];
The operationKey is always the same because in your default invocation it is not set, so it's possed as nil, and when it's nill it's just the class name. SDWebImage has a very aggressive policy of cancelling all previous requests that way.
Some people believe it only does that for multiple requests of the same URL, but this code does not vary on URL so that may be a bug or not. Your best bet may be to call the sd_internalSetImageWithURL method and set your own operationKey (something with a number in it so that they're all different).

Animating a UIImageView with a mask but the mask is static

I am trying to have an animation in which a mask is placed in the center of the view. Any image view that passes behind the mask appears. So here is my code so far, but the problem with this code is that it animates the mask with the image view.
UIView *maskView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.worldImageView.frame.size.height, self.worldImageView.frame.size.height)];
// ...position maskView...
maskView.layer.position = CGPointMake(CGRectGetMidX([self.view bounds]), CGRectGetMidY([self.view bounds]));
maskView.layer.backgroundColor = [UIColor blackColor].CGColor;
maskView.layer.cornerRadius = 90;
self.worldImage = [[UIImageView alloc] init];
self.worldImage.frame = self.worldImageView.frame;
self.worldImage.image = [UIImage imageNamed:#"continents.png"];
[maskView addSubview:self.worldImage];
[self.view addSubview:maskView];
CABasicAnimation* worldAnimation = [[CABasicAnimation alloc] init];
[worldAnimation setFromValue:[NSValue valueWithCGPoint:CGPointMake(self.view.frame.size.width + 50, CGRectGetMidY([maskView bounds]))]];
[worldAnimation setToValue:[NSValue valueWithCGPoint:CGPointMake(-50, CGRectGetMidY([maskView bounds]))]];
worldAnimation.keyPath = #"position";
worldAnimation.duration = 6.0f;
worldAnimation.repeatCount = HUGE_VALF;
[[self.worldImage layer] addAnimation:worldAnimation forKey:nil];
I don't know if I explained this well enough. Please tell me if you need more info. Thank you in advance!
Your issue here is that the mask property of UIView is attached to that UIView - they can't move separately. Technically, it's actually attached to the view's underlying layer, but whatever.
If you want the image to appear as if it's passing in front of a circular window (so that you can see it as it goes by) you'll need to add it as a subview of the view with the mask. So, you might do something like this:
UIView *maskView = [[UIView alloc] init];
// ...position maskView...
maskView.layer.cornerRadius = 90;
maskView.clipsToBounds = YES;
self.worldImage = [[UIImageView alloc] init];
self.worldImage.frame = self.worldImageView.frame;
self.worldImage.image = [UIImage imageNamed:#"continents.png"];
[maskView addSubview:self.worldImage];
[self.view addSubview:maskView];
// ...animate worldImage back and forth...
Note that instead of using a CAShapeLayer, I simply put rounded corners on maskView; since you want a circular mask, it's a much simpler trick. Also, when animating worldImage, consider using one of UIView's block-based animation methods – they're a lot easier to handle for simple stuff like this.

NSMutableArray objects being lost

I hope this makes sense...I have an NSMutableArray that I'm attempting to store multiple UIScrollView's in. Each UIScrollView is going to have multiple images and the ultimate goal is to be able to allow the user to swipe vertically for categories (each instance of UIScrollView) and horizontally for each image in that category (each instance of UIImageView). For now, until I get this code to work, I'm just creating 1 UIScrollView with 1 image and I'm adding that to scrollViewManager. This seems to add everything correctly, but when I leave this function, game over. My Array is empty. I don't understand. Am I supposed to do some sort of deep copy when I add to the Array so it doesn't get destroyed. Perhaps I'll figure it out when I wake up tomorrow, but for now, I'd like to break everything in sight. Thanks, in advance!
EDIT: Sorry for lack of details, I posted this rather late. My project is using ARC, so I'm not releasing scrollView anywhere. Here is the declaration for scrollViewManager in my header file:
#property (nonatomic, retain) NSMutableArray *scrollViewManager;
Here is the code I use to retrieve my scrollView:
UIScrollView *test = (UIScrollView*) [self.scrollViewManager objectAtIndex: 0];
And here is the code to initialize the scrollView and array:
scrollViewManager = [[NSMutableArray alloc] initWithCapacity: 1];
UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
[scrollView setBackgroundColor:[UIColor blackColor]];
[scrollView setCanCancelContentTouches:NO];
scrollView.indicatorStyle = UIScrollViewIndicatorStyleWhite;
scrollView.clipsToBounds = YES; // default is NO, we want to restrict drawing within our scrollview
scrollView.scrollEnabled = YES;
scrollView.pagingEnabled = YES;
NSString *imageName = #"pic1.png";//[NSString stringWithFormat:#"pic%d.jpg", i+1];
UIImage *image = [UIImage imageNamed:imageName];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
// setup each frame to a default height and width, it will be properly placed when we call "updateScrollList"
CGRect rect = imageView.frame;
rect.size.height = 400;
rect.size.width = 300;
imageView.frame = rect;
imageView.tag = 1; // tag our images for later use when we place them in serial fashion
[scrollView addSubview:imageView];
[self.scrollViewManager addObject: scrollView];
There are some things that are kind of vague. For example:
Are you using ARC, if not and you are releasing your scrollView anywhere?
Are you using the auto-create-synthesize thing?
What type of property is your scrollViewManager (weak, strong, etc).
If you are creating your ivars automatically when defining a property, your ivar should be called _scrollViewManager instead of scrollViewManager.
The use of self.scrollViewManager is correct when using this method.
I always do this kind of stuff the other way around. When I have a property like this:
#property (nonatomic, strong) NSMutableArray* myArray;
I always initialize them using the self keyword:
self.myArray = [NSMutableArray new];
And when modifying it, I always use the generated ivar:
[_myArray addObject:myFineObject];
I think this is something I kept using when moving from non-ARC to ARC. Not sure if it still the way to go, but it works like expected.

Adding individual UIImageViews for each item in an array

I am trying to add a individual UiImageView for each item in an array this is what I have so far
_shapeArray = [NSArray arrayWithObjects:#"cloud.png",#"star.png", nil];
for (int i = 0; i < [_shapeArray count]; i++){
// I make a UIImage, which I will draw later
UIImage* image = [UIImage imageNamed:[NSString stringWithFormat:#"%#",[_shapeArray objectAtIndex:i]]];
UIImageView* blockView = [[UIImageView alloc] initWithImage:image];
blockView.frame = CGRectMake(arc4random()%320, arc4random()%460, image.size.width, image.size.height);
[self.view addSubview:blockView];
}
But as you can tell it just adds the last image in the array. I can not figure out a way to maybe add the array object number to the name of the UIImageView. Maybe I am going at it the wrong way, if so what would be the best way?
This code works, but you need to make sure of a couple of things:
- That the file name actually exists in your bundle (check for uppercase/lowercase), you would not get an error message if it didn't, but it would not show the picture
- That the image sizes are not too large and don't cover each other
You are adding the images in the same frame.
blockView.frame = CGRectMake(arc4random()%320+SomeXValue, arc4random()%460+SomeYvalue, image.size.width, image.size.height);

Subclass of UIPageControl refresh only after uiscrollview move, not before

the problem I've met today is with my subclass of UIPageControl. When I initialize it, the frame (specifically the origin) and image of dots stays default, which is the problem, since I want it to change right after initialization. However, when I move with scrollView (as in "touch and move") after initialization, they (the dots) somehow jump to the right position with correct images.
What could be the problem?
Code:
CustomPageControl.m
- (id) initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
activeImage = [UIImage imageNamed:#"doton.png"];
inactiveImage = [UIImage imageNamed:#"dotoff.png"];
return self;
}
- (void) updateDots
{
for (int i = 0; i < [self.subviews count]; i++)
{
UIImageView *dot = [self.subviews objectAtIndex:i];
if (i == self.currentPage) dot.image = activeImage;
else dot.image = inactiveImage;
[dot setFrame:CGRectMake(i * 13.5, 1.5, 17, 17)];
}
}
- (void)setCurrentPage:(NSInteger)currentPage
{
[super setCurrentPage:currentPage];
[self updateDots];
}
#end
ChoosingView.m - init part
scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 160, 300)];
[scrollView setBackgroundColor:[UIColor clearColor]];
[scrollView setDelaysContentTouches:NO];
[scrollView setCanCancelContentTouches:YES];
[scrollView setClipsToBounds:NO];
[scrollView setScrollEnabled:YES];
[scrollView setPagingEnabled:YES];
[scrollView setShowsHorizontalScrollIndicator:NO];
[scrollView setShowsVerticalScrollIndicator:NO];
pageControl = [[CustomPageControl alloc] initWithFrame:CGRectMake(200, 300, 80, 20)];
[pageControl setBackgroundColor:[UIColor clearColor]];
pageControl.numberOfPages = 6;
[pageControl setCurrentPage:0];
the last line is when I would expect the UIPageControl to refresh, however that does not happen.
Does this happen with the standard UIPageControl implementation?
Your problem states that your objects subViews (eg the UIImageViews) rects/size are not initialising to your desired size/position.
I implemented this code in my project with a nib rather than programmatically and I needed to call -(void)updateDots to set it as its initial condition was the standard dots..
I dont see how the UIScrollView has any bearing impact on this unless somehow its linked to your -(void)updateDots function (E.g. your setting the currentIndex of your custom page control). You state, "However, when I move with scrollView (as in "touch and move") after initialization, they (the dots) somehow jump to the right position with correct images."
Because they "jump to the right position with correct images" it means that your -(void)updateDots function must be getting called. I dont see any other explanation.
Also your iteration loop assumes that all the UIViews in your .subViews array are UIImageViews, although fairly safe to assume this, I would check to see if the UIView is a UIImageView with reflection.