I am having trouble my UIPageViewController. What I ve done sofar:
1. On pageViewController you can swipe left, right in order to change VC
2. added lateral menu. When adding lateral menu, I created pangesture recognizer and added it to pageContentVC (so I can drag pageContentVC in order to close sidebar menu)
var menuViewController: UIViewController! {
didSet {
self.exitPanGesture = UIPanGestureRecognizer()
self.exitPanGesture.addTarget(self, action:"handleOffstagePan:")
// self.exitPanGesture.view?.userInteractionEnabled = false
self.sourceViewController.view.addGestureRecognizer(self.exitPanGesture)
}
}
Here I am setting pageContentVC to sourceVC of transitionManager:
func resetToMainPage(index: Int!) {
/* Getting the page View controller */
mainPageViewController = self.storyboard?.instantiateViewControllerWithIdentifier("MainPageViewController") as UIPageViewController
self.mainPageViewController.dataSource = self
self.mainPageViewController.delegate = self
let pageContentViewController = self.viewControllerAtIndex(index)
self.transtionManger.sourceViewController = pageContentViewController // adding swipe to the pageContentViewControlle in order to close menu
self.mainPageViewController.setViewControllers([pageContentViewController!], direction: UIPageViewControllerNavigationDirection.Forward, animated: true, completion: nil)
self.mainPageViewController.view.frame = CGRectMake(0, 102, self.view.frame.width, self.view.frame.height)
self.addChildViewController(mainPageViewController)
self.view.addSubview(mainPageViewController.view)
self.mainPageViewController.didMoveToParentViewController(self)
}
After closing menu I disabled pangesture recognizer.
` var presentingP:Bool!{
didSet{
if presentingP == true {
// enable the gesture recognizer only when the view of menucontroller is presented
self.exitPanGesture.view?.userInteractionEnabled = true
}else{
// disable gesture recognizer when menu is not presented
self.exitPanGesture.view?.userInteractionEnabled = false
isMenuVisible = false
}
}
}
` Sofar, I can swipe left, and right in order to change VC.
The problem is that I can't scroll tableView on my VC. After I disabled pageContentVC gesture, everything become disable except swiping right and left (to change VC). Question: How to keep two gestureRecognizers in one view and switch between them?
You can use the enabled property of UIGestureRecognizer to disable the one you don't want to use and enable the other one.
UIGestureRecognizer documentation
Related
I have a MasterViewController and I am adding a ChildViewController inside a MasterViewController. Inside MasterViewController I have made top button bar , and took a view as a Container view. In this container view I want to move my ChildViewControllers. And This will happen on button click in MasterViewController
This is how I am adding the ChildViewController
func addViewControllerAsChildViewController(childVC : UIViewController) {
oldVC = newVC
childVC.view.frame = viewContainer.bounds
childVC.view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
addChildViewController(childVC)
childVC.didMove(toParentViewController: self)
// Where ViewContainer is dedicated area inside the MasterViewController
viewContainer.addSubview(childVC.view)
}
And these are my button clicks
#IBAction func onClickBtnNewList(_ sender: UIButton) {
if !(newVC is NewListVC) {
initNewListVC()
addViewControllerAsChildViewController(childVC: targetViewController)
}
UIView.animate(withDuration: 4000, animations: {
self.viewIndicators.frame = sender.frame.offsetBy(dx:0,dy:2)
})
}
#IBAction func onClickBtnSavedList(_ sender: UIButton) {
if !(newVC is SavedListVC) {
initSavedListVC()
addViewControllerAsChildViewController(childVC: targetViewController)
}
UIView.animate(withDuration:400, animations: {
self.viewIndicators.frame = sender.frame.offsetBy(dx:0,dy:2)
})
}
My ChildViewControllers gets inflated correctly. But Problem is on button Click there is a another view, which I am animating on click and moving it below the button. You can see I have used the following code in button click. The animation start and ended moving my related view to its starting position. and its not moving to my expected area see code below
UIView.animate(withDuration: 4000, animations: {
self.viewIndicators.frame = sender.frame.offsetBy(dx:0,dy:2)
})
but this is not working. But If I comment out following lines that are attaching ChildViewController , The animation do move smoothly and View moves to the target area
/*
if !(newVC is NewListVC) {
initNewListVC()
hideOrShowViewController(targetViewController: newVC!)
}
*/
Now do you have any idea why it is happening ?? what could be problem?
I am using Xcode 9 and swift 4 Please help
I have a ViewController (LandingViewController) and one drawerViewController.
I am using SWRevealViewController and I added a gesture to Landing view but when it will open the DrawerViewController then it is covering status bar only once. I don't know why this is happening, But it is hiding once and after that working fine.
I am not using NavigationBar and I have a map view in my LandingViewController.
I have drawer button in my LandingViewController.
If I will open or reveal the view by button it's working fine. But if I will open it by view it is hiding status bar.
Here below is my code :-
btnDrawerMenu.addTarget(self.revealViewController(), action: #selector(SWRevealViewController.revealToggle(_:)), for: UIControlEvents.touchUpInside).
//Reveal View Drawer menu
fileprivate func createReveal() {
if self.revealViewController() != nil {
self.revealViewController().rearViewRevealWidth = self.view.frame.width - 20
self.revealViewController().rearViewRevealOverdraw = 0.0
self.revealViewController().bounceBackOnOverdraw = false
self.revealViewController().bounceBackOnLeftOverdraw = false
self.revealViewController().toggleAnimationType = .easeOut
}
}
I have in my Swift 3 application a homeViewController containing a UITableView. When a cell of the table is clicked, then I display a detailViewController. I display it as a child using the addChildViewController(vc). I want to implement the back gesture in order to return to the homeViewController. I want to have the same result as the back mode in the default Mail application of the devices (the back mode to return to the mail's home when I was in the inbox for example). In other words, the gesture allows the user to drag the view from left to right then continuing the left to right drag until the home view is showed, or drag the view from right to left in order to keep the detail view in the whole screen. I tried to do that using the UIPanGestureRecognizer but my view goes left and right and sometimes its show the home view from the right side. So in brief, the result that I want is the same as the back gesture functionality of the Mail application.
This is my code:
var rightSwipe: UIPanGestureRecognizer = UIPanGestureRecognizer()
self.rightSwipe = UIPanGestureRecognizer(target: self, action: #selector(self.handleSwipes(_:)))
self.view.addGestureRecognizer(rightSwipe)
func handleSwipes(_ sender: UIPanGestureRecognizer){
if self.rightSwipe.state == .began || self.rightSwipe.state == .changed {
let translation = rightSwipe.translation(in: self.view)
// note: 'view' is optional and need to be unwrapped
//print("translation is : \(translation)")
if(translation.x > 0 && translation.y == 0.0){
self.rightSwipe.view!.center = CGPoint(x: self.rightSwipe.view!.center.x + translation.x, y: self.rightSwipe.view!.center.y + translation.y)
rightSwipe.setTranslation(CGPoint.zero, in: self.view)
}
}
}
To use NavigationController in your storyboard embeded your HomeViewController with UINavigationController. To embed navigationController select your HomeViewController, in menu choose Editor > Embed In > Navigation Controller.
Now in didSelectRowAt indexPath push the detailViewController.
self.navigationController?.pushViewController(detailVC, animated: true)
If still gesture is not work then in HomeViewController's viewDidLoad set this one.
self.navigationController?.interactivePopGestureRecognizer.isEnabled = true
Because I want to redesign the tab bar UI, I wrote a custom tab bar controller according to https://github.com/codepath/ios_guides/wiki/Creating-a-Custom-Tab-Bar
In TabBarViewController's viewDidLoad(), define several subviews corresponding to each tab bar
homeViewController = storyboard.instantiateViewControllerWithIdentifier("HomeViewController")
...
viewControllers = [homeViewController, searchViewController, accountViewController, trendingViewController]
and the main method when tapping tab
#IBAction func didPressTab(_ sender: UIButton) {
let previousIndex = selectedIndex
selectedIndex = sender.tag
tabButtons[previousIndex!].isSelected = false
let previousVC = viewControllers[previousIndex!]
// remove previous VC
previousVC.willMove(toParentViewController: nil)
previousVC.view.removeFromSuperview()
previousVC.removeFromParentViewController()
// set current VC
sender.isSelected = true
let vc = viewControllers[selectedIndex]
addChildViewController(vc)
// Adjust the size to match content view
vc.view.frame = contentView.bounds
contentView.addSubview(vc.view)
vc.didMove(toParentViewController: self)
}
I could set a default tab bar index selectedIndex when the tab bar view is loaded. However, how can I switch to next tab bar in homeViewController (without tapping tab bar buttons)?
This doesn't work in homeViewController
TabBarViewController().tabButtons[2].isSelected = true TabBarViewController().didPressTab(TabBarViewController().tabButtons[2])
I'm not sure how to get the running tab controller, set the selectedIndex, and update subview in the subview controllers.
All you need to do is to call tabBar.setSelectedViewController: and pass the view controller.
If you only know the tab index, you call tabBar.viewControllers[index] and get the view controller.
I finally use Delegate to solve.
In SubViewController add protocol
protocol SubViewControllerDelegate {
func transferToView(index: Int)
}
and declare this in the class
var delegate: SubViewControllerDelegate?
In TabBarViewController set to conform SubViewControllerDelegate
Implement the method
func transferToView(index: Int) {
tabButtons[index].isSelected = true
didPressTab(tabButtons[index])
}
Set delegate
subViewController = storyboard.instantiateViewControllerWithIdentifier("HomeViewController")
let subVC = subViewController as! SubViewController
subVC.delegate = self
I am making app like in Euro Sport. My rootviewController is pageViewController which has 3 VCs. Swiping left and right you can change the VC. Next, I added sidebarmenu. I want to add gesture recognizer to the whole rootViewController. This is how I am adding gesture:
self.exitPanGesture = UIPanGestureRecognizer()
self.exitPanGesture.addTarget(self, action:"handleOffstagePan:")
self.sourceViewController.view.addGestureRecognizer(self.exitPanGesture)
self.sourceViewController.navigationController?.view.addGestureRecognizer(self.exitPanGesture)
When I drag rootviewController tapping on navigation bar it works. But the other parts like segmentcontrol, and pageContent doesnt work.
I am setting sourceViewController here:
func resetToMainPage(index: Int!) {
/* Getting the page View controller */
mainPageViewController = self.storyboard?.instantiateViewControllerWithIdentifier("MainPageViewController") as UIPageViewController
self.mainPageViewController.dataSource = self
self.mainPageViewController.delegate = self
pageContentViewController = self.viewControllerAtIndex(index)
// self.transtionManger.sourceViewController = pageContentViewController // adding swipe to the pageContentViewControlle in order to close menu
self.transtionManger.sourceViewController = mainPageViewController
self.mainPageViewController.setViewControllers([pageContentViewController!], direction: UIPageViewControllerNavigationDirection.Forward, animated: true, completion: nil)
self.mainPageViewController.view.frame = CGRectMake(0, 102, self.view.frame.width, self.view.frame.height)
self.addChildViewController(mainPageViewController)
self.view.addSubview(mainPageViewController.view)
self.mainPageViewController.didMoveToParentViewController(self)
}
So, My question is how to add gesture recognizer to the whole rootViewController, including navbar, segmentcontrol, pageviewcontrol?
A gesture recognizer can only be attached to one view. So the lines below mean that only navigationController?.view is getting the gesture added.
self.sourceViewController.view.addGestureRecognizer(self.exitPanGesture)
self.sourceViewController.navigationController?.view.addGestureRecognizer(self.exitPanGesture)
You can just duplicate the gesture recognizer for each view you want to have it on and then add them all that way.
self.exitPanGesture1 = UIPanGestureRecognizer()
self.exitPanGesture1.addTarget(self, action:"handleOffstagePan:")
self.sourceViewController.view.addGestureRecognizer(self.exitPanGesture1)
self.exitPanGesture2 = UIPanGestureRecognizer()
self.exitPanGesture2.addTarget(self, action:"handleOffstagePan:")
self.sourceViewController.navigationController?.view.addGestureRecognizer(self.exitPanGesture2)
guys, I solved my problem but I got another one. In my case , I created exitGestureRecognizer. I wanted to add this to whole viewcontroller views. So, here is my code:
for singleView in self.sourceViewController.view.subviews {
singleView.addGestureRecognizer(exitPanGesture)
singleView.navigationController??.view.addGestureRecognizer(exitPanGesture)
}
For some reason, recognizer on navBar.view doesnt work. If I write code in this way:
for singleView in self.sourceViewController.view.subviews {
singleView.addGestureRecognizer(exitPanGesture)
singleView.navigationController??.view.addGestureRecognizer(exitPanGesture)
}
self.sourceViewController.navigationController?.view.addGestureRecognizer(self.exitPanGesture)
Only nav bar gestures work and subview gestures dont work. If I change the order of this code. Nav bar gestures dont work but subviews gestures work. How can I add gestures to both views?