UIButtons located in a UIView underneath interfering - iphone

I have a UIScrollView over the main view of the view controller. UIScrollView contains some UIButtons (detail disclosure type) and a floating UIView -- all managed by only one view controller.
The floating UIView also contains its own UIButtons (custom, not rounded type). User is allowed to hide the floating UIView, or move it to a new location.
I found that the UIButtons contained in the UIScrollView (parent) are interfering with (preventing) tapping of the UIButtons contained in the floating UIView whenever these UIButtons overlap. If partially overlapped, only the overlapped area is a dead zone. I tried explicitly bringing the floating UIView to the front by issuing this message:
[self.myScrollView bringSubviewToFront:myFloatingView];
-but the problem does not go away.
The interference goes away if I keep the UIButtons of the parent hidden. But, this is not what I want.
Any suggestion will be appreciated.
Thanks you

A button can not interfere in the way you described. I think it something else.
All of the times I have had similar issue have been because subviews were taken outside the bounds of their parent views. The rule is:
If a subview is outside of its parent view's bounds it will not receive touch events.
This isnt explicitly stated in the docs but you can infer it by reading sections of the touch event guide.
I think what might be happening is that you are moving the floating UIView outside of its parent bounds.
It might not be it, its just a suggestion.

Related

iOS: how to allow all gestures/events *with a couple exceptions* to pass through a top level view to its subviews

I have an atypical iOS interface. Perhaps it's not practical but I'm giving it a go. Hope someone can help!
I have a menu in the form of a UIVIew. It contains 5 small UIImageViews. A UIPinchGestureRecognizer is attached to the UIVIew. When pinched inward, the 5 UIImageViews animate from off screen to form a circle in the middle of the window. When pinched outward, they animate back offscreen. Everything works great there.
I'd like to be able to, at any point in the application, pinch the screen to reveal the menu, select one of the 'buttons' (UIImageView), and load the associated subview.
The real problem is, if the current visible view is a UIScrollView or UITableView, my app is having trouble figuring out whether the menu or other subview should handle the touch event. If I really focus and make sure two finger touch the screen at the EXACT same time, the pinch will work and pull the menu inward. But otherwise, it attempts to scroll the current visible view.
I would like all events except the pinch gesture, (and a tap gesture when the menu is visible), to pass through the menu view to the rest of the subviews.
I understand I can override the hitTest:withEvent method to determine the correct view to handle the event, but I'm unclear at this point how exactly to use it. Neither the Apple docs nor any answers I've read on stack overflow have made this method clear to me.
Any help is much appreciated.
As UITableView is a subclass of UIScrollView, it inherits all of UIScrollView's properties including its gesture recognisers.
UIScrollView declares a UIPinchGestureRecognizer and UIPanGestureRecognizer. I'm not sure of the implementation details but I imagine the UITableView disables the pinch gesture recogniser as you are not supposed to be able to zoom a tableview!
In any case, you can attach your own UIPinchGestureRecognizer to the table view:
UIPinchGestureRecognizer *yPGR = [[UIPinchGestureRecognizer alloc]
initWithTarget:probablySelf action:yourMenuShowSelectorHere];
UITableView *tv = ...
// ...
[tv addGestureRecognizer:yPGR];
Then, you can make sure that the UITableView scoll does NOT scroll until your pinch has failed:
[tv.panGestureRecognizer requireGestureRecognizerToFail:yPGR];
This way, the UITableView will not scroll until it is sure that it has not detected a pinch.
EDIT: UIScrollView only uses (or at least declares public access to) UIGestureRecognizers in iOS 5 and up.

UIScrollView not detecting touches past the fold

I have a UIScrollView instance with many views inside. I have touchesBegan: defined inside my implementation of a subclass of UIView, but touches are only detected for views that are originally shown inside the scrollview (without scrolling). That is, initially all touches are detected, but when I scroll down, no touches are detected, except for on those views which were originally above the fold (i.e. they originally fit in the scrollview), and moreover, only those parts of those views which were above the fold (in the cases of views that were partially shown originally).
I hope this is clear... anyone have any idea what could be causing a situation like this?
After a day of debugging, I found the simple solution. The height of the frame of the view inside the scrollview had been set to the height of the screen. I needed to extend it to the full height of the scrollview.

