У меня есть код, который рисует линии, используя UIBezierPath.Чертеж класса рисования прямых линий вместо изогнутых линий
Код использует addCurveToPoint
, который должен рисовать кривые линии, используя кубический путь безье, однако конечный результат кода вместо этого связан с прямыми линиями, но addLineToPoint
не используется.
Что может происходить, почему не кривые рисунка кода?
import UIKit
class DrawingView: UIView, UITextFieldDelegate {
// Modifiable values within the code
let lineWidth : CGFloat = 2.0
let lineColor = UIColor.redColor()
let lineColorAlpha : CGFloat = 0.4
let shouldAllowUserChangeLineWidth = true
let maximumUndoRedoChances = 10
var path = UIBezierPath()
var previousImages : [UIImage] = [UIImage]()
// Represents current image index
var currentImageIndex = 0
// Control points for drawing curve smoothly
private var controlPoint1 : CGPoint?
private var controlPoint2 : CGPoint?
private var undoButton : UIButton!
private var redoButton : UIButton!
private var textField : UITextField!
//MARK: Init methods
override init(frame: CGRect) {
super.init(frame: frame)
setDefaultValues()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setDefaultValues()
}
// Draw the path when needed
override func drawRect(rect: CGRect) {
if currentImageIndex > 0 {
previousImages[currentImageIndex - 1].drawInRect(rect)
}
lineColor.setStroke()
path.strokeWithBlendMode(CGBlendMode.Normal, alpha: lineColorAlpha)
}
override func layoutSubviews() {
super.layoutSubviews()
redoButton.frame = CGRectMake(bounds.size.width - 58, 30, 50, 44)
if shouldAllowUserChangeLineWidth {
textField.center = CGPointMake(center.x, 52)
}
}
func setDefaultValues() {
multipleTouchEnabled = false
backgroundColor = UIColor.whiteColor()
path.lineWidth = lineWidth
addButtonsAndField()
}
func addButtonsAndField() {
undoButton = UIButton(frame: CGRectMake(8, 30, 50, 44))
undoButton.setTitle("Undo", forState: UIControlState.Normal)
undoButton.setTitleColor(UIColor.blackColor(), forState: UIControlState.Normal)
undoButton.backgroundColor = UIColor.lightGrayColor()
undoButton.addTarget(self, action: "undoButtonTapped:", forControlEvents: UIControlEvents.TouchUpInside)
addSubview(undoButton)
redoButton = UIButton(frame: CGRectMake(bounds.size.width - 58, 30, 50, 44))
redoButton.setTitle("Redo", forState: UIControlState.Normal)
redoButton.setTitleColor(UIColor.blackColor(), forState: UIControlState.Normal)
redoButton.backgroundColor = UIColor.lightGrayColor()
redoButton.addTarget(self, action: "redoButtonTapped:", forControlEvents: UIControlEvents.TouchUpInside)
addSubview(redoButton)
if shouldAllowUserChangeLineWidth {
textField = UITextField(frame: CGRectMake(0, 0, 50, 40))
textField.backgroundColor = UIColor.lightGrayColor()
textField.center = CGPointMake(center.x, 52)
textField.keyboardType = UIKeyboardType.NumberPad
textField.delegate = self
addSubview(textField)
}
}
//MARK: Touches methods
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
// Find the start point and move the path there
endEditing(true)
let touchPoint = touches.first?.locationInView(self)
path.moveToPoint(touchPoint!)
}
override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
let touchPoint = touches.first?.locationInView(self)
controlPoint1 = CGPointMake((path.currentPoint.x + touchPoint!.x)/2, (path.currentPoint.y + touchPoint!.y)/2)
controlPoint2 = CGPointMake((path.currentPoint.x + touchPoint!.x)/2, (path.currentPoint.y + touchPoint!.y)/2)
path.addCurveToPoint(touchPoint!, controlPoint1: controlPoint1!, controlPoint2: controlPoint2!)
setNeedsDisplay()
}
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
let touchPoint = touches.first?.locationInView(self)
controlPoint1 = CGPointMake((path.currentPoint.x + touchPoint!.x)/2, (path.currentPoint.y + touchPoint!.y)/2)
controlPoint2 = CGPointMake((path.currentPoint.x + touchPoint!.x)/2, (path.currentPoint.y + touchPoint!.y)/2)
path.addCurveToPoint(touchPoint!, controlPoint1: controlPoint1!, controlPoint2: controlPoint2!)
savePreviousImage()
setNeedsDisplay()
// Remove all points to optimize the drawing speed
path.removeAllPoints()
}
override func touchesCancelled(touches: Set<UITouch>?, withEvent event: UIEvent?) {
touchesEnded(touches!, withEvent: event)
}
//MARK: Selector methods
func undoButtonTapped(sender : UIButton) {
if currentImageIndex > 0 {
setNeedsDisplay()
currentImageIndex--
}
}
func redoButtonTapped(sender : UIButton) {
if currentImageIndex != previousImages.count {
setNeedsDisplay()
currentImageIndex++
}
}
//MARK: UITextFieldDelegate
func textFieldDidEndEditing(textField: UITextField) {
if let n = NSNumberFormatter().numberFromString(textField.text!) {
if n.integerValue > 0 {
path.lineWidth = CGFloat(n)
}
}
}
//MARK: Saving images for reloading when undo or redo called
private func savePreviousImage() {
UIGraphicsBeginImageContextWithOptions(bounds.size, true, UIScreen.mainScreen().scale)
lineColor.setStroke()
// Create a image with white color
let rectPath = UIBezierPath(rect: bounds)
backgroundColor?.setFill()
rectPath.fill()
if currentImageIndex > 0 {
previousImages[currentImageIndex - 1].drawInRect(bounds)
}
path.strokeWithBlendMode(CGBlendMode.Normal, alpha: lineColorAlpha)
if previousImages.count >= currentImageIndex {
previousImages.removeRange(currentImageIndex..<previousImages.count)
}
if previousImages.count >= maximumUndoRedoChances {
previousImages.removeFirst()
}
else {
currentImageIndex++
}
previousImages.append(UIGraphicsGetImageFromCurrentImageContext())
UIGraphicsEndImageContext()
}
}
HTTP: // код. tutsplus.com/tutorials/smooth-freehand-drawing-on-ios--mobile-13164 –
Вам нужно настроить 'controlPoint1' и' controlPoint2' для создания гладкой кривой. В настоящее время вы устанавливаете обе контрольные точки на полпути между предыдущей точкой и следующей точкой, что создает прямую линию. Учебник, связанный с MrT, показывает некоторые способы расчета разумных контрольных точек. –