I have a UIViewController that is presented with UIModalPresentationFormSheet. So when the keyboard is visible it stays visible until the view controller gets dismissed.
In that UIViewController I have a navigation controller. So in every UIViewController pushed to that navigation controller I have to check these things:
when the keyboard shows/hides I have to adjust the contentInset
when view appears I have to check if the keyboard is visible or not (the navigation controller remembers that with the notification) and adjust the contentInset. I push UITableViewControllers there, so I don't get viewDidAppear and co. So I have to do all this with the UINavigationControllerDelegate methods?
on every rotation I have to do adjust the contentInset
Otherwise the keyboard may cover some content.
Is that the correct handling? Isn't there any easier solution for this problem? Because this is kind a messy!
I didn't found a better solution, so i did it this way.
Related
I have a UINavigationController subclass, which manages a custom navigation bar. This navigation bar's look depends on the top view controller. I ask the top view controller about the type of the bar to be displayed when -pushViewController:animated: or -popViewControllerAnimated: happens.
The problem is, that the navigation bar type change is played when the user starts swiping but I could not find any event which tells me that the swipe was successful or not, so if the user cancels the swipe, I stuck on the previous view controller with the desired navigation bar look of the one below it in the navigation stack.
I have tried UINavigationControllerDelegate, but neither -navigationController:didShowViewController:animated: nor -navigationController:didShowViewController:animated: gets called. My second thought was to use interactiveGestureRecognizer, but it seems it it ends successfully both on successful and cancelled back swipe, and the topViewController is also still the same when the recognizer event is called.
I know, that the top view controller's -viewDidAppear will be called again upon cancelled swipe, but I don't want my users to implement any logic in their controllers to support my navigation implementation.
Any ideas?
Try using the UINavigationControllerDelegate, you can rely on its callbacks to know when a viewController is going to be displayed or not.
Getting interactivePopGestureRecognizer dismiss callback/event
my UIPageViewController class conforms to UIPageViewControllerDataSource protocol and yet UIPageControl is not visible.
I've attached screen representing segues between UIPageViewController and it's child UIViewController's which are added by setViewControllers method.
Question is why Page Control is not shown and what can i do with it except adding UIPageControl instance to view myself ?
For some reason, it seems as though UIPageControl only appears when the Transition Style is set to "Scroll" -- very frustrating! (Hope I'm wrong?)
Click on your UIPageViewController ('Home Page View Controller'?) to see the option under Page View Controller.
Make sure you've implemented the optional -presentationCountForPageViewController: and -presentationIndexForPageViewController: data source methods.
UIPageViewController.h is very clear about the requirements:
A page indicator will be visible if both methods are implemented,
transition style is 'UIPageViewControllerTransitionStyleScroll', and
navigation orientation is
'UIPageViewControllerNavigationOrientationHorizontal'.
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.
As what I said above. I encountered a problem that I have to dismiss the popover on screen while I don't know where it come from.
What I want to do is : when the app become inactive, I want to dismiss the popover. But I don't know where the popover is presented, and which controller is responds to it?
Is there a notification which I could listen to when the UIPopover is presented?
Or can I find the Popover on the screen?
Thank you guys.
Just subclass your own implementation of UIPopoverController and overridepresentPopoverFromRect:inView:permittedArrowDirections:animated and presentPopoverFromBarButtonItem:permittedArrowDirections:animated and keep track of popover references in a global array. Since Apple's HIG says only one popover is allowed at a time on screen, you only need to track the last one.
I have added a UIButton to a toolbar that is only accessible via the RootViewController (which has a navigation bar and toolbar) of my app. When navigating to another view, I hide the UIButton, but when I go back to the initial screen (a map view) the UIButton remains hidden and I must unhide it. Since it is the RootViewController I am doing this in, viewWillAppear is not called, so I cannot use that method.
I am wondering if there is any way the RootViewController knows when a view is being popped off the navigationController stack, if so, how would you suggest I check for this? Is there any way you would recommend implementing this?
Thanks in advance!
if your app using UINavigationController for navigation then viewWillAppear will obviously called