如何在UICollectionView上绘制触摸(UIBezierPath)?

时间:2016-08-02 00:27:04

标签: ios swift uicollectionview uibezierpath

好的,我花了好几个小时搜索和尝试一些事情,而且我已经空了。希望你们都能提供帮助!

我需要在UICollectionView上使用Apple Pencil(或手指,基本上)绘制。想想盘旋的细胞,绘制箭头,那种东西。我正在使用Apple的示例CanvasView.swift来创建UIView的子类,并且我已经能够将其设置为其他视图的子视图,以便在它们之上绘制没有问题。但是,当我使用UICollectionView执行此操作时,它不起作用。如果我将View和CollectionView放在viewController中的同一“级别”并将UICollectionView设置为隐藏,它就可以工作。如果UICollectionView可见,则仍然会绘制线条,但当然不能通过UICollectionView看到这些线条。没有其他任何方式。

我已经尝试了子类化UICollectionViewController以便自己提出一些东西,但似乎无法弄清楚如何让它工作。任何帮助都会非常感激!

谢谢!

修改:在

下添加更多详情

IB中的这个设置(通过PieChartView绘图)工作得很好: IB setup

我正在使用的代码如下(当然,删除了无关的代码):

import UIKit
import Charts

class DetailViewController: UIViewController {

    // MARK: - PROPERTIES

    @IBOutlet weak var pieCanvasView:  CanvasView!

    var canvasView: CanvasView!
    var visualizeAzimuth = false
    var table: Table!
    var masterView: MasterViewController!
    var updated: Bool! {
        didSet {
            if updated == true {
                // reload chart with new values when value changes
                updateDataSets(table.monthsToShow(), values: table.unitsSoldShow())
                pieChartView.notifyDataSetChanged()
            }
        }
    }

    // MARK: - FUNCTIONS

    override func viewDidLoad() {
        super.viewDidLoad()
    // lots of other chart-related stuff here
    }

    // MARK: - Chart

    func setChart(dataPoints:[String], values: [Double]) {
        // stuff for setting up the chart
    }

    func changeChartType(index: Int) {
    // stuff for changing the chart type
    }

    func updateDataSets(dataPoints:[String], values: [Double]) {
        // stuff for updating the chart
    }

    // MARK: - Touch Handling


    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        canvasView.drawTouches(touches, withEvent: event)
    }

    override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
        canvasView.drawTouches(touches, withEvent: event)
    }

    override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
        canvasView.drawTouches(touches, withEvent: event)
        canvasView.endTouches(touches, cancel: false)
    }

    override func touchesCancelled(touches: Set<UITouch>?, withEvent event: UIEvent?) {
        guard let touches = touches else { return }
        canvasView.endTouches(touches, cancel: true)
    }

    override func touchesEstimatedPropertiesUpdated(touches: Set<NSObject>) {
        canvasView.updateEstimatedPropertiesForTouches(touches)
    }
}

因此,理论上,此设置应该可以在UICollectionView上绘制:

V View
  V CollectionView
      CanvasView

......但事实并非如此。 (原谅图,不能发布超过2个链接)

我已尝试按如下方式对UICollectionViewController进行子类化,结果如下:

import UIKit

class CollectionViewCanvas: UICollectionViewController {

    // MARK: - VARIABLES

    var visualizeAzimuth = false

    var table:      Table!
    var detailView: DetailViewController!
    let reuseIdentifier = "cell" // also set as cell identifier in storyboard
    var textView:     UITextView!
    var clearButton:  UIButton!
    var workingData: [Double]! = []

    var canvasView = CanvasView()

    // MARK: - FUNCTIONS

    override func loadView() {
        super.loadView()

        self.collectionView?.addSubview(canvasView)
        canvasView.hidden = false
     collectionView?.hidden = true
    }

    // MARK: - UICollectionViewDataSource protocol

    // tell the collection view how many cells to make
    override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        //return self.items.count
        return self.table.COUNT
    }

    // make a cell for each cell index path
    override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
        // cell formatting here
    }

    // MARK: - UICollectionViewDelegate protocol

    override func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
        // doing stuff in here that sets up the cells
        collectionView.reloadItemsAtIndexPaths(indices)
    }

    // MARK: - UICOllectionViewDelegateFlowLayout

    func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAtIndex section: Int) -> CGFloat {
        return -0.5
    }

    func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAtIndex section: Int) -> CGFloat {
        return 0
    }

    func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
        let cellWidth = collectionView.frame.width / 5.0
        return CGSize(width: cellWidth, height: 50)
    }

    // MARK: - Touches for CanvasView

    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        canvasView.drawTouches(touches, withEvent: event)
    }

    override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
        canvasView.drawTouches(touches, withEvent: event)
    }

    override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
        canvasView.drawTouches(touches, withEvent: event)
        canvasView.endTouches(touches, cancel: false)
    }

    override func touchesCancelled(touches: Set<UITouch>?, withEvent event: UIEvent?) {
        guard let touches = touches else { return }
        canvasView.endTouches(touches, cancel: true)
    }

    override func touchesEstimatedPropertiesUpdated(touches: Set<NSObject>) {
        canvasView.updateEstimatedPropertiesForTouches(touches)
    }
}

在这种情况下,将collectionView设置为hidden,我可以使用Pencil触发touchesBegan()。如果collectionView可见,那么触摸将直接转到didSelectItemAtIndexPath,就是那样。

希望这有助于澄清!

0 个答案:

没有答案