Image view not responding to touch event - ios

I have a grid of thumbnail images, and when one of them is touched, I'd like to show the whole image. Now, I know that UIImageView does not respond to touch events, but as suggested in this answer, I created a UIButton to handle the event. See code below:
- (void)displayImage
{
NSUInteger i = 0; // The actual code is different and works; this is just for brevity's sake.
// UILazyImageView is a subclass of UIImageView
UILazyImageView *imageView = [[UILazyImageView alloc] initWithURL:[NSURL URLWithString:[[[self images] objectAtIndex:i] thumbnailUrl]]];
UIButton *imageButton = [UIButton buttonWithType:UIButtonTypeCustom];
[imageButton setFrame:[imageView frame]];
[imageButton addTarget:self action:#selector(imageTapped:) forControlEvents:UIControlEventTouchUpInside];
[imageView addSubview:imageButton];
[[self containerView] addSubview:imageView];
[imageView release];
}
}
- (void)imageTapped:(id)sender
{
NSLog(#"Image tapped.");
// Get the index of sender in the images array
NSUInteger index = 0; // Don't worry, I know. I'll implement this later
FullImageViewController *fullImageViewController = [[[FullImageViewController alloc] initWithImageURL:[NSURL URLWithString:[[[self images] objectAtIndex:index] url]]] autorelease];
[[self navigationController] pushViewController:fullImageViewController animated:YES];
}
Ok. So I've create a custom button, set its frame to match the image frame, told it to respond to touch up inside and how to respond, and added it to the image's subviews. But when I run this, I get nothing. The "Image tapped." doesn't appear in the console, so I know that the message isn't being sent. What am I doing wrong here?
Many thanks for all your help.

by default UIImageView has its userInteractionEnabled property set to NO
add this line
imageView.userInteractionEnabled = YES;

Try
imageView.userInteractionEnabled = YES;
This is a property inherited from UIView, but as per Apple's docs, UIImageView changes its default value to NO, ignoring all events.

In addition to setting imageView.userInteractionEnabled = YES, you can eliminate the button altogether and add a UITapGestureRecognizer to the UIImageView to handle taps. It would look something like:
UITapGestureRecognizer *recognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(imageTapped:)];
[imageView addGestureRecognizer:recognizer];

Related

How to change to another image every 5 seconds in UIView?

