subview outside parentview frame events - iphone

I'm adding programmatically an UIView B to another UIView A.
The A frame is {{0, 372}, {320, 44}}.
B UIView is add at {0, -74} and is {320, 74} wide.
My problem is that B touch events are not handled.
More precisely touch events are handled to a sibling UITableView of UIView A wich ends at {0, 372} even if B UIview is displayed over UITableView.
Any solution please ?

To determine the view in which a touch event falls, Cocoa traverses the view hierarchy (and sends each subview a hitTest:withEvent: message. In turn, this message calls pointInside:withEvent: on itself, which returns a boolean value that indicates whether the view contains the specified point.
Presumably, you could subclass your UIView A and override its pointInside:withEvent: method to return YES also for points that are outside A's bounds but inside B's.

Okay, your B-UIView is completely outside and above the bounds of A-UIView. If you set up two generic views with the same frames like this in Interface builder and set the backgrounds to different colors, you will see absolutely nothing of B-UIView.
alt text http://img256.imageshack.us/img256/6789/screenshot20091030at350.png
It's exactly like defining a view whose frame is outside the bounds of the screen. If no part of it is visible it will not trap touches because it's off in undefined space having tea with the square root of negative one.
The UITableView is handling the hits because the B UIView is not in the responder chain at all.
You need to make B-UIView a sibling of A-View instead of an invisible and inactive subview. Then overlay that on the bottom of the UITableView.

You cannot do this in such way. You should add both your A and B views to another view C. And it will work.

Related

UIButtons located in a UIView underneath interfering

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.

ScrollView outside visible View

I try to create something similar to the task-menu in iOS4:
(Sorry cant post images not enough Rep)
I have normal ViewController on thats view i addSubview of my menuView. I set menuViews Y to -95 so i can just move the viewControllers view 95 Down to Display the menu. But the scrollView in my menuView doesn't work if the menuViews Y is Negative.
Your scrollview doesn't receive the touch input because it is outside the bounds of the its superview (the view of the main ViewController you mentioned). The way the touch interaction system works is the AppKit framework goes down the view hierarchy testing each view and subview with the - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event function. If a view returns YES to this function, it will start the process all over again with all of its subviews until it finds the lowest subview that still returns YES. The problem with your setup is that the superview of Scrollview is going to return NO because the touch is above it and your menuView never even gets tested. So you have two possible solutions:
Implement your ViewControllers view as a subclass of UIView (if it is not already) and overload the pointInside:withEvent: function to return YES if the touch is within it's frame OR if it is within the bounds of menuView (ViewControllers frame minus the frame of menuView).
The second solution would be to simply put menuView at the origin of its superview (0,0) and leave the ViewControllers view at (0,0) as well.
I suggest the second as it is less convoluted and more to the point.

UIScrollView inside a CALayer

I'm developing some kind of card game in which my view objects (cards, etc) are all CALayers. These objects are added as sublayers of a mainBoard (a CALayer), which, in turn, is a sublayer of the [UIView layer] property of my mainView. Everything is Ok, I can do hit testing to verify which layer is being touched through the touchesBegan:withEvent: callback of the mainView class normally, and so on.
However, I need to have a scroll inside my mainBoard to show "bigger" CALayers, so I tried first adding the "bigger" CALayer inside a CAScrollLayer, but I noticed that the CAScrollLayer doesn't really scroll (doesn't handle user input, neither draws scrollbars). So, the workaround would be to add an UIScrollView directly to the mainView UIView. The UIScrollView scrolls perfectly, until I try to add the "bigger" layer to it, by using [scrollView.layer addSublayer:<bigger layer>].
Does anyone has any idea of how I can have "scrollable" objects inside a CALayer?
Thanks!
nacho4d pointed the answer for my question.
Replying to mark: the "bigger" layer (a layer whose bounds is bigger than the area available in the screen (and so, needs to be contained in a scrollable area)).
The solution was to first wrap the "bigger" layer in a UIView:
UIView *wrapperView = ...
[wrapperView.layer addSublayer:<bigger_layer>];
afterwards, I can add the view as a subview of the UIScrollview:
[<uiscrollview> addSubview:wrapperView];
// set up scrolling properties
<uiscrollview>.contentSize = <bigger_layer>.frame.size;
The problem was that I was trying to add the "bigger" layer as a sublayer of the UIScrollview directly, instead, wrapping it in a UIView and adding it as a subview worked.
Thanks

Cocoa-Touch: Can I have multiple views per view-controller, or specify bounds of a uiview?

Here's a hypothetical question:
Say I subclass a UIView that draws a triangle and I want this triangle uiview to part of the screen. And then say I subclass another UIView that draws a rectangle and I want the rectangle to take part of the screen.
In other words:
Can a view-controller have multiple views simultaneously being drawn on the screen
If so, can I set location bounds for these views. Say I want a view 50x50 on the left side of the screen etc?
Can I specify the bounds via interface builder?
A view controller owns a view hierarchy, not just a single view. However, that hierarchy must have a root at some top level view, which ends up being self.view for the view controller.
The view that is self.view need not have any direct content to display. It can simply be a UIView that holds other views, your rectangle and circle. The root view should be large enough to cover (really be under) any other views it contains. All the views in the hierarchy may be laid out in interface builder.
yes
yes
yes

Second UIScrollView responding when using a UIScrollView

This is more of a check as I believe this is right but its a lot of work if I'm wrong.
I want to basically achieve fixed positioning with a scrollView. I want to have a list along the top that is always visible, scrolls horizontal only and then a scrollview beneath that to move around the information which scrolls both vertically and horizontally.
I figure I need to subclass UIScrollView and overwrite touchesBegan, touchesMoved and touchesEnded to send the touch to both UIScrollViews.
Is this right or off track?
Cheers
Overriding the touch events on a scroll view is probably not what you want to do. Instead you can simply use a single scroll view, and then in the parent view's -layoutSubviews or in the scroll view's delegate methods you can move the list so it's always at the same vertical position (use the scroll view's contentOffset property to determine where that should be). Both the delegate method and -layoutSubviews is called before the drawing actually occurs after the scroll view scrolls, so by always repositioning your view where you want it to be, it will appear to remain fixed to the user.