IOS - Superview is catching touch events on landscape mode - objective-c

I've a UIViewController created programmatically, and when I insert its view to my general view, the 300 pixels in the bottom of the UIView aren't getting any touch event, the touch event is being caught by the superview, the main UIView.
The important fact is that only occurs when I'm on landscape mode.
Any ideas?
EDIT:
Here goes an screenshot, the oranged background is the UIView that have its own UIViewController and that needs be touched, but the as I said, the last pixels from bottom (aprox. 275) are being catched by the main UIViewController. So the buttons are never called.
Only on landscape mode!

Related

How do automatically resize an NSPopover with auto layout

I currently have an NSPopover subclass which sets it content view controller to a custom NSViewController meant to represent a tab view:
self.popover.contentViewController = tabViewController;
self.popover.animates = YES;
I'm rolling my own "tab view controller" because I've heard that NSTabViewController doesn't play well with animations. I'd like to use auto layout so I don't think I want to mess around with the popover's contentSize property. When I change tabs the popover correctly changes its size, however, it doesn't animate the change. Furthermore, I have a cross-fade animation that occurs when the tab view switches and the popover doesn't resize until after the animation finishes.
First, I'd like to figure out how to get the popover resize to animate and then I'll worry about getting the animation in sync.
Thanks

NSScrollView + layer-backing

I have this hierarchy:
NSPageController -> NSScrollView -> NSView 1 (same size as scroll view) -> centered NSView 2 (a page in a catalog) -> more subviews (interactive elements on page)
this is from the NSPageController sample, I replaced the NSImageView there with NSView 1.
Now I want to enable layer-backing and set the wantsLayer and layer redraw policy.
The problem I'm having is that as soon as I turn layer backing on the NSScrollView it no longer properly updates the layer bounds of NSView 1 when zooming the scroll view with a pinch gesture on a trackpad.
What am I missing to have the trickle down of layer-backing work?
Also, I found that if I enable layer-backing beginning with NSView 2, then the resizing works, but the page image I'm drawing there looks very coarse. I moved to NSView 1 with the layer-backing because I also want a shadow on NSView 2 and this only shows up if the superview has layer-backing turned on as well.

Handle tap event by subview of UIScrollView while scrolling

I have custom UIScrollView subclass with some content views inside. In some of them I have UITapGestureRecogniser. All works fine when scroll view is not scrolling. But when it scrolling content views does not receive tap action. What is the simplest solution to handle tap action by subview while scroll view is scrolling?
Details:
MyScrollView scrolls horizontally. It contains a lot of content views (e.g. MyContentView). Each MyContentView has width about one third of MyScrollView width. So there are about 3-4 visible MyContentView elements at a moment. The main behavior of MyScrollView is to 1)make sure that after scrolling one of MyContentView elements will be at center of screen and 2)to scroll to center of MyContentView if user taps on it. So the main answer I hope to get is how to "properly" implement handling of tap action in MyContentView while MyScrollView is decelerating.
I found some same questions and answers but none of them satisfied me. The best was to implement gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer: of UITapGestureRecogniser delegate. But in this case I sometimes (when I tap, make smaaaal drag and release finger so tap is steel recognizable(lets called it quasi tap)) have both tap and scroll events and it leads to bugs for me even if scroll view is not scrolling when I begin tap. When user make quasi tap my application tries to scroll to tapped MyContentView element and than immediately handle normal scrolling. It seems even more terrible, due to some other functionality start to perform after handling tap (it must not perform when normal scrolling).
I need solution where scroll view wait enough to decide it is not tap event and only then make scroll. Otherwise if tap event had recognized scroll must not happen.
You can go with the custom delegates methods as well, using #protocol. Implement those delegate methods in view controller where your UIScrollView has been added.
like in MyContentView:
In touchesBegan method,
[self.delegate contentViewTapped:self];
Now in ContainerView class where scroll view is added, implement that method:
- (void)contentViewTapped:(MyContentView *)myContentView {
NSLog (#"ContentView no: %d", myContentView.tag); // if tag has been set while adding this view to scrollview.
}
Go through the examples for #protocol.
Hope this is what you required.
Enjoy Coding :)
This is built into UIScrollView - take a look at the delaysContentTouches and canCancelContentTouches properties. This should alleviate the problem when dragging a small bit after a tap.
This is all system built-in behaviour. I would suggest sticking with what Apple has provided for the feel of your interface (how it reacts to small drags, for instance) so that your app doesn't feel out of place on a user's phone.
EDIT:
Alternatively, you could disable scrolling of your scroll view in you gesture recognizer and re-enable it once it's ended/cancelled.
Further Edit:
I don't understand - I've created a sample project that illustrates how to intercept touches in a subview of a scroll view using gesture recognizer delegate methods. Play close attention to the "Cancellable Content Touches" and "Delays Content Touches" properties of the scroll view. They're both YES for very important reasons.
You scroll view should be delaying content touches until it has determined if the user is attempting a tap, pseudo-tap (as you put it), or a pan for the scroll view. Apple has already written the functionality you're trying to build; UIScrollView will already do what you want.
The problem is that the system doesn't want a scroll view's subviews intercepting tap events while the scroll view is scrolling. To this end, it cancels touch events if it determines that the user is actually trying to pan. Setting "Delays Content Touches" enables this behaviour. Ensure it's turned on and you should be fine.