UIView take away first responder status

Imagine the situation when you have UITableView placed into UIScrollView.
If you tap on table view and begin vertical moving - UITableView become first responder and will scroll vertically. But if you will move finger horizontally - UIScrollView become first responder and will scroll horizontally.
I have similar situation but instead of UIScrollView I have simple UIView object that intercept - (void)touchesMoved: events and make moving (kinda self made ScrollView).
But how I can do the same trick that UIScrollView do - determine horizontal moving and take away first responder status from UITableView???
Thanks in advance!!!
You could try overriding canBecomeFirstResponder in your view and returning the appropriate value at the appropriate time.
Have you tried throwing a UIPanGestureRecodnizer on the view. You should then be able to set a #selector which will allow you to handle the event in question. Also with pan you can choose to only change the x element and leave the y element alone. Further more with the pan element attached to a view you will not have to worry about having a first responder. Pan elements can a lot of the time be used as a swiping element if you had acceleration and or deceleration. Beyond that I would say you could also add a UISwipeGestureRecognizer element left and right but I do not think you get information such as how far the user swiped meaning, if you want the screen to snap back when the user has not made it far enough to the right or left then you will not have that option. Also, swipe will not give the same effect as the UIScrollView but UIPanGestureRecognizer can, if you do a little extra coding. The extra coding would be observing the position of the x value and then using a little bit of animation for the view to snap to the right or left when the user lets go of the view. Other then that the view should and will follow the finger if you set the x properly.

Nested UITapGestureRecognizers

If I have several views stacked one on top of the other (all subviews of each other) where each one has a UITapGestureRecognizer attached to it.
How can I make sure that the highest visible view received the gesture and not the furthest ancestor?
The tap gesture is only valid for the current view. Further the frame of your current view(-controller). You can create a blank view over the hole screen and put in there your current view lets say 200x200 px. (essentially it is both in the same view)
Now all gestures should respond to your topmost view-controller. The bad thing about that: you can't access the views below anymore.

UIScrollview with two images - Keeping 1 image zoomable and 1 image static (fixed size)

I have a UIView which contains a zoomable UIImageView and also another semitransparent UIView on top of that.
What I am trying to achieve is to be able to zoom the UIImageView while keeping the semitransparent view static and not zoomed.
If I add the semitransparent UIView on top of the UIImageView (which is added to the UIScrollView), everything zooms. However, if I add both as subviews to the base UIView, the touches only get tracked is the semitransparent UIView since its the last one added.
I do need control to reside first at the semitransparent UIView for the touches since I may want to resize the semitransparent view. However, I'd like to pass control of the touches to the UIScrollView if two fingers are used. Is there anyway for me to achieve this? The nextresponder doesn't seem to work. I also tried to use hittest in addition to subclassing UIWindow, but the base UIView needs to push/pop navigation controlling ability so I don't think I can subclass UIWindow to push onto the navigation stack.
Any help would be appreciated.
Thanks,
Winston
Hm.. you can try this hierarchy (possibly subclasses):
UIView (container)
> UIView (semitransparent overlay)
> UIScrollview
- UIView (zoomable content)
Like this, the overlay does not scale.
The tricky thing then is the user interaction on multiple layers. Its easy if there are areas in your overlay that should not detect user touches, for that you just set the UIView property 'userInteractionEnabled' to 'NO' for the view parts where touches should be 'forwarded' to the underlaying layers.
But if I get you right, you need something more complicated. You probably could set up some kind of master-touch-controller in the container UIView, that finds out what is happening and then calls certain methods of its subviews / forwards the events.
I don't know all the exact methods you need to override/implement in the container, but check out the tapZoom demo from the ScrollView Suite sample code. It's a pretty nice example there.
Just out of curiosity, may I ask what this interaction model is used for?