I have a banner currently that gets images from my site, and I can scroll the banners left and rights to get the next or previous image. However, I also want it to change the images automatically every 5 secs.
I tried adding these codes to imageView, but the banner becomes empty not showing any images.
imageView.animateImages = delegate.bannerDetailsArray;
imageView.animationDuration = 5.0;
imageView.animationRepeatCount = 0;
[imageview startAnimating];
I am guessing that the array is where the issue is, but I am currently no clue how to fix it.
Can anyone shred some lights how to make the banner images change every 5 seconds?
-(void) bannerSettings
{
bannerScrollView = [UIScrollView new];
[bannerScrollView setBackgroundColor:BackGroundColor];
[bannerScrollView setFrame:CGRectMake(0,0,delegate.windowWidth, [self imageWithImage:delegate.windowWidth maxHeight:200])];
[bannerScrollView setPagingEnabled:YES];
[bannerScrollView setContentSize:CGSizeMake([delegate.bannerDetailsArray count]*delegate.windowWidth, 0)];
NSLog(#"%#",delegate.bannerDetailsArray);
for(int i=0;i<[delegate.bannerDetailsArray count];i++)
{
UIImageView * imageView = [UIImageView new];
[imageView setFrame:CGRectMake(i*delegate.windowWidth,0,delegate.windowWidth,[self imageWithImage:delegate.windowWidth maxHeight:200])];
[imageView sd_setImageWithURL:[NSURL URLWithString:[[delegate.bannerDetailsArray objectAtIndex:i]objectForKey:#"bannerImage"]]];
[imageView setContentMode:UIViewContentModeScaleAspectFill];
[imageView.layer setMasksToBounds:YES];
[imageView setUserInteractionEnabled:YES];
[imageView setTag:i];
//imageView.animateImages = delegate.bannerDetailsArray;
//imageView.animationDuration = 3.0;
//imageView.animationRepeatCount = 0;
//[imageview startAnimating];
[bannerScrollView addSubview:imageView];
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(bannerGestureTapped:)];
[imageView addGestureRecognizer:singleTap];
*The above codes works fine when the animation part ignored.
Thank you
ScrollView has a property
setContentOffset:animated:
Use this property in NSTimer function to see the effect.Follow this thread. It contains step by step process of how to make this.
Or.
You can use UIPageViewController and NStimer combination like this popular thread.
UIPageVC has a method like this.
- (void)setViewControllers:(NSArray *)viewControllers
direction:(UIPageViewControllerNavigationDirection)direction
animated:(BOOL)animated
completion:(void (^)(BOOL finished))completion
It expects a data to deliver. Then you can use NSTimer for a certain period of time to give the image.

How to assign and use array of imageViews using tag

I created arrays of imageViews in UIScrollView programmatically and made then user interacted by assigning them tap gesture. Now, I want to differentiate, which image view is clicked so that I can get images from clicked imageView. However, I was unable to assign them different tag. Here is my code. I am adding 15 images Views.
for (int i = 0; i < 15; i++) {
originx = ((_imageView.frame.size.width+5)*i); //Calculate origin x for each image view.
_imageView = [[UIImageView alloc]initWithFrame:CGRectMake(originx, self.view.frame.origin.y+5, imageViewHeightWidth, imageViewHeightWidth)];
[_imageView setBackgroundColor:[ UIColor colorWithRed:191.0/255.0 green:65.0/255.0 blue:78.0/255.0 alpha:0.5]];
//_imageView.layer.cornerRadius = 10.0;
_imageView.image = [UIImage imageNamed:[_imgArray objectAtIndex:i]];
//Enabling user interaction for gesture.
[_imageView setUserInteractionEnabled:YES];
[_imageView setMultipleTouchEnabled:YES];
//Tap Gesture enabled.
_gesture =[[UITapGestureRecognizer alloc]initWithTarget:self action:#selector(tapTheImage:)];
_gesture.numberOfTapsRequired = 1;
//Add a tap gesture.
[_imageView addGestureRecognizer:_gesture];
//Assigning the tag to image View.
_imageView.tag = 200+i;
//Adding image in to scroll view.
[_gallaryScrollView addSubview:_imageView];
}
//Here i am getting same tag value for every imageView. i.e. "214".
-(void)tapTheImage:(id)sender
{
NSLog(#"The tag value of imagView is%ld",(long)[_imageView tag]);
}
Change TapTheImage method
-(void) TapTheImage:(UITapGestureRecognizer *)gestureRecognizer{
//Get the View
UIImageView *tableGridImage = (UIImageView*)gestureRecognizer.view;
NSLog(#"%d",tableGridImage.tag);
}
You are not creating a new object of UIImageView.
Change the line
_imageView = [[UIImageView alloc]initWithFrame:CGRectMake(originx, self.view.frame.origin.y+5, imageViewHeightWidth, imageViewHeightWidth)];
to
UIImageView *_imageView = [[UIImageView alloc]initWithFrame:CGRectMake(originx, self.view.frame.origin.y+5, imageViewHeightWidth, imageViewHeightWidth)];

how to set background image properly in iOS

I am working on a view based app, I have set the background image as follows.
.h file:
UIImageView *BackgroundImage;
.m file:
viewdidLoad method:
BackgroundImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"BG.png"]];
[[self view] addSubview:BackgroundImage];
[BackgroundImage.superview sendSubviewToBack:BackgroundImage];
and on the rotate method:
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
BackgroundImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"BG2.png"]];
[[self view] addSubview:BackgroundImage];
[BackgroundImage.superview sendSubviewToBack:BackgroundImage];
[super viewDidLoad];
}
Using this code I am able to set the background, but on rotation the first loaded image is not removed and the second one is loading just behind the first one, so just half of the image is visible, because of the first image is in front of second one.
Is there is a better way to do this?
OR
How can I just remove the first image and then set the second one?
Please help me to resolve this.
Change your didRotate... method to:
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
[BackgroundImage removeFromSuperview];
BackgroundImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"BG2.png"]];
[[self view] addSubview:BackgroundImage];
}
Notice the [BackgroundImage removeFromSuperview]; line. What we are doing here is whenever the device rotates, you remove the old image view and add another one.
Also please notice that variable names should start with lower case, so BackgroundImage should be backgroundImage. This is to tell them apart from classes' names.
If you change your code like this should to work
BackgroundImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"BG.png"]];
[self.view addSubview:BackgroundImage];
[self.view sendSubviewToBack:BackgroundImage];
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
[BackgroundImage removeFromSuperview];
BackgroundImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"BG2.png"]];
[self.view addSubview:BackgroundImage];
[self.view sendSubviewToBack:BackgroundImage];
[super viewDidLoad];
}
This is because you are initializing the UIImageview again. Better to use same UIImageView that is backgroundImage with different image.
[Background Image set image:[UIImage imageNamed:#"BG2.png"]];
Just set the new image when rotating:
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
BackgroundImage.image = [UIImage imageNamed:#"BG2.png"];
}
Your code kept adding new image views when rotating.
How [do stuff] properly in iOS?
Start your ivar names using an underscore and a lowercase letter: _backgroundImage instead of BackgroundImage.
Insert a subview in the right spot: [self.view insertSubview:_backgroundImage atIndex:0];

UIButton suddenly stops working

So I'm having issues with the buttons for the filters in my photo app. I'm not exactly sure why, but they've suddenly stopped working. The selector is not being called when they're tapped, but I have no idea why. They were working just fine a few days ago, but for some reason they're not now. I've checked the UIView subviews array, verified that it's right on top. I need a way to see if, for some reason, the touches are not making it to the button. I'm not sure how to do this.
I wish I had more information to give, but this is all I've got. I hope someone has some suggestions because I'm at wit's end with it.
Thanks in advance!
Button Creation Method:
-(void)createFilterButtonsForThumbnail:(UIImage *)thumbnail
{
UIView *filtersContainer = self.filterContainer;
CGRect buttonFrame = CGRectMake(kFilterFrameThickness, kFilterFrameThickness,
thumbnail.size.width, thumbnail.size.height);
CGFloat frameWidth = thumbnail.size.width+(2*kFilterFrameThickness);
CGFloat frameHeight = kFilterPickerHeight;
UIEdgeInsets backgroundInsets = UIEdgeInsetsMake(0, kFilterFrameThickness, 0, kFilterFrameThickness);
UIImage *buttonBackgroundImage = [[UIImage imageNamed:#"FilmReel"] resizableImageWithCapInsets:backgroundInsets];
for (int i = 0;i<(self.filterPaths.count+kFilterNonLookups+1);i++){
UIImageView *buttonBackground = [[UIImageView alloc] initWithFrame:CGRectMake(kFilterSidePadding+(i*(frameWidth+kFilterSidePadding)),
0,
frameWidth,
frameHeight)];
[buttonBackground setImage:buttonBackgroundImage];
UIButton *thumbnailButton = [[UIButton alloc] initWithFrame:buttonFrame];
UIImage *filteredThumbnail = [self applyFilterAtIndex:i ToImage:thumbnail];
[thumbnailButton setImage:filteredThumbnail forState:UIControlStateNormal];
[thumbnailButton addTarget:self action:#selector(filterSelected:) forControlEvents:UIControlEventTouchUpInside];
[thumbnailButton setTag:i];
[buttonBackground addSubview:thumbnailButton];
[filtersContainer addSubview:buttonBackground];
if ((i > (kFilterProMinimumIndex)) && ([self isProVersion]) == NO){
UIImageView *proTag = [[UIImageView alloc] initWithImage:nil];
CGRect proFrame = CGRectMake(buttonFrame.origin.x,
buttonFrame.origin.y + buttonFrame.size.height - kFilterProIconHeight-kFilterFrameThickness,
kFilterProIconWidth,
kFilterProIconHeight);
[proTag setBackgroundColor:[UIColor orangeColor]];
[proTag setFrame:proFrame];
[thumbnailButton addSubview:proTag];
[self.filterProTags addObject:proTag];
}
}
}
Selector Method:
-(void)filterSelected:(UIButton *)button
{
NSLog(#"Pressed button for index %i",button.tag);
int buttonTag = button.tag;
if ((buttonTag < kFilterProMinimumIndex+1) || ([self isProVersion] == YES)){
[self.imageView setImage:[self applyFilterAtIndex:buttonTag ToImage:self.workingImage]];
}
else {
[self processProPurchaseAfterAlert];
}
}
I see a couple issues in this, but I'm not sure which ones are causing it to break. First, you should instantiate your button using buttonWithType: on UIButton:
UIButton *thumbnailButton = [UIButton buttonWithType:UIButtonTypeCustom];
[thumbnailButton setFrame:buttonFrame]
The reason for this is UIButton is a class cluster, and you should let the OS give you the correct button.
Secondly, you're adding the Button as a Subview of an UIImageView, which by default, has userInteractionEnabled set to NO.
This property is inherited from the UIView parent class. This class
changes the default value of this property to NO.
You should have the button be one large button, with the background of the button be the image you want it to be.

iOS touching a UIImageView

- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
container = [[UIView alloc] initWithFrame:self.view.frame];
UIImageView* main_im0 = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"icon1.png"]];
[container addSubview:main_im0];
[self.view addSubview:container];
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *tt = [touches anyObject];
UIImageView *touchedview=(UIImageView*)[tt view];
NSArray *views = [container subviews];
for (UIImageView* im in views)
{
UIImageView* focus=im;
if (touchedview==focus)
{
}
}
}
I have this piece of code that setting up an ImageView called main_im0 which is put into a UIView container which then put into view. When I clciked on the main_im0, I expect the touch function would hit the condition of touchedview==focus. However, I couldn't get that condition activated? what's wrong?
Please enable
main_im0.userInteractionEnabled = YES;
by default it's No for UIImageView
Jason, maybe I am misinterpreting your code but aren't you going a round about way of achieving a tap gesture on a UIView?
You can use:
// enable user interaction with this view
main_img0.userInteractionEnabled = YES;
// setup a tap gesture to call a method once triggered (like a javascript mouseClick event)
UITapGesture *tapGesture = [[UITapGesture alloc] initWithTarget:self selector:#selector(myMethodToDoSomething)];
[main_img0 addGestureRecognizer:tapGesture];
// if you are not using Automatic Reference Counting, then remember to release your allocated tapGesture object
[tapGesture release];
...somewhere later in your code....
// method to do something
-(void)myMethodToDoSomething
{
NSLog(#"This method executed");
}
Now when you tap on your main_img0 view, the method "myMethodToDoSomething" will execute
By the way, if you just want a custom looking button with your own photoshop designed image, you can simply create a UIButton with code and set the background image property of the UIButton. Like so:
UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 100, 50)];
[button setImage:[UIImage imageNamed:#"mybutton.png"] forControlState:UIControlStateNormal];

Resources