Coordinates in landscape mode iPad app correspond to portrait mode

I'm having a weird issue with an iPad app I'm writing.
I want to add a UIToolbar to my main view controller (set as root view controller in the app delegate). Within this main view controller, I support only landscape orientations. When I set the frame for my toolbar, however, it seems that the ipad still thinks it's in portrait mode! What I mean by this is when I run this line:
[_toolbar setFrame:CGRectMake(0, 0, [[self view] frame].size.width, 44)];
The width of the toolbar is only 768, rather than 1024, even though the width of the screen at this point is clearly 1024, because the toolbar extends across only 2/3 of the screen. I'm having similar problems with placing subviews, and getting really weird placement on my main view controller.
Has anyone else run into problems like this? If so, how did you fix it? Thanks!
You should use the view's bounds, instead of frame, and you should not execute your code too early in the view's life cycle.
If you invoke your code from the control's viewDidAppear, then I guess it will work. But if you invoke your code from viewWillAppear, then it is too early.

Removing views from UIScrollView

I have two UIScrollViews that I move images between. The user can drag and forth between the scroll views. I am trying to animate the movement of the image from one scroll view to another. In -touchesMoved (handled in my UIViewController which has two custom UIScrollViews that intercept touch and sends to my UIViewController), I am trying to set the "center" of my UIImageView that is being moved. As it is moved, the image gets hidden behind the UIScrollView and not visible. How do I make it appear on top of the UIScrollView? I am able to handle the -touchesEnded properly by animating in the destination scroll view.
I am also confused about -convertPoint:fromView: usage in the iPhone Programming Guide (See Chapter 3, Event Handling). If the touch coordinates are in window coordinates, to change my view (UIImageView inside a UIScrollView which is inside a UIView and inside a window) center don't I have to use -convertPoint:toView:, i.e.,
imageView.center = [self.view.window convertPoint:currentTouchPosition toView:imageView];
What am I missing?
You can use the method - (void)bringSubviewToFront:(UIView *)view for making the image view the front most view.
Johan
It depends on how you structured your views. If both scrollviews and the imageview are at the same level, it should work. If the imageview is a subview of one of the scrollviews, you can try bringing the scrollview to the front. That way also the imageview will be drawn over the other scrollview.
Johan
I have a View Controller with two ScrollViews. Images are added as subviews. ScrollViews are already in the front. I tried bringing scrollview to the front and also imageview of the scrollview to the front. But somehow when i drag, the center of the image goes over my other scrollview2 which i also tried sending back. But does not seem to work. Here is what i do, in TouchesMove (inside a ViewController)
view= [[scrollView1 subviews] objectAtIndex:currentImageIndex];
[self.view bringSubviewToFront:scrollView1];
[scrollView1 bringSubviewToFront:view];
[self.view sendSubviewToBack:scrollView2];
scrollView1 and scrollView2 are two scrollviews that are part of the ViewController's view.
Does this make sense ?
thanks
mohan