Issue with subviews overlapping - ios

I'm trying to create a custom view which containes several images. I do that by adding them programmatically. The problem is that those subviews overlap each other and I can't find the way to change that. The only solution I can see is doing something like setting frames for each new image programmatically. I would be grateful if someone could tell me what is the best way to solve this issue.
for (id image in self.images) {
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
[self.imageViews addObject:imageView];
[self addSubview:imageView];
}

If you wanna make your customView like UICollectionView you need a UIScrollView and add your subviews in it. Everytime when you add a subview change frame location so it could be something like this:
int xPosition = 0;
int yPosition =0;
for (id image in self.images) {
if (xPosition>self.view.frame.size.width) {
//give size to every imageView and every time in loop change the location
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(xPosition, yPosition, 50, 50)];
imageView.image = image;
yPosition = yPosition + 50;
[self.view addSubView:imageView];
}
else {
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(xPosition, yPosition, 50, 50)];
imageView.image = image;
xPosition = xPosition + 50;
[self.view addSubView:imageView];
}
}

Without using Interface Builder your only real options are to change the frame or the center.
imageView.frame = CGRectMake(x coord, y coord, width, height);
This method lets you resize and move whereas changing the center lets you do just that, move the center of the view.
or
imageView.center = CGPointMake(x coord, y coord);
Or as recommended add constraints.

Related

Why isn't my code moving image position?

I want an image to automatically align to the top, I figure the only want to do this is through making a frame that positions it that way. After doing some research, I can't seem to figure out why this code doesn't move the image at all... I have substituted many values in the topPadding and leftPadding variables..
- (void)constructImageView:(UIImage *)image {
CGFloat topPadding = 20.f;
CGFloat leftPadding = 30.f;
CGRect frame = CGRectMake(leftPadding, topPadding, image.size.width, image.size.height);
self.imageView = [[UIImageView alloc] initWithFrame:frame];
self.imageView.image = image;
[self addSubview:self.imageView];
}
Are you using Autolayout? If yes, setFrame: does not work properly with autolayout. If thats the case, then your options are:
Use this: self.view.translatesAutoresizingMaskIntoConstraints = YES
Write your own constraints instead of setting the view's frame

UIImageView and autolayout

