Приложение Draw отстает при добавлении shapeLayer в слой представлений в Swift / IOS - PullRequest
0 голосов
/ 15 ноября 2018

Я создаю приложение для рисования .Это приложение позволяет пользователю рисовать на представлении.Я называю этот вид чертеж в коде, приведенном ниже.Для создания этого приложения я использую BeizerPath и ShapeLayer , когда пользователь касается экрана, UIBeizerPath и CAShapeLayer инициализируется.Проблема с этим приложением после того, как какой-то чертежный вид отстаетЯ не могу понять, что происходит.Есть ли лучший способ оптимизировать это приложение?

CanvasViewController: UIViewController {

    // MARK: Properties

    @IBOutlet weak var verticalScrollView: UIScrollView!
    var lastPoint:CGPoint?   // var mutablePath:CGMutablePath?
    var drawLine:UIBezierPath?
    var shapeLayer:CAShapeLayer?
    let dropDown = DropDown()
    var shape:CAShapeLayer?
    let listOfDropDownMenu:[String] = ["Create New Canvas","Save","Change Color"]
    var presenter: CanvasModuleInterface?

    // MARK: IBOutlets
     @IBOutlet weak var drawingView: UIView!
    @IBOutlet weak var showColorViewControllerDropDownButton: UIBarButtonItem!

    // MARK: VC's Life cycle

    override func viewDidLoad() {
        super.viewDidLoad()
        self.setup()
        self.verticalScrollView.isUserInteractionEnabled = false
    }

    // MARK: IBActions

    // MARK: Other Functions

    @IBAction func ShowColorViewControllerAction(_ sender: Any) {
         self.dropDown.anchorView = self.showColorViewControllerDropDownButton
         self.dropDown.dataSource = self.listOfDropDownMenu
        self.dropDown.selectionAction = { [unowned self] (index: Int, item: String) in
            switch index{
            case 0:
              self.createNewView()
            case 1:
              self.saveTheCanvas()
            case 2:
             self.presentToColorViewController()

            //self.presentColorController()
            default:
                print("out of order !!!")
            }

        }
        self.dropDown.show()
    }

    private func createNewView(){
        //Mark: - create new canvas
        self.drawingView.layer.sublayers!.forEach { (layers) in
            layers.removeFromSuperlayer()
        }
    }
    private func presentToColorViewController(){
        // Mark : - naviagate to color view controller.


    }
    private func saveTheCanvas(){
        // Mark: - save the drawing

    }

    private func setup() {
        // all setup should be done here
    }
    private func presentColorController(){
        let colorSelectionController = EFColorSelectionViewController()
        let colorNavigationController = UINavigationController(rootViewController: colorSelectionController)
        colorNavigationController.navigationBar.backgroundColor = UIColor.white
        colorNavigationController.navigationBar.isTranslucent = false
        colorNavigationController.modalPresentationStyle = UIModalPresentationStyle.popover
        colorSelectionController.delegate = self
        colorSelectionController.color = self.view.backgroundColor ?? UIColor.white

        if UIUserInterfaceSizeClass.compact == self.traitCollection.horizontalSizeClass {
            let doneButton: UIBarButtonItem = UIBarButtonItem(
                title: NSLocalizedString("Done", comment: ""),
                style: UIBarButtonItem.Style.done,
                target: self,
                action: #selector(dismissViewController)
            )
            colorSelectionController.navigationItem.rightBarButtonItem = doneButton
        }
        self.present(colorNavigationController, animated: true, completion: nil)
    }
    @objc func dismissViewController(){
        //##ask confusion.....
        self.dismiss(animated: true, completion: nil)
    }

}

// MARK: CanvasViewInterface extension CanvasViewController: CanvasViewInterface {
     } extension CanvasViewController: EFColorSelectionViewControllerDelegate{
    func colorViewController(_ colorViewCntroller: EFColorSelectionViewController, didChangeColor color: UIColor) {

    } } extension CanvasViewController{

    //Mark: - this extension contains function for drawing the circle.
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        print("touches begin")

        self.drawLine = UIBezierPath()
        self.shapeLayer = CAShapeLayer()
        //       self.mutablePath = CGMutablePath()

        if let touchesPoint = touches.first{
            self.lastPoint = touchesPoint.location(in: self.drawingView)
         }

    }
    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
         //        self.drawingView.layer.sublayers!.forEach { (layer) in //            print(layer) //        }
      //  print(self.drawingView.layer)

    }
    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?){ //        print("\(self.drawingView)") //        print("\(self.drawingView.layer.sublayers)")

        var nextPoint:CGPoint?
        if let touchesPoint = touches.first{
            nextPoint = touchesPoint.location(in: self.drawingView)
            guard let lastLinePoint = self.lastPoint , let nextLinePoint = nextPoint else{return}
            self.drawLineInDrawingView(from: lastLinePoint, to: nextLinePoint)
        }
        if let newPoint = nextPoint{
        self.lastPoint  = newPoint
        }
    }
    func drawLineInDrawingView(from:CGPoint,to:CGPoint){
        drawLine!.move(to: CGPoint(x: from.x, y: from.y))
        drawLine!.addLine(to: CGPoint(x: to.x, y:  to.y))
        shapeLayer!.path = drawLine!.cgPath
        shapeLayer!.strokeColor = UIColor.black.cgColor
        shapeLayer!.lineCap = .round
        shapeLayer!.lineWidth = 100
        self.drawingView.layer.addSublayer(shapeLayer!)    //     print(self.drawingView.layer.sublayers)
    }
     }

1 Ответ

0 голосов
/ 15 ноября 2018

Не зная, что CanvasViewController вы используете, невозможно полностью ответить на ваш вопрос правильно, но я отвечу, если предположить, что он работает аналогично любому обычному UIView в iOS.

Есть несколько вещей, на которые я могу обратить внимание для улучшения производительности:

Прежде всего, не добавляйте одно и то же ShapeLayer снова и снова внутри drawLineInDrawingView(from:CGPoint,to:CGPoint) в чертежный вид, вместо этого делайте это только один раз в touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) и сохраняйте ссылку на него.

Во-вторых, ваш drawLineInDrawingView(from:CGPoint,to:CGPoint) должен выглядеть так:

func drawLineInDrawingView(from:CGPoint,to:CGPoint){
    CATransaction.begin()
    CATransaction.setDisableActions(true)

    drawLine!.move(to: CGPoint(x: from.x, y: from.y))
    drawLine!.addLine(to: CGPoint(x: to.x, y:  to.y))
    shapeLayer!.path = drawLine!.cgPath
    shapeLayer!.strokeColor = UIColor.black.cgColor
    shapeLayer!.lineCap = .round
    shapeLayer!.lineWidth = 100
    shapeLayer!.setNeedsDisplay()

    CATransaction.commit()
}

Итак, в заключение: при касании Began () вы добавляете shapeLayer и сохраняете ссылку на него. Внутри touchesMoved вы вызываете функцию drawLineInDrawingsFunction. Ваша функция drawLineInDrawings, только обновляет ваш Shapelayer с shapeLayer.setNeedsDisplay().

Помещение вашего преобразования внутри

CATransaction.begin()
CATransaction.setDisableActions(true)
/**Your transformation here**/
CATransaction.commit()

Предназначен только для того, чтобы запретить вашему представлению автоматически анимировать изменения и немедленно показывать их.

Надеюсь, это поможет.

...