how to add subviews in a 'for' loop - iphone

I'm simply trying to add a UIView for every object in an array without displaying more than 3 on screen but the views aren't next to each other. There is a big gap (one view width) between each view. Here's what I've got;
int numberOfUsersOnScreen;
if (array.count < 3) {
numberOfViewsOnScreen = array.count;
}else{
numberOfUsersOnScreen = 3;
}
double width = (self.scrollView.frame.size.width/numberOfViewsOnScreen);
CGRect r = CGRectMake(0, 0, width, 1200);
[self.usersScrollView setContentSize:CGSizeMake(width*array.count, 0)];
for (int i = 0; i < users.count; i++) {
r.origin.x = width * i;
UIView * view = [[UIView alloc] initFrame:r];
[self.scrollView addSubview:view];
}

Try this:
int xPosition = 0;
for (int i = 0; i < users.count; i++) {
UIView * view = [[UIView alloc] initFrame:CGRectMake(xPosition, 0, width, 1200)];
[self.scrollView addSubview:view];
xPosition += width;
}

Instead of
[self.scrollView setContentSize:CGSizeMake(width*array.count, 0)];
It should be
[self.scrollView setContentSize:CGSizeMake(width*array.count, self.scrollView.frame.size.height)];

for (int i = 0; i < users.count; i++) {
r.origin.x = width * i;
UIView * view = [[UIView alloc] initFrame:r];
[self.scrollView addSubview:view];
}
In this way you have also a memory leak on view(s) object
for (int i = 0; i < users.count; i++) {
r.origin.x = width * i;
UIView * view = [[UIView alloc] initFrame:r];
[self.scrollView addSubview:view];
[view release];
}

Related

How to place arrange images dynamically in a circle

