Place UIImageViews in row - objective-c

I am looping through a array and adding UIImageViews, the array has a have different count depending on somethings. So the amount of UIImageViews varies. What I need to do is line them up in a row in the center of the view. I know the code that I need to use its the calculations that I am having an issue with.
for (int i = 0; i < [_lettersArray count]; i++){
UIImage* imageContainer = [UIImage imageNamed:#"container.png"];
UIImageView *containerView = [[UIImageView alloc] initWithImage:imageContainer];
containerView.frame = CGRectMake(???,120,imageContainer.size.width,imageContainer.size.height);
[self.view addSubview:containerView];
}

[self _layoutViews:self.imageViews inView:self.view];
- (void) _layoutViews:(NSArray *)views inView:(UIView *)contentView
{
NSInteger overallWidth = 0;
for ( UIView *view in views ) {
overallWidth += view.frame.size.width;
}
CGSize contentSize = contentView.frame.size;
CGFloat startOffset = (contentSize.width - overallWidth)/2.0;
CGFloat offset = startOffset;
for ( UIView *view in views ) {
CGRect frame = view.frame;
frame.origin.x = offset;
frame.origin.y = (contentSize.height/2.0) - (frame.size.height/2.0);
view.frame = frame;
offset += view.frame.size.width;
}
}
For your example code it would be something like this:
CGFloat count = [_lettersArray count];
NSMutableArray *imageViews = [[NSMutableArray alloc] initWithCapacity:count];
for (int i = 0; i < [_lettersArray count]; i++) {
UIImage *imageContainer = [UIImage imageNamed:#"container.png"];
UIImageView *containerView = [[UIImageView alloc] initWithImage:imageContainer];
containerView.frame = CGRectMake(0,120,imageContainer.size.width,imageContainer.size.height);
[imageViews addObject:containerView];
[self.view addSubview:containerView];
}
[self _horizontalCenterViews:imageViews inView:self.view];
return YES;
}
- (void) _horizontalCenterViews:(NSArray *)views inView:(UIView *)contentView
{
NSInteger overallWidth = 0;
for ( UIView *view in views ) {
overallWidth += view.frame.size.width;
}
CGSize contentSize = contentView.frame.size;
CGFloat startOffset = (contentSize.width - overallWidth)/2.0;
CGFloat offset = startOffset;
for ( UIView *view in views ) {
CGRect frame = view.frame;
frame.origin.x = offset;
view.frame = frame;
offset += view.frame.size.width;
}
}

Related

UIScrollView and UIPageControl, what am I doing wrong?

I have a class which is predefining some labels and binding their values in a UIScrollView.
I've managed to show those labels, but now I'm stuck at putting a label at the 2nd part of the ScrollView.
I've pushed my project to gitHub.
I can change the label's place on the already visible part, but I must be overlooking something.
- (void)viewDidLoad
{
[super viewDidLoad];
self.navigationItem.title = _detail.name;
UIColor *bgColor = [UIColor blackColor];
UIColor *txtColor = [UIColor grayColor];
CGRect frame;
frame.origin.x = 0;
frame.origin.y = 0;
frame.size.width = _scrollView.frame.size.width *2;
NSString *phoneNr = (_detail.phoneNr == nil) ? #"Not specified" : _detail.phoneNr;
_telLabel = [self prepareLabel:phoneNr textColor:txtColor bgColor:bgColor page:0 y:telNrYAxis];
_webLabel = [self prepareLabel:#"Visit website" textColor:txtColor bgColor:bgColor page:0 y:websiteYAxis];
_detail.address = [_detail.address stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:#"\n\t "]];
NSArray *addressArrComponents = [_detail.address componentsSeparatedByString:#","] ;
_addressLabel = [self prepareLabel:[addressArrComponents componentsJoinedByString:#"\n"] textColor:txtColor bgColor:bgColor page:0 y:addressYAxis];
UILabel *lbl = [self prepareLabel:#"Derp" textColor:txtColor bgColor:bgColor page:1 y:0];
_detailView = [[UIView alloc] initWithFrame:frame];
_detailView.backgroundColor = [UIColor blackColor];
[_detailView addSubview:_webLabel];
[_detailView addSubview:_addressLabel];
[_detailView addSubview:_telLabel];
[_detailView addSubview:lbl];
[_scrollView addSubview:_detailView];
NSLog(#"%f",self.view.frame.size.height - (_scrollView.frame.origin.y + _scrollView.frame.size.height) );
_pageControl = [[UIPageControl alloc] initWithFrame:CGRectMake(self.view.frame.size.width/2, self.view.frame.size.height - 250 , self.view.frame.size.width/4, 120)];
_pageControl.numberOfPages=2;
_pageControl.currentPage=0;
[_pageControl addTarget:self action:#selector(pageChange:) forControlEvents:UIControlEventTouchDown];
_scrollView.contentSize = CGSizeMake(800,800);
_scrollView.delegate=self;
_scrollView.backgroundColor = [UIColor blackColor];
_scrollView.pagingEnabled=YES;
_scrollView.showsHorizontalScrollIndicator = NO;
_scrollView.showsVerticalScrollIndicator = NO;
_scrollView.scrollsToTop = NO;
[self pageChange:0];
[self.view addSubview:_pageControl];
// Do any additional setup after loading the view.
}
-(UILabel*)prepareLabel:(NSString*) text textColor:(UIColor*)textColor bgColor:(UIColor*)backgroundColor page:(int)page y:(int) yPos{
int lines = [[text componentsSeparatedByString:#"\n"] count];
CGRect labelFrame = CGRectMake(_detailView.frame.size.width * page +20,yPos,self.view.frame.size.width, [UIFont systemFontSize]*lines);
UILabel *returnLabel = [[UILabel alloc] initWithFrame:labelFrame];
returnLabel.text = text;
returnLabel.backgroundColor = backgroundColor;
returnLabel.textColor = textColor;
[returnLabel setNumberOfLines:lines];
[returnLabel sizeToFit];
return returnLabel;
}
- (void)loadScrollViewWithPage:(int)page {
NSLog(#"Derped");
}
-(IBAction)pageChange:(id)sender{
int page=_pageControl.currentPage;
CGRect frame = _scrollView.frame;
frame.origin.x = _scrollView.frame.size.width * page;
frame.origin.y = 0;
//CGRect frame= (page == 0) ? _detailFrame : _reviewFrame;
NSLog(#"%f",frame.origin.x);
[_scrollView scrollRectToVisible:frame animated:YES];
}
The delegate -(IBAction)pageChange:(id)sender gets fired, but I must be doing something wrong with the frames somewhere :s
Please take a look!
Try to implement this method may help you :
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
CGFloat pageWidth = self.scrollView.frame.size.width;
float fractionalPage = self.scrollView.contentOffset.x / pageWidth;
NSInteger page = lround(fractionalPage);
self.pageControl.currentPage = page;
}

space between images in thumbnail for ipad

I create Thumbnail photo with scrollview for ipad, here is the code:
// load all the images from bundle and add them to the scroll view
NSUInteger i;
for (i = 1; i <= kNumImages; i++)
{
NSString *imageName = [NSString stringWithFormat:#"image%d.jpg", i];
UIImage *image = [UIImage imageNamed:imageName];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
}
- (void)layoutScrollImages
{
UIImageView *view = nil;
NSArray *subviews = [scrollView1 subviews];
// reposition all image subviews in a horizontal serial fashion
CGFloat curXLoc = 0;
for (view in subviews)
{
if ([view isKindOfClass:[UIImageView class]] && view.tag > 0)
{
CGRect frame = view.frame;
frame.origin = CGPointMake(curXLoc, 0);
view.frame = frame;
curXLoc += (kScrollObjWidth);
}
}
}
rightnow I have all images in UIScrollView that they are next to each other, I want to have some space between each images like this picture
would you please give me some hint that how can I add space between these images?
Thanks in Advance!
Try this:
curXLoc += (kScrollObjWidth) + kDifferenceBetweenImages;
and define kDifferenceBeteweenIMages accordingly.
Use UICollectionView instead. Much easier to achieve what you want and will work better too.
It even has a property for the space between each cell.
Try this one :
CGRect frame = view.frame;
frame.origin = CGPointMake(curXLoc, 0);
frame.size.height = //put height;
frame.size.width = //put width;
frame.origin.y = //put y;
view.frame = frame;
curXLoc += (kScrollObjWidth) + 15;

Why images are not showing in UIScrollView?

I am using this code to show scrolling images but I am only getting a white screen. I drag drop uiscrollview, created the iboutlet, synthesized it and rest of the code is here
#synthesize scrollView1;
const CGFloat kScrollObjHeight = 199.0;
const CGFloat kScrollObjWidth = 280.0;
const NSUInteger kNumImages = 5;
- (void)layoutScrollImages
{
UIImageView *view = nil;
NSArray *subviews = [scrollView1 subviews];
// reposition all image subviews in a horizontal serial fashion
CGFloat curXLoc = 0;
for (view in subviews)
{
if ([view isKindOfClass:[UIImageView class]] && view.tag > 0)
{
CGRect frame = view.frame;
frame.origin = CGPointMake(curXLoc, 0);
view.frame = frame;
curXLoc += (kScrollObjWidth);
}
}
// set the content size so it can be scrollable
[scrollView1 setContentSize:CGSizeMake((kNumImages * kScrollObjWidth), [scrollView1 bounds].size.height)];
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
scrollView1 = [[UIScrollView alloc]init];
bgArray = [NSArray arrayWithObjects:#"Bg", #"Bg1.png", #"Bg2.png", #"Bg3.png", #"Bg4.png", #"Bg5.png", #"Bg6.png", #"Bg7.png", #"Bg8.png", nil];
[scrollView1 setBackgroundColor:[UIColor blackColor]];
[scrollView1 setCanCancelContentTouches:NO];
scrollView1.indicatorStyle = UIScrollViewIndicatorStyleWhite;
scrollView1.clipsToBounds = YES; // default is NO, we want to restrict drawing within our scrollview
scrollView1.scrollEnabled = YES;
// pagingEnabled property default is NO, if set the scroller will stop or snap at each photo
// if you want free-flowing scroll, don't set this property.
scrollView1.pagingEnabled = YES;
// load all the images from our bundle and add them to the scroll view
NSUInteger i;
for (i = 0; i < [bgArray count]; i++)
{
NSString *imageName = [NSString stringWithFormat:#"%#", [bgArray objectAtIndex:i]];
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 = 199.0;
rect.size.width = 280.0;
imageView.frame = rect;
imageView.tag = i; // tag our images for later use when we place them in serial fashion
[scrollView1 addSubview:imageView];
[scrollView1 setShowsHorizontalScrollIndicator:NO];
[scrollView1 setShowsVerticalScrollIndicator:NO];
}
[self layoutScrollImages];
}
I think if you are create UIScrollView from code
scrollView1 = [[UIScrollView alloc]init];
then please add the scrollView1 in view
Example:-[self.view addSubview:scrollView1];
if you are create UIScrollView from nib then
not use this code
scrollView1 = [[UIScrollView alloc]init];
solve your probem

Issue with scroll view and accessing its subviews

I have a scroll view that contains image view sized 68x78:
As you could see, all that images except from the centered one have a shadow. It changes when user scrolls, center image is always clear. It goes perfect until for the left edge image:
Here is the code:
-(void) buildSlideView{
fotosJugadores = [[NSArray alloc] initWithObjects:#"cara5.png", #"cara7.png", #"cara8.png", #"cara9.png", #"cara11.png", #"cara13.png", #"cara14.png", #"cara15.png", #"cara18.png",#"cara19.png", #"cara20.png", #"cara32.png",#"cara44.png",#"cara51.png", #"cara100.png", #"cara101.png", #"cara102.png",#"cara103.png", #"cara104.png", #"cara105.png",#"cara106.png",#"cara107.png", nil];
numberOfViews = [fotosJugadores count];
for (int i = 0; i < [fotosJugadores count]; i++) {
UIImage *myImage = [UIImage imageNamed:[fotosJugadores objectAtIndex:i]];
CGFloat yOrigin = i * (myImage.size.width+3) + 120;
UIImageView *awesomeView = [[UIImageView alloc] initWithFrame:CGRectMake(yOrigin, 0, myImage.size.width, myImage.size.height)];
awesomeView.tag = i;
awesomeView.image = myImage;
awesomeView.alpha = 0.5f;
awesomeView.backgroundColor = [UIColor blackColor];
[self.jugadorSlide addSubview:awesomeView];
awesomeView=nil;
}
[jugadorSlide setBackgroundColor:[UIColor blackColor]];
jugadorSlide.contentSize = CGSizeMake(68 * numberOfViews+240,78);
jugadorSlide.layer.cornerRadius = 11;
jugadorSlide.layer.masksToBounds = YES;
[jugadorSlide setContentOffset:CGPointMake(((68 * numberOfViews)/2), 0)];
//jugadorSlide.decelerationRate = UIScrollViewDecelerationRateNormal;
[self scrollViewDidEndDragging:jugadorSlide willDecelerate:NO];
}
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
currentIndex = roundf(scrollView.contentOffset.x / 68);
NSLog(#"current end %d", currentIndex);
UIImageView *currentImage = [scrollView viewWithTag:currentIndex];
if (currentIndex>0&&currentIndex<=21){
if (currentIndex==currentImage.tag){
currentImage.alpha=1.0f;
[self changePerfilImage:currentImage.tag];}
CGPoint pointZero= CGPointMake(scrollView.contentOffset.x, currentImage.frame.origin.y);
[jugadorSlide setContentOffset:pointZero animated:YES];
}else {
UIImageView *currentImage = [scrollView viewWithTag:0];
NSLog(#"end dragging image tag %d", currentImage.tag);
currentImage.alpha=1.0f;
[self changePerfilImage:currentImage.tag];}
CGPoint pointZero= CGPointMake(currentImage.frame.origin.x+15, 0);
//[jugadorSlide setContentOffset:pointZero animated:YES];
}
As you can see, in the scrollViewDidEndDragging: "else" , I forced the tag as a desesperate solution, but images doesn't get clear.
You are incrementing the tag twice...
awesomeView.tag = i++;
Should just be:
awesomeView.tag = i+1;
I use i+1 because I never use a tag of 0 since any subview that hasn't been assigned a tag will have a tag of 0.
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
NSInteger currentIndex = roundf(scrollView.contentOffset.x / 68.0) + 1;
UIImageView *currentImage = [scrollView viewWithTag:currentIndex];
...
}
If this doesn't work you should NSLog the currentIndex each time you land on a new image and see what is happening when you land on the first one.

Scroll View adding views on top of each other

I can add several scrollviews with its background colours changed and it works fine. So basically for every view you have different background colours. However when I try to add separate views for each of these, it adds it right on top of the other and I don't know why.
UIViewController *view1 = [self.storyboard instantiateViewControllerWithIdentifier:#"View1"];
UIViewController *view2 = [self.storyboard instantiateViewControllerWithIdentifier:#"View2"];
UIViewController *view3 = [self.storyboard instantiateViewControllerWithIdentifier:#"View3"];
for (NSInteger i=0; i<ScrollViewControllerNumberOfPages; i++) {
CGFloat yOrigin = i * self.view.frame.size.height;
CGRect subViewFrame = CGRectMake(yOrigin, 0, pageHeight, pageWidth);
NSLog(#"Printing Width and Height %f %f",pageWidth,pageHeight);
UIView *subView = [[UIView alloc] initWithFrame:subViewFrame];
// Pick a random colour for the view
CGFloat randomRed = ((CGFloat)(arc4random() % 1000))/1000;
CGFloat randomGreen = ((CGFloat)(arc4random() % 1000))/1000;
CGFloat randomBlue = ((CGFloat)(arc4random() % 1000))/1000;
subView.backgroundColor = [UIColor colorWithRed:randomRed green:randomGreen blue:randomBlue alpha:1];
NSLog(#"printin i %i", i);
if (i == 0)
subView = view1.view;
else if (i == 1)
subView = view2.view;
[self.scrollView addSubview:subView];
}
This is kind of a shot in the dark because your code would need some serious rethinking.
What you're doing is you allocate a subview, you modify it's frame and background and then completely disregard this and set it to a view of previously instantiated viewcontoller.
This should work (in a way):
UIViewController *view1 = [self.storyboard instantiateViewControllerWithIdentifier:#"View1"];
UIViewController *view2 = [self.storyboard instantiateViewControllerWithIdentifier:#"View2"];
UIViewController *view3 = [self.storyboard instantiateViewControllerWithIdentifier:#"View3"];
for (NSInteger i=0; i<ScrollViewControllerNumberOfPages; i++) {
CGFloat yOrigin = i * self.view.frame.size.height;
CGRect subViewFrame = CGRectMake(yOrigin, 0, pageHeight, pageWidth);
NSLog(#"Printing Width and Height %f %f",pageWidth,pageHeight);
UIView *subView;
if (i == 0)
subView = view1.view;
else if (i == 1)
subView = view2.view;
subView.frame = subViewFrame;
// Pick a random colour for the view
CGFloat randomRed = ((CGFloat)(arc4random() % 1000))/1000;
CGFloat randomGreen = ((CGFloat)(arc4random() % 1000))/1000;
CGFloat randomBlue = ((CGFloat)(arc4random() % 1000))/1000;
subView.backgroundColor = [UIColor colorWithRed:randomRed green:randomGreen blue:randomBlue alpha:1];
NSLog(#"printin i %d", i);
[self.scrollView addSubview:subView];
}
It might look a bit better if you do it like:
for (NSInteger i=0; i<ScrollViewControllerNumberOfPages; i++) {
CGFloat yOrigin = i * self.view.frame.size.height;
CGRect subViewFrame = CGRectMake(yOrigin, 0, pageHeight, pageWidth);
NSLog(#"Printing Width and Height %f %f",pageWidth,pageHeight);
UIViewController *subViewCont = [self.storyboard instantiateViewControllerWithIdentifier:[NSString stringWithFormat:#"View%d",i+1]];
UIView *subView = subViewCont.view;
subView.frame = subViewFrame;
// Pick a random colour for the view
CGFloat randomRed = ((CGFloat)(arc4random() % 1000))/1000;
CGFloat randomGreen = ((CGFloat)(arc4random() % 1000))/1000;
CGFloat randomBlue = ((CGFloat)(arc4random() % 1000))/1000;
subView.backgroundColor = [UIColor colorWithRed:randomRed green:randomGreen blue:randomBlue alpha:1];
NSLog(#"printin i %d", i);
[self.scrollView addSubview:subView];
}