UIPopoverController should prevent scrolling via status bar - ios

I've found that when presenting a UIPopoverController not all controls in the presenting view are disabled. Specifically, the navbar buttons (e.g. 'back') remain selectable. This is a defect in my opinion - it allows the popover to remain on screen, while the view stack pops behind it.
Oh well, at least this can be rectified using self.aboutPopoverController.passthroughViews = nil immediately after presentation.
Except this doesn't disable the status bar, which is often set up to scroll the view's content to the top.
The end result is the ability to present a popover, and then (in the background) scroll the view so that the small arrow/tab on the popover is no longer aligned with the original touch point.
Can anyone shed some light on this behavior? Is it a feature or a bug? Any workarounds?

A simple workaround could be the following:
Just before you display your UIPopoverController set UIScrollView's property scrollsToTop to NO. This way when the user taps on the status bar your scrollView won't scroll.
When you're done with the popover you can re-enable the scrollsToTop functionality.
Here is the UIScrollView documentation:
scrollsToTop
A Boolean value that controls whether the scroll-to-top gesture is enabled.
#property(nonatomic) BOOL scrollsToTop
Discussion
The scroll-to-top gesture is a tap on the status bar. When a user makes this gesture,
the system asks the scroll view closest to the status bar to scroll to the top.
If that scroll view has scrollsToTop set to NO, its delegate returns NO from
scrollViewShouldScrollToTop:, or the content is already at the top, nothing happens.
Hope this helps!

Related

Scrollview scrollsToTop doesn't work when containing multiple side by side tableviews? Have searched repeatedly

I looked in this thread and tried everything I saw, and I can't seem to get it working.
Scroll to top of UITableView by tapping status bar
I have a UINavigationController and a UITabBarController. The application first opens to a UICollectionView.
When the user makes a selection, it brings up a ScrollView run by a custom UIViewController ("ScrollViewController"). The ScrollViewController makes four TableViewControllers and puts their TableViews in the ScrollView side by side with paging enabled, and has a floating UIPageControl as well.
Tapping the top bar scrolls the CollectionView to the top, but once I bring up the ScrollView, I can't scroll up from anywhere. I have tried setting all the TableViews' scrollsToTop to NO, no change.
Any suggestions?
That's correct. You can only have one scroll view controlled by the tap of the status bar. If you have multiple scroll views on the screen (either hidden or visible) you can set one of them to be controlled by the status bar tap by disabling the auto scroll on all of the other scroll views using scrollsToTop = NO, that includes anything that uses a scroll view within it, like a table view or a pager.
self.myTableView.scrollsToTop = NO;
According to Apple's documentation:
On iPhone, the scroll-to-top gesture has no effect if there is more than one scroll view on-screen that has scrollsToTop set to YES.

View moves down when keyboard appears

I'm building an iPad app and there is something weird going on with the top edge of the view in relation to the status bar when the keyboard appears.
The view has a view with a segmented controller at the top with a container view below. When a button in the segmented controller is selected, the view in the container view changes.
I've done some research into the matter (it's definitely iOS 7 related) and have not found any kind of fix. I tried setting edgesForExtendedLayout to UIRectEdgeNone but that does not seem to have any effect. Even more strange, the view only moves half way to its original position when the keyboard dismisses. Any suggestions? I included screenshots below.
Original:
When keyboard appears:
After keyboard dismisses:
I can only assume your code is doing something to move the view when the keyboard appears then later disappears. So you state your view is a UIViewcontroller subclass (implying no contentOffset property). Log the values of the following before and after the keyboard action - one of them must have changed: contentInset, bounds, frame. Knowing which one will assist you in finding the problem.

Animate Controls down with change to UINavigationBar

I have a UINavigationController with standard UINavigationBar. When presenting certain UIViewControllers and orientations, the UINavigationBar may or may not appear and it may or may not have a prompt element. This means that the bar height changes frequently.
I have some subviews below the UINavigationBar set with NSLayoutConstraints to topLayoutGuide. It generally lays out as expected, adjusting vertical position of the subviews appropriately based on the height of the UINavigationBar. What it does not do is move the subviews at times when the UINavigationBar is animated after the view is already displayed.
Specifically, coming from a state with UINavigationBar hidden, transition to a UIViewController which does not hide the navigation bar to one which does. The view displays, then navigation bar animates into place. The subviews do not move down. If I rotate the device, every things lays out appropriately again. Only when animating the navigation bar in and out or to display/hide the prompt I not find a hook to reevaluate the constraints.
I tried [self.view updateConstraints] and [self.view updateConstraintsIfNeeded] in various places such as viewDidAppear, viewDidLayoutSubviews. Nothing seems to update that topLayoutConstraint.
I am familiar with edge restraints, translucent navigation bar and other various methods of keeping the entire view from appearing under the navigation bar. I do want to keep view full size and I want the translucent bar so these are not solutions for me. It seems the constraints should handle this automatically, hence the "auto" in auto layout.
To simplify, for recreation, UINavigationController with rootViewcontroller showing normal navigation bar with just a title. In viewDidLoad of the next presented viewController I have [self.navigationContoller setPrompt:self.myPrompt]. The view is presented, when the prompt is set, the navigation bar grows larger. Some labels below the bar are set with relation to topLayoutGuide, which places them correctly initially. I expect they would move down when the bar grows. Rotate device back and forth, they now layout correctly. Pop the viewController and push back to top, repeats as above.
So, it turns out it was all me. After trying all manner of forcing layout updates in all sorts of ways, the solution was to move the [myView setPrompt:myPrompt] out of viewDidLoad and call it in viewDidAppear instead.
Works completely as expected. Navbar grows, subviews shift and shrink as needed. Now I have to hunt down all the experimental code I plastered everywhere trying to do it wrong.

Present UIPopoverController from a moving rect

Just got this weird problem, where I have a scroll view and buttons in the scroll view. I want to display a UIPopover from the button when touched, with UITextFields inside the UIPopover. The problem comes when the Keyboard appears. In certain cases, when the UIButton is so high in the view that the popover can only be displayed under it with the UIPopoverArrowDirectionUp, and when keyboard pops in, this popover cannot move any more up and therefore magically disappears to the top left corner (probably some Apple thing).
My solution is to check the frame of the UIPopover and to check that there is enough space for the keyboard, and if not, scroll the UIScrollView up with the buttons as well in order to be able to push the UIPopover up and so make sure that both the Keyboard and the popover fit.
So the question is: Is it possible to move the popover as the button moves?
Thanks

Why are touches not detected at top of screen with status bar hidden?

In our app, we show modal windows that take up the whole screen, and we hide the status bar at this time. However, buttons placed at the top of the screen have reduced hit areas: their tops do not detect touches. This is true of custom buttons and buttons in the navigation controller.
What is preventing detection of those touches?
FYI: I have two other windows, a HUD view and a status bar overlay, and both are hidden. I've tried putting the status bar overlay behind the main window, as well. Problem remains.
Update: This problem is caused, at least in some cases, by hiding the status bar while still having a scroll view with scrollsToTop set to YES. Although I have found a case where the problem remains even after disabling scrollsToTop for all resident scroll views. (I wrote a simple method to walk the view hierarchy to find all scroll views and report their current scrollsToTop setting.)

Resources