In my VC I have a container view that holds an embedded table view.
My problem now is that I cant use navigationController?.hidesBarsOnSwipe = true
In my VC since it won't pick up swipes from the embedded table view. I have also tried to set hidesBarsOnSwipe = true in my table views VC but I can't catch that in VC1.
I have also tried to make deletages in my table view that fires once I scroll up or down and then I hide the navigation bar. But the problem there is that I can't get it to stay hidden or visible since the scroll has a bounce effect / pull to refresh = will hide/show my nav bar a few times in a row since its bouncing. And I don't want to remove the bounce effect.
So is there any way to detect navigationController?.hidesBarsOnSwipe = true in an embedded table view?
You can add a gesture recognizer, and in its delegate return true in method called func gestureRecognizer(UIGestureRecognizer, shouldRecognizeSimultaneouslyWith: UIGestureRecognizer) -> Bool to make tableView work alongside with GestureRecognizer. After that you can handle swipes to hide or show navigationBar whenever you wan.
Related
This question already has answers here:
Disable gesture to pull down form/page sheet modal presentation
(16 answers)
Closed 3 years ago.
I have a tableViewController which is presented modally with the default sheet style presentation.
I want to keep this modal style as it looks good and works well in my app. And I like the dismiss when pulling down on the navigation bar. However what I don't want is pulling down on the tableView cells to cause the tableViewController to be dismissed when the tableView is already scrolled to the top.
Is there anyway to inhibit this behaviors but keep the sheet style modal presentation? I want the pull down on the tableView to keep the vertical bounce effect and only to be able to dismiss the modally presented tableViewController through pan by pulling down on the navigation bar portion.
You can disable the pull-to-dismiss behavior by setting isModalInPresentation to true on your table view controller when the user begins dragging on the table view, and then reset it back to false when they stop dragging, like so:
class YourTableViewController: UITableViewController {
override func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
isModalInPresentation = true
}
override func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
isModalInPresentation = false
}
}
Note that you'll still be able to slightly pull down your table view controller, but at least you won't be able to dismiss it entirely. And since the value is set back to false when dragging stops, you'll be able to dismiss by pulling down on the navigation bar.
Also, if you add a UIRefreshControl to your table view, it disables the pull-to-dismiss behavior when pulling down on the table view.
The end goal is to create the same scrolling effect as the one on the "Me" tab of the twitter iOS app where the segmented control rises to the top as you scroll down and then stays fixed to it unless scrolled back up to the top.
The solution I've come up with is illustrated below. There is a view at the top, a segmented control, and a table view beneath the segmented control. All of these elements are embedded inside a scrollview that takes up the entire screen (minus tab & nav bars).
Here is the key issue: If begin scrolling by swiping up from the top-most view or the segmented control, it scrolls the scrollview that all the elements are embedded in. If I scroll the tableview, it will only scroll itself and leave the top-most view and segmented control unaffected.
How can I scroll the scrollview that the elements are embedded in no matter where the scrolling occurs on screen?
I had a similar layout in one of my projects. I used SJSegmentedViewController.
It Requires a headerViewController ,datasource for middle segment and viewController array for those segments.
This library allows you to scroll from anywhere on the screen moreover the segmented control sticks to the top as user scrolls all the way to top.
Here is how you can implement this :
First import the module into your class
import SJSegmentedScrollView
Then create a headerViewController and two viewControllers(Say Video and Tips) for segment
let headerViewController = HeaderViewController()
let video = VideoController()
let tips = TipsController()
After that set these Controller and also set the title for segmented control as following:
segmentController.headerViewController = header
segmentController.segmentControllers = [video,tips]
video.title = "Video"
tips.title = "Tips"
Then add it to the Container View
addChildViewController(segmentController)
containerView.addSubview(segmentController.view)
segmentController.view.frame = self.containerView.bounds
segmentController.didMove(toParentViewController: self)
Here Container View is a UIContainerView
Last but make sure to call in child controllers (VideoController,TipsController), After calling this function in those controllers you can scroll from anywhere on the screen.
extension HomeListingViewController: SJSegmentedViewControllerViewSource {
func viewForSegmentControllerToObserveContentOffsetChange() -> UIView {
//Scrollview in child controllers
return scrollview
}
}
You can find the full documentation here
Hope this helps!
I want to hide/show navigationBar of a UINavigationController when the WKWebView zooms out/in.
To hide or show a UINavigationBar is quite easy as follows:
self.navigationController?.navigationBarHidden = true
But the problem is that I don't know where to put the code.
I am thinking to intercept the zoom event of WKWebView. May be there are other ways, any comments are welcome.
Every WKWebView has a scrollView property which allows you to access the UIScrollView part of the the web view. You can use the UIScrollViewDelegate method, scrollViewDidScroll to get callbacks on when the web view scrolls.
First, set the scroll view delegate:
let webView = WKWebView(...)
webView.scrollView.delegate = self
Then, implement the delegate method scrollViewDidScroll and add the logic to hide and show the navigation bar:
extension YourClass: UIScrollViewDelegate {
func scrollViewDidScroll(scrollView: UIScrollView) {
// you can use the position of the scrollView to show and hide your nav bar here
}
}
I found another way to achieve it:
self.navigationController?.hidesBarsOnSwipe = true
iOS 8.0 gives UINavigationController a simple property that masks some complex behavior. If you set hidesBarsOnSwipe to be true for any UINavigationController, then iOS automatically adds a tap gesture recognizer to your view to handle hiding (and showing) the navigation bar as needed. This means you can mimic Safari's navigation bar behavior in just one line of code.
I am trying something and don't know if I am on a right track.
I have a UITableViewController added to ViewController. My table have multiple sections and I would like my table to be empty till the UISearchBar is inactive. Which I have already accomplished.
I would like to add multiple images to the blank screen in the bottom till the search bar is active, so the screen is not blank.
How do I add images to this screen till I click the search bar and hide the images once I click the search bar and populate the table.
Add imagesViews to your view controller's view. Set your search bar's delegate to your view controller subclass. Then say something like:
func searchBarTextDidBeginEditing(searchBar: UISearchBar){
self.imageView.hidden = true
}
And
func searchBarTextDidEndEditing(searchBar: UISearchBar){
if searchBar.text.length() == 0{
self.imageView.hidden = false
}
}
I'm completely stumped by this. I've been working on a project that has both a landscape view and portrait view. I segue from one view controller to another, and the 2nd view controller has a UIView that allows custom drawing. However, when I'm in landscape mode (and only when in landscape mode), I'm unable to draw in the view (with touches... functions) because when I'm in the left half of the view and I drag towards the left side of the screen, I get taken back to the previous view controller.
The view controllers are embedded in a navigation controller, so I'm not sure if this is some built-in segue that the navigation controller creates to send me back or something, but other than that there's nothing I can think of that'd be causing this.
Any idea what may be causing this? I've already checked the UIView itself and there are no gesture recognizers associated with it, so I don't know where it'd be hiding.
if ([self.navigationController respondsToSelector:#selector(interactivePopGestureRecognizer)]) {
self.navigationController.interactivePopGestureRecognizer.enabled = NO;
}
Add this to you viewDidLoad function of your second view controller.
iOS 7 and above has a feature to go back to previous view controller when swipe from the left end
UPDATE
self.navigationController.interactivePopGestureRecognizer.delegate = self
func gestureRecognizerShouldBegin(gestureRecognizer: UIGestureRecognizer!) -> Bool {
return false;
}