1

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.

enter image description here

enter image description here

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)
            }
        }

6 Answers 6

1

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.

Sign up to request clarification or add additional context in comments.

4 Comments

The scroll view is over the top so that the image and button is shown behind it in the background. When scrolling it scrolls over the top of this image and button hiding them.
I have added 2 screenshots
@Ben_hawk you didn't understood Rob answer. He said to add the button to your UIScrollView content not to the image. This way the button can be touched. And the button will scroll outside the view when you scroll up, so all should be fine.
@Ben_hawk did my answer solve the problem for you? If it did can you accept it? If not, let me know what you're struggling with and I'll help. Cheers!
1

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

enter image description here

1 Comment

I don't think that will work in this case because the scroll view must be lower than the button and image so that it scrolls over the top of them.
0

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.

2 Comments

For point 2 it would not create the desired effect. The background image and button should remain fixed and be scrolled over the top of. The same effect can be seen in the Google Maps App when looking at details of place. The place image and back button is fixed at the top and the place details scroll over the top of them
I have added 2 screen shots
0

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:

1 Comment

You may also want to compare with touchesEnded for wiggle room :)
0

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.

Comments

0
+50

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.

1 Comment

I think I have managed to achieve this with option one, not sure if there is a better way, but I have updated my question with the solution I came to.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.