2017-06-21 62 views
7

是否可以檢測觸摸並從當前用作3D Touch的視圖控制器的UIViewController中獲取觸摸的位置? (我想在觸摸從左到右移動時更改預覽控制器內的圖像)在UIViewController顯示爲3DTouch預覽時檢測UITouches

我試過touchesBegantouchesMoved都沒有被觸發。

class ThreeDTouchPreviewController: UIViewController { 

func getLocationFromTouch(touches: Set<UITouch>) -> CGPoint?{ 
     guard let touch = touches.first else { return nil } 
     return touch.location(in: self.view) 
    } 
    //Not fired 
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { 

     let location = getLocationFromTouch(touches: touches) 
     print("LOCATION", location) 
    } 
    //Not fired 
    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) { 
     let location = getLocationFromTouch(touches: touches) 
     print("LOCATION", location) 
    } 
} 

甚至嘗試添加UIPanGesture。

試圖複製FaceBook的3D觸摸功能,用戶可以從左至右移動手指以更改當前顯示的圖像。 視頻上下文:https://streamable.com/ilnln

回答

6

如果你想才達到的結果相同Facebook的3D觸摸功能,你需要創建自己的3D Touch gesture class

import UIKit.UIGestureRecognizerSubclass 

class ForceTouchGestureRecognizer: UIGestureRecognizer { 

    var forceValue: CGFloat = 0 
    var isForceTouch: Bool = false 

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent) { 
     super.touchesBegan(touches, with: event) 
     handleForceWithTouches(touches: touches) 
     state = .began 
     self.isForceTouch = false 
    } 

    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent) { 
     super.touchesMoved(touches, with: event) 
     handleForceWithTouches(touches: touches) 
     if self.forceValue > 6.0 { 
      state = .changed 
      self.isForceTouch = true 
     } 
    } 

    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent) { 
     super.touchesEnded(touches, with: event) 
     state = .ended 
     handleForceWithTouches(touches: touches) 
    } 

    override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent) { 
     super.touchesCancelled(touches, with: event) 
     state = .cancelled 
     handleForceWithTouches(touches: touches) 
    } 

    func handleForceWithTouches(touches: Set<UITouch>) { 
     if touches.count != 1 { 
      state = .failed 
      return 
     } 

     guard let touch = touches.first else { 
      state = .failed 
      return 
     } 
     forceValue = touch.force 
    } 
} 

,現在你可以在viewDidLoad方法在ViewController添加此手勢

override func viewDidLoad() { 
    super.viewDidLoad() 
    let gesture = ForceTouchGestureRecognizer(target: self, action: #selector(imagePressed(sender:))) 
    self.view.addGestureRecognizer(gesture) 
} 

現在您可以在Storyboard中管理您的控制器UI。在UICollectionViewUIImageView之上添加cover view並將其與代碼中的IBOutlets連接。

現在可以添加處理程序方法用於手勢

FUNC imagePressed(發件人:ForceTouchGestureRecognizer){

let location = sender.location(in: self.view) 

guard let indexPath = collectionView?.indexPathForItem(
    at: location) else { return } 

設圖像= self.images [indexPath.row]

switch sender.state { 
case .changed: 
    if sender.isForceTouch { 
     self.coverView?.isHidden = false 
     self.selectedImageView?.isHidden = false 
     self.selectedImageView?.image = image 
    } 

case .ended: 
    print("force: \(sender.forceValue)") 
    if sender.isForceTouch { 
     self.coverView?.isHidden = true 
     self.selectedImageView?.isHidden = true 
     self.selectedImageView?.image = nil 
    } else { 
     //TODO: handle selecting items of UICollectionView here, 
     //you can refer to this SO question for more info: https://stackoverflow.com/questions/42372609/collectionview-didnt-call-didselectitematindexpath-when-superview-has-gesture 
     print("Did select row at indexPath: \(indexPath)") 
     self.collectionView?.selectItem(at: indexPath, animated: true, scrollPosition: .centeredVertically) 
    } 

default: break 
} 

}

從這一點你需要定製你的視圖來製作它看起來和Facebook一樣。

此外,我創建了GitHub上https://github.com/ChernyshenkoTaras/3DTouchExample小例子項目進行論證

+0

剛剛測試了這一點,偉大的想法,但不與'UICollectionView',它禁用滾動很好地工作和 – kye

+0

你是對的挖掘行動。我已經在GitHub上回答並修復了代碼。現在滾動是固定的,但您需要處理'imagePressed:'函數中選擇的collectionView項目 –