3D Touch and UITableViewCell

I added some test 3D Touch functionality on the UITableViewController on iPhone 6s. In general, it works fine, but I was able to observe several problems, and I'm not sure what is happening and how to fix it in the usual way.

1) My cell is selected, so the user can click it or use "3D Touch". The problem is that when I use "Pop" and "Peek" for a UITableViewCell , it is selected, and I cannot deselect it the usual way using the setSelected: or setHighlighted: methods. I tried to deselect in different places even in previewingContext:commitViewController in presentViewController . They simply do nothing, and the cells still remain in the selected state. I got the selected cell by calling reviewingContext.sourceView and another temporary code that gave me the selected cell, but these methods did not work.

  • So, the question is, is there a normal way to deselect (or better not to select) a cell when the user clicks on it "Pop"?

2) I also noticed that sometimes when I cancel the “Pop” gesture and transfer the cell to its original state (when the previewingContext:viewControllerForLocation method was not even called), my user interface just hangs and does not respond to touch at all. I need to kill for it to work. It seems very strange, I checked this Tutorial . It works fine without the mentioned problems, but they register the delegate not in the cell, but on the UITableView , so the "Pop" gesture selects the entire tableView, but not the cell.

  • Any thoughts and what could be wrong here?

This is how I applied the 3D sensor in my UITableViewController test, which corresponds to the UIViewControllerPreviewingDelegate

 override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCellWithIdentifier("SomeDemoID", forIndexPath: indexPath) as! UITableViewCell // Some cell configuration if #available(iOS 9.0, *) { if traitCollection.forceTouchCapability == .Available { self.registerForPreviewingWithDelegate(self, sourceView: cell) } } else { // Fallback on earlier versions} return cell; } // MARK: - UIViewControllerPreviewingDelegate func previewingContext(previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) -> UIViewController? { // Just Test View Controller return UIViewController(nibName: nil, bundle: nil) } func previewingContext(previewingContext: UIViewControllerPreviewing, commitViewController viewControllerToCommit: UIViewController) { self.presentViewController(viewControllerToCommit, animated: true, completion: nil) } 

Thanks in advance!

+5
source share
3 answers
  • An easy way to add 3D Touch to a tableview cell. without one line of code

storyboard image

+3
source

I noticed the same problem. I think the problem is caused by duplication of registration. I added a flag, then the problem is fixed.

Please try this (I am using Objective-C, so please rewrite it quickly).

Introduce a category that

 @interface UITableViewCell (FourceTouchRegistered) @property (nonatomic, assign) BOOL fourceTouchRegistered; @end 

and

 #import "UITableViewCell+FourceTouchRegistered.h" #import <objc/runtime.h> @implementation UITableViewCell (FourceTouchRegistered) - (void)setFourceTouchRegistered:(BOOL)fourceTouchRegistered { objc_setAssociatedObject(self, @"fourceTouchRegistered", @(fourceTouchRegistered), OBJC_ASSOCIATION_ASSIGN); } - (BOOL)fourceTouchRegistered { return [objc_getAssociatedObject(self, @"fourceTouchRegistered") boolValue]; } @end 

then

  if(cell.fourceTouchRegistered == NO) { cell.fourceTouchRegistered = YES; if (self.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable) { [self registerForPreviewingWithDelegate:self sourceView:cell]; } } 
+1
source

Try checking if your preview of the UIViewController is presented in your previewingContext(_:viewControllerForLocation:) .

Sort of

 func previewingContext(previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) -> UIViewController? { if self.navigationController.presentedViewController.isKindOfClass(PreviewViewController) { return nil } return PreviewViewController() } 
0
source

Source: https://habr.com/ru/post/1237682/


All Articles