I have a view that is set up nicely using autolayout. The view contains a series of labels stacked from top to bottom. I am allowing the intrinsic size of these labels to determine the size of the view.
The final step is to add a background from an image. I started by trying the colorWithPatternImage method on UIColor but this isn't quite what I am looking for. I do not want to tile the image, and I can not guarantee it will always be larger than the intrinsic size of the view.
Similarly, adding a uiImageView to the view itself doesn't quite work. The view will expand to accommodate the image when I want to keep the intrinsic size based on the labels.
I guess what I am looking for is the following.
1) The background should have no effect on the size of the view.
2) The image should be scaled to fill the view but in it's original aspect ration (so cropping edges if necessary).
Any ideas appreciated.
In my case, I needed it for a UIImageView inside a dynamically-sized view in a UITableViewCell, but the image refused to shrink below its instristic size and instead worked as a minimum-size constraint for the superview. The only way I could get it ignore the intristic size is by lowering the priority at which it is enforced, right after creating the cell:
[imageView setContentCompressionResistancePriority:UILayoutPriorityDefaultLow
forAxis:UILayoutConstraintAxisHorizontal];
[imageView setContentCompressionResistancePriority:UILayoutPriorityDefaultLow
forAxis:UILayoutConstraintAxisVertical];
After this, all my constraints magically started working. In the OP's case, setting UIViewContentModeScaleAspectFill is also required, as per Mundi's answer.
In Interface Builder, add a UIImageView as the first subview to the view. Make sure its size always matches the view.
Then, in Interface Builder or code, set the contentMode:
backgroundImageView.contentMode = UIViewContentModeScaleAspectFill;
Here's how I would approach this. Hopefully it helps. :)
CGRect contentFrame = CGRectMake(0, 0, self.view.frame.size.width, 0); // This will be the frame used to create the background image view.
UIEdgeInsets contentInsets = UIEdgeInsetsMake(20, 20, 20, 20); // The margins by which the labels will be inset from the edge of their parent view.
CGFloat labelHeight = 21;
CGFloat verticalGap = 8; // The vertical space between labels
CGFloat y = contentInsets.top;
int numberOfLabels = 10;
for (int i = 0; i < numberOfLabels; i++) {
CGRect frame = CGRectMake(contentInsets.left, y, self.view.frame.size.width - (contentInsets.left + contentInsets.right), labelHeight);
UILabel *label = [[[UILabel alloc] initWithFrame: frame] autorelease];
// customize the label here
[self.view addSubview: label];
contentFrame = CGRectUnion(contentFrame, label.frame);
y += labelHeight + verticalGap;
}
contentFrame.size.height += contentInsets.bottom;
UIImageView *backgroundImageView = [[[UIImageView alloc] initWithFrame: contentFrame] autorelease];
[backgroundImageView setClipsToBounds: YES];
[backgroundImageView setContentMode: UIViewContentModeScaleAspectFill];
[backgroundImageView setImage: [UIImage imageNamed: #"background_image.png"]];
[self.view insertSubview: backgroundImageView atIndex: 0];

Stopping UIScrollView at specific place while scrolling with pagingEnabled

I have the following code to create a scroll view with additional area at the beginning and the end of the images (50 points).
UIScrollView* scroll = [[UIScrollView alloc] initWithFrame: CGRectMake(0,0,200,100)];
scroll.contentSize = CGSizeMake(400,100);
UIImageView* img1 = [[UIImageView alloc] initWithFrame: CGRectMake(50,0,100,100);
UIImageView* img2 = [[UIImageView alloc] initWithFrame: CGRectMake(150,0,100,100);
UIImageView* img3 = [[UIImageView alloc] initWithFrame: CGRectMake(250,0,100,100);
//Adding images to ImageViews
scroll.pagingEnabled = YES;
[scroll addSubView:img1];
[scroll addSubView:img2];
[scroll addSubView:img3];
The first time I see the view, I will see the additional area on the left (0-50), then the first image (50-150) and then half of the second image (150-200).
When I swipe left, I want to see half of the first image on the right, the second image at the center, and half of the third image on the right.
When I swipe left again, I want to see the third image at center, with half of the second image on the left, and the additional area on the right.
Can it be possible?
It's possible as long as you define everything correctly. Make sure that the assigned content size is equal to the overall size that you wish to scroll through. Make sure that each page size is equal to the scroll view's frame. You can set the clipsToBounds to NO if the frame clips your subviews.
You can do this by adjusting the contentSize of UIScrollView
- (void)addImagesToScrollView{
//An offset from where imageViewStarts
CGFloat xOffset = 50.0f;
CGRect imageViewFrame = CGRectMake(xOffset, 0.0f, 100.0f, 100.0f);
for (NSString *imageName in #[#"image1.jpg",#"image2.jpg",#"image3.jpg"])
{
UIImageView *imageView = [[UIImageView alloc]initWithFrame:imageViewFrame];
UIImage *image = [UIImage imageNamed:imageName];
imageView.image = image;
[self.scrollView addSubview:imageView];
imageViewFrame.origin.x+=imageViewFrame.size.width;
}
CGSize contentSize = self.scrollView.frame.size;
//Content size is calculate from the imageViewFrame and an offset is added to it
contentSize.width = imageViewFrame.origin.x+xOffset;
[self.scrollView setContentSize:contentSize];
}
Source Code
You can scroll to a particular place in the scrollview using the following code
[YOURSCROLLVIEW setContentOffset:CGPointMake(x, y) animated:YES];

iPhone UIImageView horizontall scrolling in UIScrollView - Center image?

I have method that download and resize image according to screen size to fit image fullscreen. Max image size is (320x416). Now, I have fullscreen UIScrollView, in which I am creating UIImageView with initWithFrame shifted on X by screen width, adding UIScrollView space horizontally.
No problem at all as long as I set UIImageView created inside UIScrollView [imgView setContentMode:UIViewContentModeLeft]. With [imgView setContentMode:UIViewContentModeCenter] it shifts image, every count of loop, add half screen to right, so I can see just first image, half of second and third only if I went behind scrollView bounds a bit.
Here is my code, can you someone kick me where am I missing something? Thank you.
I put NSLog under imgView initWithFrame:CGRectMake but coords are OK, X position is shifting by 320 pixels and arrange imgView in scrollView is all right then.
- (void)setImages {
int screenWidth = self.view.frame.size.width;
int screenHeight = self.view.frame.size.height;
// I know count of images here => imageIndex
[mainView setContentSize:CGSizeMake(screenWidth * imageIndex, screenHeight)];
int actualWidth = screenWidth;
for (int index = 0; index < imageIndex; index++) {
UIImageView *imgView = [[UIImageView alloc] initWithFrame:CGRectMake(actualWidth - screenWidth, 0, actualWidth, screenHeight)];
ImageProcessing *impc = [[ImageProcessing alloc] init];
UIImage *image = [UIImage imageWithData:[imagesNSDataArray objectAtIndex:index]];
UIImage *resampled = [impc processImageToWidthAndHeight:image :screenWidth :screenHeight];
// [imgView setContentMode:UIViewContentModeCenter];
[imgView setContentMode:UIViewContentModeLeft];
imgView.image = resampled;
[mainView addSubview:imgView];
actualWidth = actualWidth + screenWidth;
}
}
You are mixing view width and horizontal position. The views don't have the same width - you are making them wider and wider. When you try to center the image inside the view, it gets shifted because the view is wider than you think.
int viewX = 0;
for (int index = 0; index < imageCount; index++) {
CGRect frame = CGRectMake(viewX, 0, screenWidth, screenHeight);
UIImageView *imgView = [[UIImageView alloc] initWithFrame:frame];
[...]
viewX += screenWidth;
}

IOS Add subview on viewDidLoad

i have a problem when i'm trying to add subviews to a UIScrollView on viewDidLoad.
I'm using this code to programmatically add the UIImageViews to the scrollView:
- (void)viewDidLoad {
[super viewDidLoad];
NSInteger const_width = 100;
NSInteger numberOfViews = 4;
CGRect theFrame = [self.scrollView frame];
for (int i = 0; i < numberOfViews; i++) {
CGFloat xOrigin = i * const_width;
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(xOrigin,theFrame.origin.y,const_width,110)];
UIImage *image = [UIImage imageNamed:#"cocoloco.jpg"];
[imageView setImage:image];
//[self.scrollView addSubview:imageView];
imageView.tag = i;
CGRect rect = imageView.frame;
rect.size.height = 110;
rect.size.width = 110;
imageView.frame = rect;
[self.scrollView addSubview:imageView];
}
self.scrollView.contentSize = CGSizeMake(const_width * numberOfViews, 110);}
But i get the current view:
It seems that the scroll view frame takes its position regardless the 3 yellow tabs (that are a special TabBarController) so i get a wrong frame origin from the UIScrollView and therefore the UIImageViews are wrong positioned.
Any idea?
I don't know exactly how to do it, but add the height of the frame to the "Y" position of your rectangle. Something like this:
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(xOrigin,theFrame.origin.y + (theFrame.height),const_width,110)];
To get the scrollview below the navigation bar at the top, try
self.scrollview.autoresizingMask = UIViewAutoresizingFlexibleTopMargin;
Then position the table below the scrollview by setting it's origin base on the scrollview origin and height:
CGRect frame = tableView.frame;
frame.origin.y = self.scrollview.frame.origin.y + self.scrollview.frame.size.height;
tableView.frame = frame;
You should move any resizing or layout of your UI to the -(void)layoutSubviews method and this should sort your problem correctly.

Resources