Part of the image clickable in iOS - ios

I don't know whether this is the right place to ask this question.
I have an image when I am displaying in a UIImageView. This image view takes the full screen. In the image there are facebook, twitter and email buttons (not actually buttons - it's designed in the image).
I want to make the facebook, twitter and email "buttons" tappable and do something. Is this possible?

You are not doing it the right way.
Most of the time when you make an interface there's a lot of logical components, and each components has its own actions (animation/tappable/editable components). For each different logical component you should put a different element on it.
In your case, I would set up a full screen UIImageView just for the background, add UILabels for the texts on it (you can opt-out on this if your text won't have any effect on it, but that's what I prefer because this way it's more flexible in the future). And on top of those, you can add UIButtons for the tappable elements, for example, Facebook and twitter buttons.
Edit: If you just hate making separate images, you can always make invisible buttons (a button without any text)

Implement the touchesEnded:withEvent: method and check if the touch location is within the rectangle of a desired button in the image.
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
[super touchesEnded:touches withEvent:event];
UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInView:self.view];
if (CGRectContainsPoint(_facebookButtonRect, location))
{
// Do your stuff.
}
}
You can also place invisible buttons on top of the image view.

For each button:
1) Add a transparent UIButton as a subview to your image view. Position it on your image by setting its frame. Use alpha=1 and backgroundColor = [UIColor clearColor] for the button. Also set the button title to "". All this should give you an invisible button that still responds to touches.
2) Handle the button tap event as usual.

Related

UIButton drag finger into the bounds

I'm trying to get a particular event to work.
The user should touch one button (A), this button would pop-up some UIView, in which there is another button (B).
If the user touchUpInside button A, the popup should disappear, and the Button (B) would not be clickable.
However, if the user clicks on button (A), and then drag his finger into the button (B) then this button (B) will be selected, but only fire if the user TouchUpInside this button (B)
I have tried the most obvious TouchDragEnter and TouchDragInside, but it does not do what I expected, you have to touchDownInside first for it to work. Since the TouchDownInside event has been done on the button (A), it can't be done on the button (B)
Have I missed something, or should I just go ahead a create a subClass of my own for this particular behaviour ?
To add some difficulty, the button (A) and button (B) are not on the same UIView.
If I was to go about this, I would ignore touchUpInside etc altogether and just focus on the drag event. In the touchesMoved method, keep checking where the touches are, and if they intersect the rect of the view you are concerned about.
Something like this : (apologies for incomplete example)
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint currentPoint = [touch locationInView:self];
if ( CGRectContainsPoint(imageView.bounds, locationInView) ) {
// Point lies inside the bounds...
I have just created a library called PopMenu that implements exactly the function you mentioned. The idea is it pops out buttons when you touchdown on the menu button and keep tracking the user's finger until the user touches up on the screen. It returns the button that the user ended his touch on.

UIScrollView scroll over background view

I have a UIScrollView (with a clear background) and behind it I have a UIImage that takes up about 1/3 of the devices height. In order to initial display the image which is sitting being the scroll view I set the scrollviews contentInset to use the same height as the image. This does exactly what I want, initialing showing the image, but scrolling down will eventually cover the image with the scroll views content.
The only issue is I added a button onto of the image. However it cannot be touched because the UIScrollView is actually over the top of it (even though the button can be seen due to the clear background). How can I get this to work.
Edit:
The following solved the problem:
//viewdidload
self.scrollView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: "onScrollViewTapped:"))
...
func onScrollViewTapped(recognizer:UITapGestureRecognizer)
{
var point = recognizer.locationInView(self.view)
if CGRectContainsPoint(self.closeButton.frame, point) {
self.closeButton.sendActionsForControlEvents(UIControlEvents.TouchUpInside)
}
}
Thanks for the screenshots and reference to Google maps doing what you're looking for, I can see what you're talking about now.
I noticed that the image is clickable and is scrolled over but there is no button showing on the image itself. What you can do is put a clear button in your UIScrollView that covers the image in order to make it clickable when you're able to see it. You're not going to be able to click anything under a UIScrollView as far as I can tell.
Please let me know if that works for you.
a simple solution is to reorder the views in the document out line. The higher the view in the outline, the lower the view is as a layer
Two things to test:
1) Make sure the image that contains the button has its userInteractionEnabled set to true (the default is false). Although, since the button is a subview and added on top of the ImageView (I assume) then this might not help.
2) If that doesn't help, can you instead add the button as a subview of the UIScrollView and set its position to be where the image is? This way it should stay on the image and will be hidden as the user scrolls down, but clickable since it is a child of the ScrollView.
Some code and/or images would help as well.
I think the way to do this is to subclass whatever objects are in your UIScrollView and override touches began / touches ended. Then figure out which coordinates are being touched and whether they land within the bounds of your button
e.g. in Swift this would be:
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent?) {
println("!!! touchesBegan")
if var touch = touches.first {
var touchObj:UITouch = touch as! UITouch
println("touchesBegan \(touchObj.locationInView(self))") //this locationInView should probably target the main screen view and then test coordinates against your button bounds
}
super.touchesBegan(touches, withEvent:event!)
}
See :
https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIResponder_Class/index.html#//apple_ref/occ/instm/UIResponder/touchesBegan:withEvent:
And:
https://developer.apple.com/library/ios/documentation/UIKit/Reference/UITouch_Class/index.html#//apple_ref/occ/instm/UITouch/locationInView:
You should subclass UIScrollView and override -hitTest:withEvent: like so, to make sure it only eats touches it should.
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
UIView *const inherited = [super hitTest:point withEvent:event];
if (inherited == self) return nil;
return inherited;
}
Also make sure to set userInteractionEnabled to YES in your image view.
There is 2 way you can checked that weather touch event is fire on UIButton or not?
Option 1 : You need to add UITapGesture on UIScrollView. while tapping on UIScrollView. Tap gesture return touch point with respect to UIScrollView. you need to convert that touch point with respect to main UIView(that is self.view) using following method.
CGPoint originInSuperview = [superview convertPoint:CGPointZero fromView:subview];
after successfully conversation, you can checked that weather touch point is interact with UIButton frame or what. if it interact then you can perform you action that you are going to perform on UIButton selector.
CGRectContainsPoint(buttonView.frame, point)
Option 2 : Received first touch event while user touch on iPhone screen. and redirect touch point to current UIViewController. where you can check interact as like in option 1 describe. and perform your action.
Option 2 is already integrated in one of my project successfully but i have forgot the library that received first tap event and redirect to current controller. when i know its name i will remind you.
May this help you.

