Positioning UIViews within UIScrollViews - objective-c

I have added 9 UIViews as subviews of UIScrollView with the below code:
-(void)constructedViewsForArray:(NSArray*)_listOfItems {
[_scrollView setContentSize:CGSizeMake(_listOfItems.count * 160, _scrollView.frame.size.height)];
CGRect frame = CGRectMake(10, 5, 100, 90);
for (int i = 0; i<[_listOfItems count];i++) {
UIView *aView = [[UIView alloc]init];
UILabel *test = [[UILabel alloc]initWithFrame:CGRectMake(0, 20, 100, 20)];
test.text = [NSString stringWithFormat:#"%#",[_listOfItems objectAtIndex:i]];
[aView addSubview:test];
[aView setBackgroundColor:[UIColor redColor]];
frame.origin.x=((frame.size.width+5)*i+5);
aView.frame = frame;
[_scrollView addSubview:aView];
}
}
The view's are added correctly to the scrollview.But after scrolling the UIView's are not aligned. Please refer to the images below:
The 5px space between the first view and the screen edge is missing after scrolling.
How can I set the view positions after scrolling.
PS: Paging is enabled.
Thanks for any help.
Regards,
iSee

I think what you are missing is that there need to be 10 px between 3 and 4, and 6 and 7, etc. for paging to work like you want it.
So changing the line
frame.origin.x=((frame.size.width+5)*i+5);
to something like this
frame.origin.x=((frame.size.width+5)*i+5 + (i/3) * 5);

It looks you are not noticing that the 4th column requires 10 px margin.so you need to add 5 additional pixel after 3rd column.
if((i%3)==0)
frame.origin.x=(((frame.size.width+5)*i+5)+ (i*5));
else
frame.origin.x=((frame.size.width+5)*i+5);
I hope this will help.

Related

iOS: Programmatically create labels inside scroll view created programmatically

I am developing a project in which I have created scroll view and labels inside scroll view programmatically using following code:
UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 44, self.view.frame.size.width, 240)];
int bx=0;
for (NSString * str1 in arr1)
{
if ([arr1 count]<=2) {
label=[[UILabel alloc]initWithFrame:CGRectMake(bx, -1, scrollView.frame.size.width/[arr1 count], 100)];
label.textAlignment=NSTextAlignmentCenter;
}
else
{
label=[[UILabel alloc]initWithFrame:CGRectMake(bx, -1, 106, 100)];
label.textAlignment=NSTextAlignmentCenter;
}
[label setText:[NSString stringWithFormat:#"(%#)",str1]];
[scrollView addSubview:label];
bx +=label.frame.size.width;
}
I want to create another line of labels below the above created labels using new array.and also I want to give different color to each label.
I don't know if I really understood, but maybe you should try to play with the second property of your CGRectMake which is for the Y value.

UIScrollView buggy

Please excuse poor code atm, just trying to get it working before making it look nice. So I am trying to get UIScrollView working. If I remove all scroll view stuff, I have a nicely laid out page with 64 buttons, 32 on each side of the page. These buttons are nigh miniature; so I wanted to implement zoom to be able to click them.
Zoom currently has unexpected results. When the page starts, it is blank. Zooming unexpectedly shows some of the left side of the graph on the rigght side of the page, and it bounces as I try to scroll over towards it. But when I zoom more, it allows me to scroll more towards the middle of the buttons. Always giving me difficulties/bugging out as I scroll/zoom. So obviously unusable.
My viewDidLoad:
[super viewDidLoad];
UIScrollView *scroll = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
scroll.minimumZoomScale = 0.5;
scroll.maximumZoomScale = 3.0;
scroll.delegate = self;
CGFloat yOrigin = self.view.frame.size.width;
UIView *awesomeView = [[UIView alloc] initWithFrame:CGRectMake(yOrigin, 0, self.view.frame.size.width, self.view.frame.size.height)];
// iterate over values in the staff array
int heightBetweenBrackets = 0;
int widthBetweenBrackets = 0;
int heightFromTop = 45;
for(int i = 0; i < 64; i++)
{
if(i == 32)
{
heightBetweenBrackets = 0;
}
UIButton *myButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
myButton.frame = CGRectMake(
0 + i/32*438,
heightFromTop + i%32*3+ heightBetweenBrackets,
35, 6);
[myButton setTitle:[NSString stringWithFormat:#"%d",i] forState:UIControlStateNormal];
myButton.titleLabel.adjustsFontSizeToFitWidth = YES;
[myButton.titleLabel setFont:[UIFont fontWithName:#"Arial" size:7]];
myButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;
// [myButton addTarget:self action:#selector(chooseWinner:) forControlEvents:UIControlEventTouchUpInside];
[awesomeView addSubview:myButton];
heightBetweenBrackets += (i%2 -1 * -1) * 3;
}
[scroll addSubview:awesomeView];
scroll.contentSize = CGSizeMake(self.view.frame.size.width, self.view.frame.size.height);
[self.view addSubview:scroll];
and:
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
return self.view;
}
I apologize if the bug is stupid I'm just learning IOS =] thanks for your time
EDIT: Figured it out.
For anybody in the future: I ported over a pagination scroller, and didn't realize I had kept CGFloat yOrigin = self.view.frame.size.width; -- this of course was starting the view directly to the right of any visible space. Thus I was able to zoom and see the left of it, in a buggy manner, although it started out blank. Simply changing this to 0 solved my problem.
For anybody in the future: I ported over a pagination scroller, and didn't realize I had kept CGFloat yOrigin = self.view.frame.size.width; -- this of course was starting the view directly to the right of any visible space. Thus I was able to zoom and see the left of it, in a buggy manner, although it started out blank. Simply changing this to 0 solved my problem.

Having issues removing UIViews from a UIScrollView

I'm trying to make code that will add players to a view based on objects but, I'm having some issues.
Right now currently if I run the initView method with 4 confirmed working Player objects in playerList, only 3 UIViews will appear in my scrollview, then when I click the clear players button, only the last (3rd) UIView will be removed.
A side note, none of my custom buttons appear in the UIViews either, I have an image that they should load with, but its not working.
Thanks in advance for any help.
- (void)clearPlayers {
for (Player* i in self.playerList) {
[i.viewPane removeFromSuperview];
}
[self.playerList removeAllObjects];
}
- (void)initView {
int Loc = 0;
int Count = 1;
int margin = 5;
int height = 100;
for (Player *p in playerList) {
UIView *playerView = [[UIView alloc] initWithFrame:CGRectMake(0, Loc, 320.0, height)];
p.viewPane = playerView;
[playerView setBackgroundColor:[UIColor redColor]];
[scrollView addSubview:playerView];
UIButton *plus = [[UIButton alloc] initWithFrame:CGRectMake(200, 10, (height - 5), (height - 5))];
UIImage *buttonImage =[[UIImage alloc] initWithContentsOfFile:#"Metal_Plus_Up_2.png"];
[plus setBackgroundImage:buttonImage forState:UIControlStateNormal];
[p.viewPane addSubview:plus];
[plus release];
[playerView release];
Loc = Loc + (height + margin);
Count = Count + 1;
}
[scrollView setContentSize:CGSizeMake(320.0, (height * Count) + (margin * Count))];
}
Question: have you verified that the UIImage returned from initWithContentsOfFile is not nil? You might need the full path instead of just the filename
As far as the wackiness with the UIViews not getting removed goes, everything you've posted looks fine as far as I can see. The only thing I can think of is that maybe you don't have retain specified as an attribute for your viewPane property...

How to programmatically add text to a UIView

I have a UIView that I'd like to add several bits of text to. I have used a UITextView but I think that's overkill as it doesn't need to be editable. I thought about using a UILabel or a UITextField, but I don't see how you tell the superview where to position the UILabel or UITextField within itself. I want the lowest footprint object that will let me put text of a font/color/size of my choosing in my UIView where I want it. Not too much to ask, eh?
The simplest approach for you would be:
UILabel *yourLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 10, 300, 20)];
[yourLabel setTextColor:[UIColor blackColor]];
[yourLabel setBackgroundColor:[UIColor clearColor]];
[yourLabel setFont:[UIFont fontWithName: #"Trebuchet MS" size: 14.0f]];
[yourSuperView addSubview:yourLabel];
Building or populating Views in your code will probably require you to use CGRectMake a lot.
As its name says, it creates a rectangle that you can use to set the relative position (relative to the borders of your superview) and size of your UIView-Subclass (in this case a UILabel).
It works like this:
yourLabel.Frame = CGRectMake(x, y, width, height); //x,y,width,height are float values.
x defines the spacing between the left hand border of the superview and the beginning of the subview your about to add, same applies to y but relating to the spacing between top-border of your superview.
then width and height are self-explanatory i think.
Hope this gets you on the track.
Instead of finding a way to tell the view where to position the UILabel, you can tell the UILabel where to position itself in the view by using "center".
E.g.
myLabel.center = CGPointMake(0.0, 0.0);
Hope you'll be able to use UILabel, for me it's the basic form of a flexible non editable text.
For Swift:
let yourLabel = UILabel(frame: CGRectMake(100, 100, 100, 100))
yourLabel.textColor = UIColor.whiteColor()
yourLabel.backgroundColor = UIColor.blackColor()
yourLabel.text = "mylabel text"
yoursuperview.addSubview(yourLabel)
This question is old, but for a pure UIView text option without using UILabel or UITextField (as all the other answers describe, but the question is how to do it without them), drawRect in a subclassed UIView works for me. Like so:
- (void)drawRect:(CGRect)rect{
NSString *string = #"Hello World!";
[string drawAtPoint:CGPointMake(100, 100) withFont:[UIFont boldSystemFontOfSize:16.0]];
}
This routine displays a text at a X-Y position
-(void)placeText:(NSString *)theText:(int)theX:(int)theY {
UILabel *textLabel;
// Set font and calculate used space
UIFont *textFont = [UIFont fontWithName:#"Helvetica" size:14];
CGSize textStringSize = [theText sizeWithFont:textFont constrainedToSize:CGSizeMake(300,50) lineBreakMode:NSLineBreakByTruncatingTail];
// Position of the text
textLabel = [[UILabel alloc] initWithFrame:CGRectMake(theX+OFFSETIMAGEX-(textStringSize.width/2), theY+OFFSETIMAGEY-(textStringSize.height/2), textStringSize.width,textStringSize.height)];
// Set text attributes
textLabel.textColor = [UIColor blackColor];
textLabel.backgroundColor = [UIColor orangeColor];
textLabel.font = textFont;
textLabel.text = theText;
// Display text
[self.view addSubview:textLabel];
}
It might be late but here is what I use:-
CGRect labelFrame = CGRectMake(120,300, 530, 100);
UILabel *myLabel = [[UILabel alloc] initWithFrame:labelFrame];
//If you need to change the color
[myLabel setTextColor:[UIColor whiteColor]];
//If you need to change the system font
[myLabel setFont:[UIFont fontWithName:NULL size:23]];
//If you need alignment
[myLabel setTextAlignment:NSTextAlignmentCenter];
// The label will use an unlimited number of lines
[myLabel setNumberOfLines:0];
//Add label view to current view
[self.view addSubview:myLabel];
NSString *someString = #"Sample String, Yarp!";
myLabel.text = someString;
add a UILabel to your View. then override the View's layoutSubviews method.

UIImageView blurs image

I have a really weird problem with UIImageView. I have an image (an RGB png) 45x45 pixels which I add to the view. I can see that image is blurred after added to the view. Here is the same image in the simulator (left) and in Xcode (right):
(source: partywithvika.com)
(source: partywithvika.com)
I have custom UIImageView class with this initWithImage code:
- (id) initWithImage:(UIImage*) image {
self = [super initWithImage:image];
self.frame = CGRectMake(0, 0, 45, 45);
self.contentMode = UIViewContentModeScaleAspectFit;
self.quantity = 1;
if (self) {
self.label = [[UITextField alloc]initWithFrame:CGRectMake(0,40,45,25)];
self.label.font = [UIFont systemFontOfSize:16];
self.label.borderStyle = UITextBorderStyleNone;
self.label.enabled = TRUE;
self.label.userInteractionEnabled = TRUE;
self.label.delegate = self;
self.label.keyboardType = UIKeyboardTypeNumbersAndPunctuation;
self.label.textAlignment = UITextAlignmentCenter;
}
self.userInteractionEnabled = TRUE;
// Prepare 3 buttons: count up, count down, and delete
self.deleteButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
self.deleteButton.hidden = NO;
self.deleteButton.userInteractionEnabled = YES;
self.deleteButton.titleLabel.font = [UIFont systemFontOfSize:20];
self.deleteButton.titleLabel.textColor = [UIColor redColor];
[self.deleteButton setTitle:#"X" forState:UIControlStateNormal];
[self.deleteButton addTarget:self action:#selector(deleteIcon:) forControlEvents:UIControlEventTouchUpInside];
self.upCountButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
self.upCountButton.hidden = NO;
self.upCountButton.userInteractionEnabled = YES;
[self.upCountButton setTitle:#"+" forState:UIControlStateNormal];
[self.upCountButton addTarget:self action:#selector(addQuantity:) forControlEvents:UIControlEventTouchUpInside];
self.downCountButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
self.downCountButton.hidden = YES;
self.downCountButton.userInteractionEnabled = YES;
[self.downCountButton setTitle:#"-" forState:UIControlStateNormal];
[self.downCountButton addTarget:self action:#selector(removeQuantity:) forControlEvents:UIControlEventTouchUpInside];
return self;
}
I create it like this:
UIImage *desertIcon = [UIImage imageNamed:#"desert.png"];
IconObj *desertIconView = [[IconObj alloc] initWithImage:desertIcon];
desertIconView.center = CGPointMake(265,VERTICAL_POINT_ICON);
desertIconView.type = [IconObj TYPE_DESERT];
[self.view addSubview:desertIconView];
[desertIconView release];
Why would the displayed image be so than the one stored in a file?
In general, everything you do on iPhone with UIKit should be pixel-aligned. Problems with pixel alignment usually manifest as blurriness (this is especially true with text and images). This is why when I find blurry view, I first check if I'm setting the center property. When you set center, the frame's x, y, height and width are adjusted around that center point... frequently resulting in fractional values.
You could try using CGRectIntegral on the frame as shown:
desertIconView.center = CGPointMake(265,VERTICAL_POINT_ICON);
desertIconView.frame = CGRectIntegral(desertIconView.frame);
This may work, but if it doesn't, try setting the frame manually, without using center property to ensure that no values are fractional.
Edit: Whoops! Didn't notice that the OP had answered his own question... I'll leave this up for informational reasons anyway.
I had this problem and it was driving me nuts. After some investigation it turned out that my image was smaller than the frame, and hence the scaling up blurred it. Once I had put in higher resolution images the problem is gone.
Make sure your image size is greater than your UIImageView frame size.
Your IconObj is 45 pixels wide. You move your IconObj center to 265 which makes its frame to (242.5, VERTICAL_POINT_ICON - 25*0.5, 45, 25). Image will always be blur if some of frame parameter is not integer.
Solution, calculate the frame parameter yourself (don't use center). And always make it integer (cast to NSInteger, use ceil, floor, or round).
desertIconView.frame = CGRectMake((NSInteger)(265 - 45*0.5),
(NSInteger)(VERTICAL_POINT_ICON - 25*0.5),
45, 25);
What I ended up doing is loading bigger picture into 45x45 UIImageView, of course with
contentMode = UIViewContentModeScaleAspectFit;
I just had the same problem. First I thought wtf do I need glasses?
Then I realized it´s just not possible to center an image (or label) when you give it an odd number. You need to resize your image to e.g. 46*46 if you want to center it and stay sharp.
Or you can leave it at 45*45 but then you need to decide whether you want your image to be mal-centered 1 pixel to the right, or 1 pixel to the left. (or leave it blurry).
Try to align your IconObj view at screen pixels. If it's really 45x45 then you should set the center to something like CGPointMake(x + 0.5f, y + 0.5f).
You should also double check image size in pixels (e.g in Preview.app Command-I).
complete source for the offset problem:
contentImage = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 0, 0)];
UIImage *cImage = [UIImage imageNamed:image];
self.contentImage.image = cImage;
[self.contentImage setFrame:CGRectMake(0, 0, cImage.size.width, cImage.size.height)];
CGFloat offset = 0.0f;
if ( ( (int)cImage.size.width % 2 ) && ( (int)cImage.size.height % 2 ) ) {
offset = 0.5f;
}
[self.contentImage setCenter:CGPointMake(256.0f + offset, 256.0f + offset)];