On Facebook Messenger for iOS, it has it so if the keyboard is hidden, if you swipe up, the keyboard will show. It does this exactly in reverse to the interactive keyboard dismissal mode: the keyboard reveals itself as you swipe up at the speed in which you swipe up.
Does anybody have any pointers on how to do this?
Edit: thanks for the answers! I was mostly looking into whether there was a built-in way to do this, since I saw it being done in Facebook Messenger. However, I just read a blog post where they said they had to screenshot the system keyboard to get the effect—so I’ll assume there’s no built-in way to do this! As mentioned in the comments, I’m using a custom keyboard, so this should be a lot easier, since I have control over the frame!
Basically you'll need UIPanGestureRecognizer.
Set UIScreenEdgePanGestureRecognizer for bottom edge, UIPanGestureRecognizer for hiding the keyboard in Storyboard and drag #IBAction outlets to the code.
Set you keyboard view container with your keyboard in the bottom of the controller in Storyboard, so that user doesn't see it. Drag an #IBOutlet to your code so that you'll be able to modify it's frame.
In gesture actions when dragging your animate the view movement.
When stopped dragging you need to check the view's position and animate it to the destination if it's not there yet.
Also you'll need to add a check for the dragging area so that user cannot drag it further.
It's simple, you'll just need to check all cases and test it properly.
This is a basic setup you can build from this:
class ViewController: UIViewController {
#IBOutlet weak var keyboardContainerView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func onEdgePanGestureDrag(_ sender: UIScreenEdgePanGestureRecognizer) {
let point = sender.location(in: view)
view.layoutIfNeeded()
UIView.animate(withDuration: 0.33) {
// Animate your custom keyboard view's position
self.keyboardContainerView.frame = CGRect(x: self.keyboardContainerView.bounds.origin.x,
y: point.y,
width: self.keyboardContainerView.bounds.width,
height: self.keyboardContainerView.bounds.height)
}
view.layoutIfNeeded()
}
#IBAction func onPanGestureDrag(_ sender: UIPanGestureRecognizer) {
let point = sender.location(in: view)
view.layoutIfNeeded()
UIView.animate(withDuration: 0.33) {
// Animate your custom keyboard view's position
self.keyboardContainerView.frame = CGRect(x: self.keyboardContainerView.bounds.origin.x,
y: point.y,
width: self.keyboardContainerView.bounds.width,
height: self.keyboardContainerView.bounds.height)
}
view.layoutIfNeeded()
}
}
Here is an implementation that worked for me. It's not perfect but it works fairly well and is simple to implement.You will need a collection view or a table view.
For the sake of simplicity I will only show code that is necessary for this feature. so please handle everything else that is necessary for the views' initialization.
class ViewController: UIViewController {
var collectionView: UICollectionView!
var textView: UITextView!
override func viewDidLoad() {
super.viewDidLoad()
collectionView.panGestureRecognizer.addTarget(self, action: #selector(handlePan(_:)))
collectionView.keyboardDismissMode = .interactive
// Only necessary for empty collectionView
collectionView.alwaysBounceVertical = true
}
func handlePan(_ sender: UIPanGestureRecognizer) {
if sender.state == .changed {
let translation = sender.translation(in: view)
if translation.y < 0 && collectionView.isAtBottom && !self.textView.isFirstResponder() {
self.textView.becomeFirstResponder()
}
}
}
}
extension UIScrollView {
var isAtBottom: Bool {
return contentOffset.y >= verticalOffsetForBottom
}
var verticalOffsetForBottom: CGFloat {
let scrollViewHeight = bounds.height
let scrollContentSizeHeight = contentSize.height
let bottomInset = contentInset.bottom
let scrollViewBottomOffset = scrollContentSizeHeight + bottomInset - scrollViewHeight
return scrollViewBottomOffset
}
}
Related
I want to be able to move an instance of UIImageView from a UIScrollView to a UIView that is outside the containing UIScrollView.
I've got the panGesture working but a UIImageView shows only inside the containing UIScrollView when being dragged and gets hidden if going outside the containing UIScrollView as shown in the screenshot image.
I've tried something like someScrollView.sendSubview(toBack: self.view) to set the layer order and also imageView.layer.zIndex = .. but it doesn't seem to work in my case.
How do I achieve something as shown in the screenshot image so it can be dragged to a target UIView outside its containing view?
And also if possible, how can I create a new instance of UIImageView as the panGesture begins so the original images stay.
#IBOutlet weak var someScrollView: UIScrollView!
var letters: [String] = ["g","n","d"]
override func viewDidLoad() {
super.viewDidLoad()
someScrollView.addSubview(createLetters(letters))
someScrollView.sendSubview(toBack: self.view)
}
func createLetters(_ named: String]) -> [UIImageView] {
return named.map { name in
let letterImage = UIImageView()
letterImage.image = UIImage(named: "\(name)")
addPanGesture(image: letterImage)
return letterImage
}
}
func addPanGesture(image: UIImageView) {
let pan = UIPanGestureRecognizer(target: self, action: #selector(ViewController.handlePan(sender:)))
image.addGestureRecognizer(pan)
}
#objc func handlePan(sender: UIPanGestureRecognizer) {
let translation = sender.translation(in: view)
if let imageView = sender.view {
imageView.center = CGPoint(x:imageView.center.x + translation.x,
y:imageView.center.y + translation.y)
}
sender.setTranslation(CGPoint.zero, in: self.view)
switch sender.state {
case .began:
...
}
}
First off, it's good practice to prioritize gesture recognizers - tell the scroll view's pan gesture that it won't receive touches on account of your pan gestures (Yours comes first).
someScrollView.panGestureRecognizer.require(toFail: yourGestureRecognizer)
Unclip scroll-view's subviews to it's bounds - It's subviews will be visible when dragged outside the scrollView's bounds.
scrollView.clipsToBounds = false
You can convert the frame of your dragged view to the scrollView and newParentView ancestor's coord' system, like this (assuming self.view is scrollView & newParentView's ancestor).
let pannedViewFrame = someScrollView.convert(pannedView, to: self.view)
Then, in your gesture recognizer's selector, you can test frame intersection of pannedViewFrame and newParentView.frame, like this:
// You have an frame intersection
if pannedViewFrame.intersects(newParentView.frame) {
}
Now, if you test intersection of frames when your gesture recognizer's state is .cancelled, .ended or .failed, then:
The panning has ended AND pannedView is within newParentView's bounds
Last step, just convert pannedViewFrame to newParentView.frame's coord' using the same trick and added pannedView as subview to newParentView.
Another solution is to remove the pannedView from scrollView when GR state is .began and add it to scrollView and newParentView's common ancestor. The rest is the same as i previously mentioned.
I have a label in my view controller. I am trying to move the position of the label 50 points to the left every time I tap the label. This is what I have so far but my label won't move in the simulation. I do have constraints on the label. It is about 100 wide and 50 in height, and it is also centered in the view controller.
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let tapGesture = UITapGestureRecognizer(target: gestureLabel, action: #selector(moveLabel))
gestureLabel.addGestureRecognizer(tapGesture)
}
func moveLabel(){
if(left){
moveLeft()
}
else{
moveRight()
}
}
func moveLeft(){
let originalX = gestureLabel.frame.origin.x
if(originalX < 0){
bringIntoFrame()
}
else{
gestureLabel.frame.offsetBy(dx: -50, dy: 0)
}
}
here You can move label where ever You want it
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
if let touch = touches.first {
let position = touch.location(in: self.view)
print(position.x)
print(position.y)
lbl.frame.origin = CGPoint(x:position.x-60,y:position.y-50)
}
}
UILabel's userInteractionEnabled is false by default. Try setting it to true
You should be changing the constraint of the label, not the label itself.
Also, your target should be self, not gestureLabel.
Plus, you could animate that. :)
Like so:
class ViewController: UIViewController {
// Centers the Meme horizontally.
#IBOutlet weak var centerHorizontalConstraint: NSLayoutConstraint!
// A custom UIView.
#IBOutlet weak var okayMeme: OkayMeme!
override func viewDidLoad() {
super.viewDidLoad()
addGestureRecognizer()
}
func addGestureRecognizer() {
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(moveMeme))
okayMeme.addGestureRecognizer(tapGesture)
}
func moveMeme() {
UIView.animate(withDuration: 2.0) {
self.centerHorizontalConstraint.constant -= 50
self.view.layoutIfNeeded()
}
}
}
"Demo":
You made a new frame, but didn't assign it to the label. offsetBy doesn't change the frame in place. It creates a new one.
Replace
gestureLabel.frame.offsetBy(dx: -50, dy: 0)
with
gestureLabel.frame = gestureLabel.frame.offsetBy(dx: -50, dy: 0)
But the method above assumes, that you're using directly, not constraints. A standard approach is to have a "Leading to Superview" constraint and change its constant instead of changing the frame.
The label wont move because it has constraints. The easiest way to do this is next:
1) create a label programatically (so you can move it freely around)
var labelDinamic = UILabel(frame: CGRectMake(0, 0,200, 200));
labelDinamic.text = "test text";
self.view.addSubview(labelDinamic);
2) set label initial position (i suggest to use the position of your current label that has constraints. also, hide you constraint label, because you dont need it to be displayed)
labelDinamic.frame.origin.x = yourLabelWithConstraints.frame.origin.x;
labelDinamic.frame.origin.y = yourLabelWithConstraints.frame.origin.y;
3) now you move your label where ever You want with the property
labelDinamic.frame.origin.x = 123
labelDinamic.frame.origin.y = 200
I have attached an image here
I am a newbie to iOS development. My question is as follows:
I want to swipe my scrollView outside of its width using gesture control.
To be precise I want my UIScrollView to scroll when swipe is performed in the subview (there is only one subview).
I have gone through several StackOverflow question but I couldn't quite get a correct answer.
Your help is much appreciated!
class ViewController: UIViewController, UIGestureRecognizerDelegate {
#IBOutlet weak var scrollView: UIScrollView!
var images = [UIImageView]()
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewDidAppear(_ animated: Bool) {
var contentWidth: CGFloat = 0.0
for x in 0...2 {
let image = UIImage(named: "icon\(x).png")
let imageView = UIImageView(image:image)
images.append(imageView)
var newX: CGFloat = 0.0
newX = scrollView.frame.size.width/2 + scrollView.frame.size.width * CGFloat(x)
contentWidth += newX
scrollView.addSubview(imageView)
imageView.frame = CGRect(x: newX - 75, y: (scrollView.frame.size.height/2) - 75, width: 150, height: 150)
}
scrollView.clipsToBounds = false
scrollView.contentSize = CGSize(width: contentWidth, height: view.frame.size.height)
}
As you can see in the image the width of my UIScrollView has a grey background color (I did that to illustrate my point). Now I want to also scroll the scroll view when a user swipes in the subview (non-grey) UIImageView.
I have added the following function and made a return of yes to enable both views to recognize gestures simultaneously. But, I am not getting the desired result. Can anyone take a look?
func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
Place view.addGestureRecognizer(scrollView.panGestureRecognizer) in viewDidLoad function.
What it eventually does is it assigns scrollview's gesture recognizer to look for gestures in main view. So it automatically move content of scrollview even when gestures are outside of the scrollview rect.
you can forward touch events in that subview to scrollview. see this answer
I am trying to get something like this to work. This is the Uber App. Where a user can swipe another view up, in front of a background view.
The background view is fairly simple, it has been done already. The view which will be swiped on top will be a UITableView. I want the user to be able to see just a little top part first when the app launches, then upon swiping a little it should stop in the middle and then after fully swiping up should take it all the way to the top, replacing the Background view.
Frameworks I have looked at are pullable view for iOS. But it is way too old and doesn't get any nice animations across. I have also looked at SWRevealViewController but I can't figure out how to swipe up from below.
I have also tried to use a button so when a user clicks on it, the table view controller appears modally, covering vertical, but that is not what I want. It needs to recognize a gesture.
Any help is greatly appreciated. Thanks.
I'm aware that the question is almost 2 and a half years old, but just in case someone finds this through a search engine:
I'd say that your best bet is to use UIViewPropertyAnimator. There's a great article about it here: http://www.swiftkickmobile.com/building-better-app-animations-swift-uiviewpropertyanimator/
EDIT:
I managed to get a simple prototype working with UIViewPropertyAnimator, here's a GIF of it:
Here's the project on Github: https://github.com/Luigi123/UIViewPropertyAnimatorExample
Basically I have two UIViewControllers, the main one called ViewController and the secondary one called BottomSheetViewController. The secondary view has an UIPanGestureRecognizer to make it draggable, and inside the recognizer's callback function I do 3 things (after actually moving it):
① calculate how much percent of the screen have been dragged,
② trigger the animations in the secondary view itself,
③ notify the main view about the drag action so it can trigger it's animations. In this case I use a Notification, passing the percentage inside notification.userInfo.
I'm not sure how to convey ①, so as an example if the screen is 500 pixels tall and the user dragged the secondary view up to the 100th pixel, I calculate that the user dragged it 20% of the way up. This percentage is exactly what I need to pass into the fractionComplete property inside the UIViewPropertyAnimator instances.
⚠️ One thing to note is that I couldn't make it work with an actual navigation bar, so I used a "normal" view with a label in it's place.
I tried making the code smaller by removing some utility functions like checking if the user interaction is finished, but that means that the user can stop dragging in the middle of the screen and the app wouldn't react at all, so I really suggest you see the entire code in the github repo. But the good news is that the entire code that executes the animations fits in about 100 lines of code.
With that in mind, here's the code for the main screen, ViewController:
import UIKit
import MapKit
import NotificationCenter
class ViewController: UIViewController {
#IBOutlet weak var someView: UIView!
#IBOutlet weak var blackView: UIView!
var animator: UIViewPropertyAnimator?
func createBottomView() {
guard let sub = storyboard!.instantiateViewController(withIdentifier: "BottomSheetViewController") as? BottomSheetViewController else { return }
self.addChild(sub)
self.view.addSubview(sub.view)
sub.didMove(toParent: self)
sub.view.frame = CGRect(x: 0, y: view.frame.maxY - 100, width: view.frame.width, height: view.frame.height)
}
func subViewGotPanned(_ percentage: Int) {
guard let propAnimator = animator else {
animator = UIViewPropertyAnimator(duration: 3, curve: .linear, animations: {
self.blackView.alpha = 1
self.someView.transform = CGAffineTransform(scaleX: 0.8, y: 0.8).concatenating(CGAffineTransform(translationX: 0, y: -20))
})
animator?.startAnimation()
animator?.pauseAnimation()
return
}
propAnimator.fractionComplete = CGFloat(percentage) / 100
}
func receiveNotification(_ notification: Notification) {
guard let percentage = notification.userInfo?["percentage"] as? Int else { return }
subViewGotPanned(percentage)
}
override func viewDidLoad() {
super.viewDidLoad()
createBottomView()
let name = NSNotification.Name(rawValue: "BottomViewMoved")
NotificationCenter.default.addObserver(forName: name, object: nil, queue: nil, using: receiveNotification(_:))
}
}
And the code for the secondary view (BottomSheetViewController):
import UIKit
import NotificationCenter
class BottomSheetViewController: UIViewController, UIGestureRecognizerDelegate {
#IBOutlet weak var navBarView: UIView!
var panGestureRecognizer: UIPanGestureRecognizer?
var animator: UIViewPropertyAnimator?
override func viewDidLoad() {
gotPanned(0)
super.viewDidLoad()
let gestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(respondToPanGesture))
view.addGestureRecognizer(gestureRecognizer)
gestureRecognizer.delegate = self
panGestureRecognizer = gestureRecognizer
}
func gotPanned(_ percentage: Int) {
if animator == nil {
animator = UIViewPropertyAnimator(duration: 1, curve: .linear, animations: {
let scaleTransform = CGAffineTransform(scaleX: 1, y: 5).concatenating(CGAffineTransform(translationX: 0, y: 240))
self.navBarView.transform = scaleTransform
self.navBarView.alpha = 0
})
animator?.isReversed = true
animator?.startAnimation()
animator?.pauseAnimation()
}
animator?.fractionComplete = CGFloat(percentage) / 100
}
// MARK: methods to make the view draggable
#objc func respondToPanGesture(recognizer: UIPanGestureRecognizer) {
let translation = recognizer.translation(in: self.view)
moveToY(self.view.frame.minY + translation.y)
recognizer.setTranslation(.zero, in: self.view)
}
private func moveToY(_ position: CGFloat) {
view.frame = CGRect(x: 0, y: position, width: view.frame.width, height: view.frame.height)
let maxHeight = view.frame.height - 100
let percentage = Int(100 - ((position * 100) / maxHeight))
gotPanned(percentage)
let name = NSNotification.Name(rawValue: "BottomViewMoved")
NotificationCenter.default.post(name: name, object: nil, userInfo: ["percentage": percentage])
}
}
EDIT: So, some time has passed and now there is a really awesome library called Pulley. It does exactly what I wanted it to do, and its a breeze to setup!
Original answer:
Thanks to both Rikh and Tj3n for giving me hints. I managed to do something very basic, it doesn't have nice animations like Uber but it gets the job done.
With the following code, you can swipe any UIViewController. I use a UIPanGestureRecognizer on my image, which will stay on top of the dragged view at all times. Basically, you use that image and it recognizes where it gets dragged, and it sets the view's frame according to the user's input.
First go to your storyboard and add an identifier for the UIViewController that will be dragged.
Then in the MainViewController, use the following code:
class MainViewController: UIViewController {
// This image will be dragged up or down.
#IBOutlet var imageView: UIImageView!
// Gesture recognizer, will be added to image below.
var swipedOnImage = UIPanGestureRecognizer()
// This is the view controller that will be dragged with the image. In my case it's a UITableViewController.
var vc = UIViewController()
override func viewDidLoad() {
super.viewDidLoad()
// I'm using a storyboard.
let sb = UIStoryboard(name: "Main", bundle: nil)
// I have identified the view inside my storyboard.
vc = sb.instantiateViewController(withIdentifier: "TableVC")
// These values can be played around with, depending on how much you want the view to show up when it starts.
vc.view.frame = CGRect(x: 0, y: self.view.frame.height, width: self.view.frame.width, height: -300)
self.addChildViewController(vc)
self.view.addSubview(vc.view)
vc.didMove(toParentViewController: self)
swipedOnImage = UIPanGestureRecognizer(target: self, action: #selector(self.swipedOnViewAction))
imageView.addGestureRecognizer(swipedOnImage)
imageView.isUserInteractionEnabled = true
}
// This function handles resizing of the tableview.
func swipedOnViewAction() {
let yLocationTouched = swipedOnImage.location(in: self.view).y
imageView.frame.origin.y = yLocationTouched
// These values can be played around with if required.
vc.view.frame = CGRect(x: 0, y: yLocationTouched, width: UIScreen.main.bounds.width, height: (UIScreen.main.bounds.height) - (yLocationTouched))
vc.view.frame.origin.y = yLocationTouched + 50
}
Final Product
Now, It is possible that my answer might not be the most efficient way of going at this, but I am new to iOS so this is the best I could come up with for the time being.
You can embed that table view inside a custom scroll view that will only handle touch when touch that table view part (override hittest), then drag it up (disable tableview scroll), till the upper part then disable scroll view and enable tableview scroll again
Or, you can just add the swipe gesture into your tableview and change it's frame along and disable swipe when it reach the top
Experiment with those and eventually you will achieve the effect you wanted
As Tj3n pointed out, you could use a UISwipeGesture to display the UITableView. So using constraints (instead of frames) heres how you could go about doing that:
Go to your UIViewController inside your Story board on which you wish to display the UITableView. Drag and drop the UITableView and add a leading, trailing and height to the UITableView. Now add a vertical constraint between the UIViewController and UITableView so that the UITableView appears below the UIViewController(Play around with this vertical value until you can display the top part of the UITableView to suit your need). Create outlets for the vertical spacing constraint and height constraint (in case you need to set a specific height that you can figure out at run time). On the swipe up just animatedly set the vertical constraint to be equal to the negative value of the height sort of like:
topSpaceToViewControllerConstraint.constant = -mainTableViewHeightConstraint.constant
UIView.animate(withDuration: 0.3) {
view.layoutIfNeeded()
};
Alternatively
If you want to be able to bring the UITableView up depending on the pan amount (i.e depending on how much the user has moved across the screen or how fast) you should use a UIPanGestureRecognizer instead and try and set frames instead of autoLayout for the UITableView (as I'm not a big fan of calling view.layoutIfNeeded repeatedly. I read somewhere that it is an expensive operation, would appreciate it if someone would confirm or correct this).
func handlePan(sender: UIPanGestureRecognizer) {
if sender.state == .Changed {
//update y origin value here based on the pan amount
}
}
Alternatively using UITableViewController
Doing what you wish to perform is also possible using a UITableViewController if you wish to but it involves a lot of faking and effort by creating a custom UINavigationControllerDelegate mainly to create a custom animation that will use UIPercentDrivenInteractiveTransition to pull the new UITableViewController up using a UIPanGestureRecognizer if you want it depending on the pan amount. Otherwise you can simply add a UISwipeGestureRecognizer to present the UITableViewController but you will still have to again create a custom animation to "fake" the effect you want.
I'm trying to implement functionality in my practice app very similar to that of Snapchat, where you drag a UITableViewCell to the right or left, and as you're dragging, an image behind the view is slowly appearing until it reaches a certain point, and after it does, it starts a segue or PageViewController type segue to another view controller that you can use to chat with your friend.
At first, I tried using the screen edge pan gesture recognizer, but that only works if you start swiping from the edge of the screen. I need to be able to swipe from anywhere within the UITableViewCell.
A demonstration of my needed functionality is in Snapchat, where you see it more clearly when you slowly swipe right on one of your friend's table cell's and it slowly shows the image of a messaging icon and eventually leads to another view where you can chat.
So would a pan gesture recognizer be enough for this? If so, what would be the best method to follow to get this done? I've seen tutorials on pan gesture recognizers but I don't see how it could eventually lead to another view controller after swiping a certain distance. I think I could get away with putting the messaging icon behind the displayed table cell content that could appear while swiping right, but how could I implement such smooth functionality?
Learning this would really increase my experience in smooth user experience. Any advice or methods would be greatly appreciated, thanks.
EDIT: Please leave answers in Objective C, please. I don't know Swift.
You can create a custom TableViewCell for this. Code below should do what you're asking. Just need to add the delegate to your ViewController
protocol TableViewCellDelegate {
func something()
}
class TableViewCell: UITableViewCell {
var startSegue = false
var label: UILabel // Or UIView, whatever you want to show
var delegate: TableViewCellDelegate? // Delegate to your ViewController to perform the segue
required init(coder aDecoder: NSCoder) {
fatalError("NSCoding not supported")
}
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
// Utility method for creating the label / view
func createLabel() -> UILabel {
let label = UILabel(frame: CGRect.nullRect)
// Add label customization here
return label
}
// Create "check" & "cross" labels for context cues
label = createLabel() // Create the label
label.text = "\u{2713}" // Add check symbol as text
super.init(style: style, reuseIdentifier: reuseIdentifier)
addSubview(label)
// Add a pan recognizer
var recognizer = UIPanGestureRecognizer(target: self, action: "handleSwipe:")
recognizer.delegate = self
addGestureRecognizer(recognizer)
}
let cueMargin: CGFloat = 10.0, cueWidth: CGFloat = 50.0
override func layoutSubviews() {
// The label starts out of view
label.frame = CGRect(x: bounds.size.width + cueMargin, y: 0, width: cueWidth, height: bounds.size.height)
}
func handleSwipe(recognizer: UIPanGestureRecognizer) {
let translation = recognizer.translationInView(self)
if recognizer.state == .Changed {
center = CGPointMake(center.x + translation.x, center.y)
startSegue = frame.origin.x < -frame.size.width / 2.0 // If swiped over 50%, return true
label.textColor = startSegue ? UIColor.redColor() : UIColor.whiteColor() // If swiped over 50%, become red
recognizer.setTranslation(CGPointZero, inView: self)
}
if recognizer.state == .Ended {
let originalFrame = CGRect(x: 0, y: frame.origin.y, width: bounds.size.width, height: bounds.size.height)
if delegate != nil {
startSegue ? delegate!.something() : UIView.animateWithDuration(0.2) { self.frame = originalFrame }
}
}
}
// Need this to handle the conflict between vertical swipes of tableviewgesture and pangesture
override func gestureRecognizerShouldBegin(gestureRecognizer: UIGestureRecognizer) -> Bool {
if let panGestureRecognizer = gestureRecognizer as? UIPanGestureRecognizer {
let velocity = panGestureRecognizer.velocityInView(superview!)
if fabs(velocity.x) >= fabs(velocity.y) { return true }
return false
}
return false
}
}
I got this from this tutorial
EDIT:
In your ViewController you'll have to 'register' this TableViewCell by using:
yourTableName.registerClass(TableViewCell.self, forCellReuseIdentifier: "cellIdentifier")
And your TableViewDataSource for cellForRowAtIndexPath would look like:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cellIdentifier", forIndexPath: indexPath) as TableViewCell
cell.delegate = self
// Add stuff for your other labels like:
// "cell.name = item.name" etc
return cell
}
If you want to pass data back to the ViewController, just use the delegate.