I have a windowed (e.g. not a full-screen) UIScrollView (inside a UIView) which scrolls through groups of UIImageViews with UIButtons on them (the idea being you click the button to do something with the displayed image). The UIButton does take any touch events - how can I fix it?
I've read this, this, this, this and this - but I either don't understand the answer or its implications, or it's not really relevant.
NSUInteger i;
for (i = 1; i <= kNumImages; i++)
{
Sentence *testSentence = [[managedObjectContext executeFetchRequest:request error:&error] objectAtIndex:i];
//NSLog(#"testSentence: %#", testSentence);
//NSString *imageName = [NSString stringWithFormat:#"image%d.jpg", i];
//Your going to need to optimise this by creating another thumbnail image to use here.
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *imageName = [[paths objectAtIndex:0] stringByAppendingPathComponent:[testSentence image]];
//NSLog(#"imageName: %#", imageName);
UIImage *image = [[UIImage alloc] initWithContentsOfFile:imageName];
//NSLog(#"image: %#", image);
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
//NSLog(#"imageView: %#", imageView);
[imageView setContentMode:UIViewContentModeScaleAspectFit];
[imageView setBackgroundColor:[UIColor blackColor]];
// 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 = kScrollObjHeight;
rect.size.width = kScrollObjWidth;
imageView.frame = rect;
imageView.tag = i; // tag our images for later use when we place them in serial fashion
imageView.frame = rect;
UIButton *aButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[aButton setTitle:#"Play" forState:UIControlStateNormal];
aButton.frame = CGRectMake(10, 10, 70, 70);
[aButton setUserInteractionEnabled:YES];
[aButton setEnabled:YES];
[aButton setAlpha:1];
UIView *buttonWrapperUIView = [[UIView alloc] init];
[aButton addTarget:self action:#selector(clickPlay:) forControlEvents:UIControlEventTouchUpInside];
[imageView addSubview:aButton];
[imageView bringSubviewToFront:aButton];
[scrollView1 addSubview:imageView];
NSLog(#"aButton %#", aButton);
[image release];
[imageView release];
}
[self layoutScrollImages]; // now place the photos in serial layout within the scrollview
try
[imageView setUserInteractionEnabled:YES]
Related
When clicking on gallery button it shows black screen
UIButton *galleryButton = [UIButton buttonWithType:UIButtonTypeCustom];
[galleryButton addTarget:self action:#selector(ScrollView:) forControlEvents:UIControlEventTouchUpInside];
galleryButton.frame = CGRectMake(0, 0, 30, 30);
UIImage *ime = [UIImage imageNamed:#"photos.png"];
[galleryButton setImage:ime forState:UIControlStateNormal];
UIBarButtonItem *gallerybutton = [[UIBarButtonItem alloc] initWithCustomView:galleryButton];
-(void)ScrollView:(id)sender
{
ImageScrollViewController *imagescrollviewcontroller = [[ImageScrollViewController alloc] init];
[self presentViewController:imagescrollviewcontroller animated:YES completion:NULL];
[imagescrollviewcontroller release];
}
- (void)viewDidLoad
{
self.view.backgroundColor = [UIColor viewFlipsideBackgroundColor];
[_imageScrollView setBackgroundColor:[UIColor blackColor]];
[_imageScrollView setCanCancelContentTouches:NO];
_imageScrollView.indicatorStyle = UIScrollViewIndicatorStyleWhite;
_imageScrollView.clipsToBounds = YES; // default is NO, we want to restrict drawing within our scrollview
_imageScrollView.scrollEnabled = YES;
_imageScrollView.pagingEnabled = YES;
// load all the images from our bundle and add them to the scroll view
NSUInteger i;
for (i = 1; i <= kNumImages; i++)
{
NSString *imageName = [NSString stringWithFormat:#"image%d.png", i];
UIImage *image = [UIImage imageNamed:imageName];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
CGRect rect = imageView.frame;
rect.size.height = kScrollObjHeight;
rect.size.width = kScrollObjWidth;
imageView.frame = rect;
imageView.tag = i;
[_imageScrollView addSubview:imageView];
//[imageView release];
}
[self layoutScrollImages];
- (void)layoutScrollImages
{
UIImageView *view = nil;
NSArray *subviews = [_imageScrollView 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
[_imageScrollView setContentSize:CGSizeMake((kNumImages * kScrollObjWidth), [_imageScrollView bounds].size.height)];
}
Any idea why it is not showing images but black screen. I am following apple sample code for scrolling images. Changes i have made is that they are showing two subview in scrollview. i am showing only one subview.
Thanks for help.
I tried to change the image in the imageview but I can't seem to do that.
My code shown below creates a new subview for each image to display. However, the images just overlap and shows the overlapped images at the end which is not supposed to be.
.m:
for (int i = 0; i < [imageArr count]; i++) {
NSArray *imageNameArr = [[imageArr objectAtIndex:i] componentsSeparatedByString:#"."];
check=line;
NSString *msg = [textView.text stringByAppendingString:[NSString stringWithFormat:#"Opening image: %#\n",[imageArr objectAtIndex:i]]];
[textView performSelectorOnMainThread:#selector(setText:) withObject:msg waitUntilDone:NO];
line=line+1;
NSString *imagePath = [NSString stringWithFormat:#"%#/%#",jName,[imageArr objectAtIndex:i]];
NSString *imageFile = [NSHomeDirectory() stringByAppendingPathComponent:imagePath];
NSLog(#"------------------------------");
NSLog(#"ImageFile: %#\n",imageFile);
NSLog(#"Interger value: %i\n",i);
UIImage *myImage = [UIImage imageWithContentsOfFile:imageFile];
UIImageView *imageView = [[UIImageView alloc] initWithImage:myImage];
imageView.contentMode = UIViewContentModeScaleAspectFit;
[scrollView addSubview:imageView];
[imageView release];
.....
.....
}
How to show the images individually, without overlapping?
put this line out of for loop:
UIImageView *imageView = [[UIImageView alloc] initWithImage:myImage];
[scrollView addSubview:imageView];
and use it like:
UIImageView *imageView = [[UIImageView alloc] init];
[scrollView addSubview:imageView];
and use:
[imageView setImage:[UIImage imageWithContentsOfFile:fullImgNm]];
Inside for loop.
You create the imageview out of loop and change the source(Image) for that imageview inside the loop.
You do this before loop starts,
UIImageView *imageView = [[UIImageView alloc] init];
[scrollView addSubview:imageView];
and add the image like this inside the loop,
[imageView setImage:[UIImage imageWithContentsOfFile:imageFile]];
i have an iPhone app in which i have several images. These images add in image view. That image view add sub view with scroll view. Now i want to add a transparent button on every image. How can i do that? I have shown my code below:
- (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 += (kScrollWidth);
}
}
// set the content size so it can be scrollable
[scrollView1 setContentSize:CGSizeMake((kNoImages * 500), 700)];
}
- (void)viewDidLoad{
self.view.backgroundColor = [UIColor viewFlipsideBackgroundColor];
// 1. setup the scrollview for multiple images and add it to the view controller
//
// note: the following can be done in Interface Builder, but we show this in code for clarity
[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;
//imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"image0.jpg"]];
[scrollView1 addSubview:imageView];
[scrollView1 setContentSize:CGSizeMake(500,700)];
scrollView1.minimumZoomScale = 1;
scrollView1.maximumZoomScale = 3;
scrollView1.delegate = self;
[scrollView1 setScrollEnabled: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 = 1; i <= kNoImages; i++)
{
NSString *imageName = [NSString stringWithFormat:#"page-%d.jpg", 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 = kScrollHeight;
rect.size.width = kScrollWidth;
ImageView.frame = rect;
ImageView.tag = i; // tag our images for later use when we place them in serial fashion
UIButton *btnView2= [UIButton buttonWithType:UIButtonTypeCustom];
[btnView2 setTitle:#"view" forState:UIControlStateNormal];
[btnView2 addTarget:self action:#selector(View:)forControlEvents:UIControlEventTouchDown];
[btnView2 setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
btnView2.frame=CGRectMake(0,0,460,460 );
[scrollView1 addSubview:btnView2];
scrollView1.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
[scrollView1 addSubview:ImageView];
[ImageView release];
}
[self layoutScrollImages]; // now place the photos in serial layout within the scrollview
}
-(IBAction)View:(id)sender{
NSURL *imgUrl=[[NSURL alloc] initWithString:#"http://farm4.static.flickr.com/3567/3523321514_371d9ac42f.jpg"];
NSData *imgData = [NSData dataWithContentsOfURL:imgUrl];
UIImage *img = [UIImage imageWithData:imgData];
UIImageView *imgView = [[UIImageView alloc] initWithImage:img];
[self.view addSubview:imgView];
//[self.navigationController pushViewController:ivc animated:YES];
[imgUrl release];
}
Instead of adding Imageview and transparent button on top of Imageview. You can just add UIButton customtype and set button image to your image in your scrollview. There is no need to take imageview and UIButton both. Just take UIButton and setImage and you will be fine. I tried to give you sample code below from my app. Please modify it as per your need. I think it is what you need.
First of Take all constant in one of global file. I took it in en.lproj. like below.
"TotalThumbnailCount"="6";
"Coloumn"="2";
"ThumbnailHeight"="151";
"ThumbnailWidth"="151";
//Marging between two images
"MarginX" = "6";
"MarginY" = "6";
Then initialize all your local varaibles from global variables. like below
-(void)PopulateVariables{
TotalThumbnail = [NSLocalizedString(#"TotalThumbnailCount",nil) intValue];
Colomn = [NSLocalizedString(#"Coloumn",nil) intValue];
ThumbnailHeight = [NSLocalizedString(#"ThumbnailHeight",nil) intValue];
ThumbnailWidth = [NSLocalizedString(#"ThumbnailWidth",nil) intValue];
MarginX = [NSLocalizedString(#"MarginX",nil) intValue];
MarginY= [NSLocalizedString(#"MarginY",nil) intValue];
}
Now, you should initiate your thumbnail images using UIButton from below function.
-(void)PopulateThumbnails
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
XCordinate=MarginX;
YCordinate = MarginY;file:
for(int i=1; i <=TotalThumbnail;i++){
UIButton *btnMenu = [UIButton buttonWithType:UIButtonTypeCustom];
//NSData *data =UIImageJPEGRepresentation(, 1);
[btnMenu setBackgroundImage:[UIImage imageNamed:[NSString stringWithFormat:#"%d.png",i]] forState:UIControlStateNormal];
CGRect frame = btnMenu.frame;
frame.size.width=ThumbnailWidth;
frame.size.height=ThumbnailHeight;
frame.origin.x=XCordinate;
frame.origin.y=YCordinate;
btnMenu.frame=frame;
btnMenu.tag=i;
btnMenu.alpha = 1;
[btnMenu addTarget:self action:#selector(btnSelected:) forControlEvents:UIControlEventTouchUpInside];
[scrollView addSubview:btnMenu];
XCordinate = btnMenu.frame.origin.x + btnMenu.frame.size.width + MarginX;
if(i%Colomn==0)
{
XPosition = XCordinate;
YCordinate = btnMenu.frame.origin.y + btnMenu.frame.size.height + MarginY;
XCordinate = MarginX;
}
}
[pool release];
}
And then set your scrollview contentsize
scrollView.contentSize = CGSizeMake(XPosition, YCordinate);
When some one tap on any image it will goes in below event.
-(IBAction)btnSelected:(id)sender{
UIButton *btnSelected = sender;
switch (btnSelected.tag) {
}
Let me know if I miss anything and if you don't understand.. Hope this help.
You can add UITapGestureRecognizer to each image:
UITapGestureRecognizer *tapGesture = [[[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapAction:)] autorelease];
[imageView addGestureRecognizer:tapGesture];
[self.view addSubview:imageView];
When you create your imageview, create a uibutton and add it as a subview to the imageview.
Set the properties of the button to be custom type. Also set the frame of the button same as that of the imageview.
button = [UIButton buttonWithType:UIButtonTypeCustom];
Google how to create a uibutton programatically. You can then add the necessary selectors to handle button press events.
Alternatively you can create a element in Interfacebuilder. A custom class which has a uiimageview and clear uibutton. You can then use this element to add to your uiscrollview.
I am trying to create a scrollable menu bar (which I am succeeding in doing) but now instead I want to add a large button with an image centred in the button, instead of taking up the total width and height of the button
THis is my current code:
[scrollView setBackgroundColor:[UIColor whiteColor]];
[scrollView setCanCancelContentTouches:NO];
scrollView.indicatorStyle = UIScrollViewIndicatorStyleWhite;
scrollView.clipsToBounds = YES;
scrollView.scrollEnabled = YES;
UIImage *image;
UIImageView *iv;
UIButton *button;
count = [returned count];
for (int i=0; i<count; i++)
{
image = [UIImage imageNamed:#"coat2.jpg"];
iv = [[UIImageView alloc] initWithFrame:CGRectMake(0,0,105,120)];
button = [[UIButton alloc] initWithFrame:CGRectMake(0,0,105,120)];
[button setAlpha:100];
[button setTag:1];
[button addTarget:self action:#selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
iv.image = image;
iv.tag=#"coat2.jpg";
iv.userInteractionEnabled = YES;
[iv insertSubview:button atIndex:0];
[button release];
[scrollView addSubview:iv];
[iv release];
}
[scrollView setScrollEnabled:YES];
[self layoutScrollImages];
scrollView.delegate = self;
the above code creates an image and button over it where the button and image are of the exact same width and height. I want the button to be significantly larger both in height and width.
Is this possible?
Thanks!
2nd attempt (using help from Joseph Tura)
[scrollView setBackgroundColor:[UIColor whiteColor]];
[scrollView setCanCancelContentTouches:NO];
scrollView.indicatorStyle = UIScrollViewIndicatorStyleWhite;
scrollView.clipsToBounds = YES;
scrollView.scrollEnabled = YES;
UIImage *image;
count = [returned count];
for (int i=0; i<count; i++)
{
image = [UIImage imageNamed:#"coat2.jpg"];
iv = [[UIImageView alloc] initWithFrame:CGRectMake(0,20,105,120)];
button = [[ProductButton alloc] initWithFrame:CGRectMake(0,20,105,120)];
[button setAlpha:100];
[button setTag:1];
[button addTarget:self action:#selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
iv.tag=tag;
iv.userInteractionEnabled = YES;
iv.image = myimage;
UIView *uiView = [[UIView alloc] initWithFrame:CGRectMake(0,20,105,120)];
[uiView addSubview:iv];
button = [[ProductButton alloc] initWithFrame:CGRectMake(0,0,210,240)];
button.center = CGPointMake(uiView.frame.size.width /2, uiView.frame.size.height/2);
[button setTag:1];
[button addTarget:self action:#selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
[uiView addSubview:button];
[scrollView addSubview:uiView];
}
[scrollView setScrollEnabled:YES];
[self layoutScrollImages];
scrollView.delegate = self;
-----
-(void)layoutScrollImages
{
//UIImageView *view = nil;
UIView *view = nil;
NSArray *subviews = [scrollView subviews];
CGFloat curXLoc = 0;
for (view in subviews)
{
if ([view isKindOfClass:[UIView class]] && view.tag > 0)
{
CGRect frame = view.frame;
frame.origin = CGPointMake(curXLoc, 0);
view.frame = frame;
curXLoc += 110;
}
}
[scrollView setContentSize: CGSizeMake(count*110, [scrollView bounds].size.height)];
}
Why not put both elements inside a UIView?
UIView *aView = [[UIView alloc] initWithFrame:iv.frame];
[aView addSubview:iv];
button = [[UIButton alloc] initWithFrame:CGRectMake(0,0,210,240)];
button.center = CGPointMake(aView.frame.size.width / 2, aView.frame.size.height / 2);
[aView addSubview:button];
I use the following to display scrollview and pagecontrol
scrollView=[[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 320, 179)];
pageControl=[[UIPageControl alloc] initWithFrame:CGRectMake(0, 179, 320, 20)];
scrollView.delegate = self;
[scrollView setBackgroundColor:[UIColor blackColor]];
[scrollView setCanCancelContentTouches:NO];
scrollView.indicatorStyle = UIScrollViewIndicatorStyleWhite;
scrollView.clipsToBounds = YES;
scrollView.scrollEnabled = YES;
scrollView.pagingEnabled = YES;
int index=[[self._parameters objectForKey:#"index"] intValue];
NSString *imageNamePrefix=[[activeAppIdList objectAtIndex:index] objectForKey:#"AppID"];
int noOfScreenShot=[[[activeAppIdList objectAtIndex:index] objectForKey:#"NoOfScreenShot"] intValue];
CGFloat cx = 0;
for (int j=1;j<=noOfScreenShot ; j++) {
UIImage *image =[[UIImage alloc] init];
image= [self loadImage:[[NSString alloc]initWithFormat:#"%#_%d.jpg",imageNamePrefix,j]];
if (image == nil) {
NSString *urlString = [[NSString alloc]initWithFormat:#"http://localhost/MoreApp/images/%#_%d.jpg",imageNamePrefix,j];
NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:urlString]];
UIImage *temp=[[UIImage alloc]initWithData:imageData] ;
[self saveImage:temp withName:[[NSString alloc]initWithFormat:#"%#_%d.jpg",imageNamePrefix,j]];
image = temp;
[temp release];
[urlString release];
}
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
[image release];
imageView.frame = CGRectMake(cx,0,scrollView.frame.size.width,scrollView.frame.size.height);
[scrollView addSubview:imageView];
[imageView release];
cx += scrollView.frame.size.width;
}
NSLog(#"No Of pages..%d",noOfScreenShot);
pageControl.numberOfPages = noOfScreenShot;
pageControl.currentPage = 0;
scrollView.contentSize = CGSizeMake(cx,scrollView.frame.size.height);
NSLog(#"Width:%f",scrollView.frame.size.width);
[ refToSelf.instructionView addSubview:scrollView];
[ refToSelf.instructionView addSubview:pageControl];
[scrollView release];
[pageControl release];
scrollview is ok but pagecontroll didn't showed...
can help??
If the page control's and container's background color is the same (by default white) page control won't be visible.
For anyone who finds this, another silly mistake you can make is to not set the numberOfPages attribute on the UIPageControl, which will also cause it to not display.
My mistake was equally annoying - developing with storyboard in 3.5 inch view, and built on 4 inch device on simulator so it was offscreen. Silly!