PanGesture Recognizer not working. [Swift] - swift

I would like to go back to the previous view by using Pangesture (drag view) but I can’t. I can do function “pan” only on the left edge of the screen, let’s say 5%. The other area of current view the Pangesture function is not working. Is there any way that I can go back to the root view with Pangesture? Please advise. Thank you.
var pan = UIPanGestureRecognizer(target: self, action: "handlePanGesture:")
self.mainView.addGestureRecognizer(pan)
func handlePanGesture(recognizer: UIPanGestureRecognizer) {
var touchLocation = recognizer.translationInView(self.view)
????
}

Here's an example of a view controller that uses a UIPanGestureRecognizer setup on the storyboard:
(Just one inspector shown for example purposes)
ViewController:
class PhotoDetaislViewController: UIViewController {
// the connection
#IBOutlet var swipeRight: UISwipeGestureRecognizer!
override func viewDidLoad() {
super.viewDidLoad()
//Swipe navigation
swipeRight.addTarget(self, action: "swipeRight:") // sets up the swipeRight var
}
func swipeRight(sender: UISwipeGestureRecognizer) {
// do your navigation here
}
}

Related

adding a pan gesture to a subview of a UIView called from a UIViewController

I created a custom view with a subview where its frame origin x is set to the width of the parent view so that it looks like a tab sticking out of the view. (like a tab folder). The custom view is an IBOutlet in a view controller. My objective is to drag the tab to pull out the custom view like opening a panel. When I add the Pan gesture to the dragging tab, the subview, nothing happens. It works when I add it directly to the parent view. Any help would be awesome.
let pan = UIPanGestureRecognizer(target: self, action: #selector(dragView(pan:)))
pan.minimumNumberOfTouches = 1
pan.delegate = self
notesView.dragView.addGestureRecognizer(pan)
neither the func nor the delegate methods are triggered.
//MARK: - Don't forget to add UIGestureRecognizerDelegate, when you add delegate to gestureRecognizer
class ViewController: UIViewController, UIGestureRecognizerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
//MARK: set panGestureRecognizer
let panGestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(panGestureRecognizerTapped))
panGestureRecognizer.minimumNumberOfTouches = 1
//MARK: set panGestureRecognizer delegate
panGestureRecognizer.delegate = self
//MARK: Set panGestureRecognizer to view
view.addGestureRecognizer(panGestureRecognizer)
//MARK: - Add user interaction to you custom view or view
view.isUserInteractionEnabled = true
}
//MARK: when tap is happened the below attribute will be executed
#objc func panGestureRecognizerTapped() {
print("Pan Gesture Recognizer Tapped")
}
}
//The resource code is at the below link:
https://github.com/ahmetbostanciklioglu/PanGestureRecognizer.git

How to use a button created in XIB custom view to control setContentOffset in viewController.swift?

I followed this tutorial to create a Snapchat-Like Menu: https://www.youtube.com/watch?v=1_daE3IL_1s
In short, the idea was to create custom views with XIB, and add them into a scrollview.
I would like to add a "back" button to one of the custom views so that the scrollview will automatically scroll back to its initial view when the button is tapped. The Idea I had was to write a code inside the custom view's IBAction function to call UIScrollview's content offset delegate function.
the following is the code in View Controller:
class ViewController: UIViewController, UIScrollViewDelegate {
//I'm naming the Scroll View as "scrollView"
#IBOutlet weak var scrollView: UIScrollView! {
didSet{
scrollView.delegate = self
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
var v1 : View1 = View1(nibName: "View1", bundle: nil)
var v2 : View2 = View2(nibName: "View2", bundle: nil)
self.addChild(v1)
self.scrollView.addSubview(v1.view)
v1.didMove(toParent: self)
self.addChild(v2)
self.scrollView.addSubview(v2.view)
v1.didMove(toParent: self)
var v2Frame : CGRect = v2.view.frame
v2Frame.origin.x = self.view.frame.width
v2.view.frame = v2Frame
self.scrollView.contentSize = CGSize(width: self.view.frame.width * 2, height: self.view.frame.height)
// self.scrollView.contentSize = CGSize(self.view.frame.width * 2, self.view.frame.size.height)
}
}
The following ht the code in View2:
class View2: UIViewController {
#IBOutlet weak var buttonHome: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func buttonHomeAction(_ sender: Any) {
//how to access scrollview.setContentOffset from ViewController to scroll the view back to the first view?
}
So my question is how to access scrollview.setContentOffset from ViewController to scroll the view back to the first view? Am I on the right track? Or are there any alternative methods where I can tap a button and scroll the view back to its first page?
Thank you!
I can think of two good options here:
1) Hold a weak reference in View2 of the scrollView. in View2 add:
weak var scrollView: UIScrollView?
and in ViewController, after view2 creation add:
view2.scrollView = self.scrollView
now, in buttonHomeAction you'll have access to the scrollView.
2) If you are familiar with Apple's delegation pattern, you can add a delegate, which can be a weak reference of the presenting view controller.
Create a protocol for the delegate, using named by the view holds the delegate. so, in this case: View2Delegate
and add a method that describes the action.
protocol View2Delegate: AnyObject {
func buttonTapped()
}
so, in View2 add:
weak var delegate: View2Delegate?
and in ViewController, after view2 creation add:
view2.delegate = self
now, in ViewController implement the protocol method and access scrollView:
extension ViewController: View2Delegate {
func buttonTapped() {
// access scrollView as self.scrollView
}
}