How do I allow the user to add text the same way that snapchat does?

Where the user clicks on the screen and the keyboard and text field show up. Then when they are done it disappears and the text is saved. But I don't want the box to be around it I just want the words that the user typed to appear. I am somewhat a noob to Xcode, and I have been trying to figure this out for many days now. If you guys have any input that would be great!
Thanks in Advance
First you have to create a UiTextField or a UILabel.
In Snapchat the keyboard hides whenever you tap on the screen. Objective-C provides a methode to detect if the screen was touched.
Use - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
With resignFirstResponder you hide the keyboard from your label.
you have to implement -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event method, when method fired than
UITouch *touch = [touches anyObject];
float position = [touch locationInView:view];
and add UITextField at that point, and on return of UITextField create UILabel with the calculation of text size and add it to view at same position where UITextField was added and remove UITextField from superview.
Or for touch you also can use UITapGestureRecognizer

Make UIView area unclickable

So i have a UIView setup on the Ipad for a small project i am working on. I will be displaying an image or a view on that page. I wanted to know if is it possible to create an invisible border (say 1") around the view that will be unclickable ?
I was thinking of adding a button and disabling it, but i think that would not allow the image to be shown full screen.
I have already setup a recognizer, because i want a three finger swipe to go to the next image. What would be the best approach for this ?
Use a custom UIView class and override hitTest:withEvent:.
- UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
CGRect frame = CGRectInset(self.bounds, 25, 25);
return CGRectContainsPoint(frame, point) ? self : nil;
}
Adjust the inset to meet your needs.

iPad: How can I click buttons underneath transparent portions of a UIView

I am subclassing a view which is the same size as my main ViewController (1024x768). This subview has a transparent background and contains buttons that are sized 50w X 50h and are positioned dynamically.
My issue is that I need to interact with content and buttons that exist beneath this view but this subview is blocking that interaction.
I've seen some posts address a similar problem, but I am unclear of the actual usage.
-pointInside:withEvent: is how iOS asks if a touch is within a particular view. If a view returns YES, iOS calls -hitTest:withEvent: to determine the particular subview of that view that was touched. That method will return self if there are no subviews at the location of that touch. So you can pass any touches that aren't on subviews back to views behind this one by implementing -pointInside:withEvent: like this:
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
{
return ([self hitTest:point withEvent:event] != self);
}
If you need to catch some touches that aren't on subviews, your implementation will be more complicated, but this method is still the right place to tell iOS where your view is and accepts touch events.
Did you try to set userInteractionEnabled to YES or NO?
If all else fails you can bring those subviews to the front programmatically using
[self.view bringSubviewToFront:buttonToClick];

Resources