How can i dynamically arrange icons(UIButtons, with backgroundImages) in circle image.SOmething like it should like concentric circles.
I am using the following code,
UIImageView *container = [[UIImageView alloc] initWithFrame:CGRectMake(0.0, 0.0f, 299.0f, 298.0f)];
container.image = [UIImage imageNamed:#"AR_RF004_circle.png"];
container.center = CGPointMake(self.view.bounds.size.width/2.0, self.view.bounds.size.height/2.0);
[self.view addSubview:container];
NSArray *imagesArray = [[NSArray alloc]initWithObjects:[UIImage imageNamed:#"AR1.png"],[UIImage imageNamed:#"AR2.png"],[UIImage imageNamed:#"AR3.png"],[UIImage imageNamed:#"AR4.png"],[UIImage imageNamed:#"AR5.png"], nil];
int numberOfSections = 5;
CGFloat angleSize = 2*M_PI/numberOfSections;
for (int j = 0; j < numberOfSections; ++j) {
UIButton *sectionLabel = [[UIButton alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 150.0f, 128.0f)];
[sectionLabel setBackgroundImage:[imagesArray objectAtIndex:j] forState:UIControlStateNormal];
sectionLabel.layer.anchorPoint = CGPointMake(0.9f, 0.1f);
sectionLabel.layer.position = CGPointMake(container.bounds.size.width/2.0, container.bounds.size.height/2.0); // places anchorPoint of each label directly in the center of the circle.
sectionLabel.transform = CGAffineTransformMakeRotation(angleSize*j);
[container addSubview:sectionLabel];
NSLog(#"section label x and y is %f ,%f",sectionLabel.frame.origin.x,sectionLabel.frame.origin.y);
}
[container release];
Thanks in Advance
You can use this piece of code:
UIButton *currentButton;
int buttonCount = 20;
int radius = 200;
float angleBetweenButtons = (2 * M_PI) / buttonCount;
float x = 0;
float y = 0;
CGAffineTransform rotationTransform;
for (int i = 0; i < buttonCount; i++)
{
// get your button from array or something
currentButton = ...
...
x = radius + cosf(i * angleBetweenButtons) * radius;
y = radius + sinf(i * angleBetweenButtons) * radius;
rotationTransform = CGAffineTransformIdentity;
rotationTransform = CGAffineTransformRotate(rotationTransform, (i * angleBetweenButtons));
currentButton.center = CGPointMake(x, y);
currentButton.transform = rotationTransform;
}
I think you can do something like this
sectionLabel.center = container.center;
I have not checked other code.. Simplest way for this

Moving previous image in ScrollView using button click

When I press previous button it does not take any effect. Next Button is working properly but previous button do not show previous image. I am using scroll view to load images:
- (IBAction)next{
int arraycount = [appDelegate.articles count];
for (int nextIndex = [pageControl currentPage]; nextIndex < arraycount; nextIndex++) {
if ( self.scrollView.contentOffset.x <= self.scrollView.frame.size.width ) {
CGRect frame;
frame.origin.x = self.scrollView.contentOffset.x + self.scrollView.frame.size.width;
frame.origin.y = 0;
frame.size = self.scrollView.frame.size;
[self.scrollView scrollRectToVisible:frame animated:YES];
pageControlBeingUsed = YES;
}
}
}
-(IBAction)previousButtonAction
{
int arraycount = [appDelegate.articles count];
NSLog(#" arraycount : %d", arraycount);
NSLog(#" [pageControl currentPage] : %d", [pageControl currentPage]);
for (int nextIndex = [pageControl currentPage]; nextIndex>arraycount; nextIndex--) {
if ( self.scrollView.contentOffset.x >= self.scrollView.frame.size.width ) {
CGRect frame;
frame.origin.x = self.scrollView.contentOffset.x + self.scrollView.frame.size.width;
frame.origin.y = 0;
frame.size = self.scrollView.frame.size;
[self.scrollView scrollRectToVisible:frame animated:YES];
pageControlBeingUsed = YES;
}
}
}
Okay, I now think I would approach this differently. I would check the current offset before re-assigning it.
untested code:
- (IBAction)next{
if ( self.scrollView.contentOffset.x <= self.scrollView.frame.size.width ) {
CGRect frame;
frame.origin.x = self.scrollView.contentOffset.x + self.scrollView.frame.size.width;
frame.origin.y = 0;
frame.size = self.scrollView.frame.size;
[self.scrollView scrollRectToVisible:frame animated:YES];
pageControlBeingUsed = YES;
}
}
I would disable the "next" button when the user gets to the third image. If you prefer to return to the first image when the user presses "next" in the third image, then you must add an additional else after your if to indicate that case:
- (IBAction)next{
int arraycount = [appDelegate.articles count];
for (int nextIndex = [pageControl currentPage]; nextIndex < arraycount; nextIndex++) {
if (nextIndex < arraycount) {
CGRect frame;
frame.origin.x = self.scrollView.frame.size.width * nextIndex;
frame.origin.y = 0;
frame.size = self.scrollView.frame.size;
[self.scrollView scrollRectToVisible:frame animated:YES];
pageControlBeingUsed = YES;
}
// If the user clicks on next in the last item, return to the first
else {
CGRect frame;
frame.origin.x = 0;
frame.origin.y = 0;
frame.size = self.scrollView.frame.size;
[self.scrollView scrollRectToVisible:frame animated:YES];
pageControlBeingUsed = YES;
}
}
}
arraycount = 3
[pageControl currentPage] is zero indexed so when you are on page 3 it equals 2.
so the start of your for loop nextIndex equals 2 which is less than arrayCount so it gets into your loop.
change it to:
for (int nextIndex = [pageControl currentPage]; nextIndex < (arraycount-1); nextIndex++) {
okay what does this output:
- (IBAction)next{
int arraycount = [appDelegate.articles count];
NSLog(#" arraycount : %d", arraycount);
NSLog(#" [pageControl currentPage] : %d", [pageControl currentPage]);
for (int nextIndex = [pageControl currentPage]; nextIndex < (arraycount-1); nextIndex++) {
NSLog(#" nextIndex : %d", nextIndex);
CGRect frame;
frame.origin.x = self.scrollView.frame.size.width * nextIndex;
frame.origin.y = 0;
frame.size = self.scrollView.frame.size;
[self.scrollView scrollRectToVisible:frame animated:YES];
pageControlBeingUsed = YES;
}
}
Fo me it is working in swift 3.
func prevAction (sender:UIButton)
{
print("self.scView.contentOffset.x ..\(self.scView.contentOffset.x)")
if ( self.scView.contentOffset.x <= self.scView.contentSize.width )
{
var frame = CGRect()
frame.origin.x = self.scView.contentOffset.x - 80;
frame.origin.y = 0;
frame.size = self.scView.frame.size;
self.scView .scrollRectToVisible(frame, animated: true)
}
}
Thanks to #ader.

How to scroll characters on a label in Cocos2D?

I have a sprite on which there is a label (CCLabelTTF). On that label i have A,B,C,D,E, etc printed when they are clicked. I want them to scroll left. I've googled some tuorials but i am unable to find the solution and stuck here for long. Here is the screenshot of my game. You can see the characters from A to J. When i click on more incoming characters, that portion should scroll. What can i do to make the characters scroll?
Here is the code from which the characters are shown on label (lblSelectedAlpha) added on sprite:-
-(void)showSelectedAlphaBet{
fSelectedAlphaY =26;
if (tempBackground) {
[tempBackground removeFromParentAndCleanup:YES];
}
tempBackground = [CCSprite spriteWithFile:#"stripe_2.png"];
tempBackground.position = ccp(160,30);
[self addChild:tempBackground z:30];
for (int i=0; i<[arryAddSelectedChar count]; i++) {
// NSLog(#"[arryAddSelectedChar count] %#",[arryAddSelectedChar objectAtIndex:i]);
lblSelectedAlpha = [CCLabelTTF labelWithString:
[arryAddSelectedChar objectAtIndex:i]dimensions:CGSizeMake(30,30)
alignment:UITextAlignmentCenter fontName:#"Marker Felt" fontSize:30];
lblSelectedAlpha.position = ccp(fSelectedAlphaY,25);
lblSelectedAlpha.tag=i;
lblSelectedAlpha.color = ccc3(125,125,125);
[tempBackground addChild:lblSelectedAlpha z:5];
fSelectedAlphaY +=25;
}
}
Scrolling is simply a constant change in position over time. Basically something like this:
-(void) update:(ccTime)delta
{
label.position = CGPointMake(label.position.x - 1, label.position.y);
}
Well, this is how i implemented scrolling in my cocos2d game
// How to add scroll on label. This i did with a UITextView
// inside init, i took
{
scroll = [[UIScrollView alloc] initWithFrame:CGRectMake(10,430, 150, 50)]
alphabetScroll = [[UITextView alloc] initWithFrame:CGRectMake(10,0,50 ,50)];
alphabetScroll.font = [UIFont fontWithName:#"verdana" size:30.0f];
alphabetScroll.backgroundColor = [UIColor clearColor];
alphabetScroll.textColor = [UIColor colorWithRed:125.0/255.0 green:125.0/255.0 blue:125.0/255.0 alpha:1.0f];
alphabetScroll.userInteractionEnabled=NO;
[scroll addSubview:alphabetScroll];
[[[CCDirector sharedDirector]openGLView]addSubview:scroll];
}
-(void)showSelectedAlphaBet
{
NSLog(#"showSelectedAlphaBet");
fSelectedAlphaY =26; // I have 26 alphabets
if (tempBackground) {
[tempBackground removeFromParentAndCleanup:YES];
}
// Area where alphabets are added on touch
tempBackground = [CCSprite spriteWithFile:#"stripe_2.png"];
tempBackground.position = ccp(160,30);
[self addChild:tempBackground z:30];
bottomAlphabet = #" ";
for (int i=0; i<[arryAddSelectedChar count]; i++) {
NSLog(#"[arryAddSelectedChar count] %#",[arryAddSelectedChar objectAtIndex:i]);
bottomAlphabet = [bottomAlphabet stringByAppendingString:[arryAddSelectedChar objectAtIndex:i]];
}
// Implementing shifting/scrolling
int newScrollViewWidth;
int newLabelWidth;
newScrollViewWidth =25*[arryAddSelectedChar count];
newLabelWidth =50*[arryAddSelectedChar count];
[scroll setContentSize:CGSizeMake(newScrollViewWidth, 45)];
alphabetScroll.frame = CGRectMake(0, 0, newLabelWidth, 45);
alphabetScroll.text = bottomAlphabet;
if (newScrollViewWidth > 150) {
CGPoint svos;
CGPoint pt;
svos = scroll.contentOffset;
CGRect rc = [alphabetScroll bounds];
rc = [alphabetScroll convertRect:rc toView:scroll];
pt = rc.origin;
pt.y = 0;
pt.x += 20*([arryAddSelectedChar count]-5);
[scroll setContentOffset:pt animated:YES];
}
}
// In dealloc
[alphabetScroll release];

Object leak : Adding and removing UIImageView to a UIScrollView

I'm trying to dynamically add Images to a ScrollView. Before adding I check if there are any subviews in the ScrollView and delete them in a for loop.
When I release the imageview I get a runtime error stating i'm trying to acces a deallocated instance. If I remove the release statement the application will run correctly but "build and analyze" shows a leak because th reference count of imageview is not decreased..
if ([scrollView.subviews count]>0){
for (int i=0; i<[scrollView.subviews count]; ++i) {
[[scrollView.subviews objectAtIndex:i] removeFromSuperview];
}
}
//Making a scroller with results
int scrollWidth = 0.0f;
int scrollHeight = 0.0f;
for (int i = 0; i<previewImages.count;++i)
{
UIImage *image=[previewImages objectAtIndex:i];
scrollWidth = scrollWidth + image.size.width; // Width of all the images
if (image.size.height > scrollHeight)scrollHeight= image.size.height; // Maximum image height
[image release];
}
float xC = 0.0f;
for (int i=0; i<previewImages.count; ++i) {
UIImage *image=[previewImages objectAtIndex:i];
UIImageView *imageview = [[UIImageView alloc] initWithFrame:CGRectMake(xC, 0.0f, image.size.width, image.size.height)];
UILabel *subScript = [[UILabel alloc] initWithFrame:CGRectMake(xC, image.size.height-30.0f, image.size.width,30.0f)];
subScript.textColor = [UIColor whiteColor];
subScript.backgroundColor = [UIColor colorWithWhite:0.5f alpha:0.5f];
subScript.text = [imagePaths objectAtIndex:i];
imageview.image = image;
xC = xC + image.size.width;
[image release];
[scrollView addSubview:imageview];
[imageview release];
[scrollView addSubview:subScript];
[subScript release];
}
[scrollView setContentSize:CGSizeMake(scrollWidth , scrollHeight)];
Any suggestions about the memory leak or general best practices for adding and removing views from an array into a scrollView are much appreciated!
if ([scrollView.subviews count]>0){
for (int i=0; i<[scrollView.subviews count]; ++i) {
[[scrollView.subviews objectAtIndex:i] removeFromSuperview];
}
}
is wrong, because you are removing subview from subviews array. Do reverse iteration would fix that, but I would suggest keeping the view in separated array instead.

UIScrollView offsetting content double the requested amount

The Issue
My PSWSnapshotView's end up exactly snapshotIndex too far to the right inside the _scrollView (40px offset). Yet, they are set with their frame to have the first one at (0, 0), though that first one shows up at (snapshotInset, 0) instead :/.
The Code
- (void)layoutViews
{
CGRect frame = self.frame;
CGFloat pageWidth = frame.size.width - (snapshotInset * 2);
CGRect pageFrame = CGRectMake(0.0f, 0.0f, pageWidth, frame.size.height);
NSInteger pageCount = [applications count];
[pageControl setNumberOfPages:pageCount];
[scrollView setFrame:CGRectMake(snapshotInset, 0.0f, pageWidth, frame.size.height)];
[scrollView setContentSize:CGSizeMake((pageWidth * pageCount) + 1.0f, frame.size.height)];
for (int i = 0; i < pageCount; i++) {
PSWSnapshotView *view;
if ([snapshotViews count] <= i)
{
PSWSnapshotView *view = [[PSWSnapshotView alloc] initWithFrame:pageFrame application:[applications objectAtIndex:i]];
view.delegate = self;
[scrollView addSubview:view];
[snapshotViews addObject:view];
[view release];
}
else
{
view = [snapshotViews objectAtIndex:i];
[view setFrame:pageFrame];
}
pageFrame.origin.x += pageWidth;
}
}
The Values
self.frame.size.width = 320;
self.frame.size.height = 370;
snapshotInset = 40;
[applications count] = 2;
All the sizes and frames are set correctly (I checked w/ NSLog).
Are you possibly setting the scrollView.contentOffset somewhere, independent of this? Also, and this may just be a copy/paste issue, you reference both snapshotInset and _snapshotInset.