Dismissing side menu by tapping anywhere

I created a side menu using a container view. It slides in the main view each time i press a menu.
You can find my project here:
https://github.com/marybnq/side-menu
I need to dismiss it by tapping anywhere in the mainVC.
How do I do it?
Try this:
class FirstViewController: UIViewController {
#IBOutlet weak var menuConstraint: NSLayoutConstraint!
var sideMenuOpen = false
var gesture : UITapGestureRecognizer?
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self,
selector: #selector(toggleSideMenu), name: NSNotification.Name("ToggleSideMenu"), object: nil)
gesture = UITapGestureRecognizer(target: self, action: #selector(FirstViewController.toggleSideMenu))
}
#objc func toggleSideMenu() {
if sideMenuOpen {
sideMenuOpen = false
menuConstraint.constant = -240
self.view.removeGestureRecognizer(gesture!)
} else {
sideMenuOpen = true
menuConstraint.constant = 0
self.view.addGestureRecognizer(gesture!)
}
}
}
Simple:
1. Add tap gesture to view of mainVC and disable it by default
2. Enable tap gesture on showing side menu, to handle taps
3. Disable tap gesture on hiding side menu

Swift: Re-activating Tap Gesture on Disclosure Indicators

I have a Swift project that has a Table View Controller with multiple Static Cell Sections. Some cells have UITextFields and others have Accessory: Disclosure Indicators. I’ve implemented the following Swift code to dismiss the keyboard when the background is tapped:
override func viewDidLoad() {
super.viewDidLoad()
let tapGesture = UITapGestureRecognizer(target: self, action: Selector("hideKeyboard"))
tapGesture.cancelsTouchesInView = true
tableView.addGestureRecognizer(tapGesture)
}
func hideKeyboard() {
tableView.endEditing(true)
}
This works great for releasing the keyboard on tapping the background, but it also removed the tap gesture for the Disclosure Indicators (swipe still works). Does anyone know how to re-activate the tap gesture for the Disclosure Indicators cells after implementing this hideKeyboard() function?
Keep a reference to the gesture recognizer and remove it from the view when you hide the keyboard.
class YourController: UITableViewController {
let tapGesture: UITapGestureRecognizer = {
let tg = UITapGestureRecognizer(target: self, action: "hideKeyboard")
tg.cancelsTouchesInView = true
return tg
}()
override func viewDidLoad() {
super.viewDidLoad()
tableView.addGestureRecognizer(tapGesture)
}
func hideKeyboard() {
tableView.endEditing(true)
tableView.removeGestureRecognizer(tapGesture)
}
}

Displaying a UIAlertView adjacent to button pressed to call

I'm trying to figure out if theres a way to tie the location a programatically created UIAlertView is displayed on screen to the location of the button pressed to activate it.
I would like to have my alert view display directly below my button.
Thanks to gutenmorgenuhu for setting me on the right direction I was able to create a UIPopover that locates its self to the button pressed.
I first created a new UIViewController with the content of my popover (a UIPickerView in this case), that view is given the storyboard name Popover.
Then in my original view I created 2 buttons, topButton and bottomButton and linked them to their respective actions and outlets.
My code follows:
import UIKit
class ViewController: UIViewController, UIPopoverControllerDelegate, UIPopoverPresentationControllerDelegate {
//declare variables
var popOverLocation: CGRect!
// Set outlets for all buttons
#IBOutlet weak var topButton: UIButton!
#IBOutlet weak var bottomButton: UIButton!
//Add actions to buttons, first trigger popOverLocation to take the frame properties of the active button, then call the popover function.
#IBAction func topButton(sender: AnyObject) {
popOverLocation = topButton.frame
popOver()
}
#IBAction func bottomButton(sender: AnyObject) {
popOverLocation = bottomButton.frame
popOver()
}
//function for creating the popover
func popOver() {
//Read the height, and XY coordinates of the active button
var h = popOverLocation.height
var x = popOverLocation.origin.x
var y = popOverLocation.origin.y + h
//create the popover
var popoverContent = self.storyboard!.instantiateViewControllerWithIdentifier("Popover") as UIViewController
var nav = UINavigationController(rootViewController: popoverContent)
nav.modalPresentationStyle = UIModalPresentationStyle.Popover
var popover = nav.popoverPresentationController! as UIPopoverPresentationController
popover.sourceView = self.view
popover.delegate = self
//set the size of the popover
popoverContent.preferredContentSize = CGSizeMake(200,300);
//set the direction the popover arrow is allowed to point
popover.permittedArrowDirections = UIPopoverArrowDirection.Up
//using the buttons coordinates set the location of the popover
popover.sourceRect = CGRectMake(x,y,0,0)
self.presentViewController(nav, animated: true, completion: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}