2017-06-21 12 views
7

Có thể phát hiện chạm và lấy vị trí của một liên lạc từ UIViewController hiện đang được sử dụng làm bộ điều khiển xem previewingContext cho 3D Touch không? (Tôi muốn thay đổi hình ảnh trong bộ điều khiển xem trước khi di chuyển từ trái sang phải)Phát hiện UITouches trong khi UIViewController đang được hiển thị dưới dạng xem trước 3DTouch

Tôi đã thử cả hai touchesBegantouchesMoved không ai trong số chúng được kích hoạt.

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) 
    } 
} 

Thậm chí đã thử thêm UIPanGesture.

Cố gắng nhân rộng tính năng 3D Touch của FaceBook nơi người dùng có thể di chuyển ngón tay từ trái sang phải để thay đổi hình ảnh hiện tại đang được hiển thị. Video cho bối cảnh: https://streamable.com/ilnln

Trả lời

6

Nếu bạn muốn đạt được kết quả tương tự như trong không gian 3D cảm ứng FaceBook của tính năng mà bạn cần để tạo của riêng bạn 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 
    } 
} 

và bây giờ bạn có thể thêm cử chỉ này trong ViewController của bạn trong viewDidLoad phương pháp

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

Bây giờ bạn có thể quản lý giao diện người dùng bộ điều khiển trong Bảng phân cảnh. Thêm cover view trên UICollectionViewUIImageView ở giữa và kết nối với mã IBOutlets.

Bây giờ bạn có thể thêm các phương pháp xử lý đối với cử chỉ

func imagePressed (sender: ForceTouchGestureRecognizer) {

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

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

let image = 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 
} 

}

Từ thời điểm này, bạn cần tùy chỉnh chế độ xem của mình để tạo nó trông giống như cách Facebook làm.

Ngoài ra tôi tạo ra dự án ví dụ nhỏ trên GitHub https://github.com/ChernyshenkoTaras/3DTouchExample để chứng minh nó

+0

Chỉ cần thử nghiệm điều này ra, ý tưởng tuyệt vời nhưng không làm việc tốt với 'UICollectionView', nó vô hiệu hóa di chuyển và khai thác hành động – kye

+0

Bạn nói đúng. Tôi đã trả lời và sửa mã trên GitHub. Bây giờ di chuyển là cố định, nhưng bạn cần phải xử lý các mục collectionView chọn trong hàm 'imagePressed:' –

Các vấn đề liên quan