The content of this article is referenced from portal. the original was written in OC, and I changed it to Swift.
Let's start by looking at:
The first picture is that we drew an image of "IOS", the second picture is that we clicked save successfully, and the third picture is that we can see the picture we just drew in the album.
It feels good to have wood. And then we'll talk about how it's going to come true.
We are divided into two parts: the upper part of the drawing board and the lower half of the control area.
The top half of the drawing board is our custom view, and we set the following properties:
Class Myview:uiview { var color = Uicolor.redcolor ()//Line Color var linewidth:float = 1.0//Line width private var Allline: [Dictionary<string, anyobject>] = []//Save existing lines private var cancelline: [Dictionary<string, Anyobject>] = []//Save the revoked line private var Bézier = Uibezierpath ()//Bézier curve}
Where the color and width of the line in the controller to use, the remaining three do not need so we set up private.
Let's talk about the fallback function, it's actually very simple.
The two arrays of allline and cancelline are equivalent to two stacks. Back up, let the existing line out of the stack, into the stack to undo the line.
The exact code actually has just a few lines:
Func backimage () {//two arrays are equivalent to two stacks. Back up, let the existing line out of the stack, into the stack to undo the line. If Allline.isempty = = False {//If the array is not empty then execute cancelline.append (allline.last!)//Stack allline.removelast ()// Out Stack setneedsdisplay ()//Redraw interface }}
The forward function is just the opposite of backwards. Forward, let the dropped line out of the stack, into the stack of existing lines.
Func forwardimage () {//forward just as opposed to back, let the dropped line out of the stack, into the stack of existing lines. If Cancelline.isempty = = False {//If the array is not empty then execute allline.append (cancelline.last!)//into the stack Cancelline.removelast ()//out Stack setneedsdisplay ()//Redraw interface }}
Next talk about Bezier curves. For this example, it is simply:
1. creates a new Bezier curve and stores it in the array each time you start touching, recording the coordinates of the touch as the current coordinates of the Bezier curve.
2. the coordinates of each instantaneous are recorded while sliding, and the current coordinates of the Bezier curve are updated to this new coordinate.
3. redraw the interface.
4. perform the second step. Until this touch is over.
The code to start touching is as follows:
Override Func Touchesbegan (touches:set<uitouch>, withevent event:uievent?) { Bézier = Uibezierpath ()//New Bézier curve let point = touches.first!. Locationinview (self)//get Touch points bezier.movetopoint (point)//Set the point you just touched as the starting point of the Bezier var tmpdic = dictionary< String, anyobject> () tmpdic["color"] = Color tmpdic["linewidth"] = linewidth tmpdic["line"] = Bézier allline.append (tmpdic)//Put line in array}
The code for the touch swipe is as follows (yes, three lines, haha):
Override Func touchesmoved (touches:set<uitouch>, withevent event:uievent?) {Let point = touches.first!. Locationinview (self)//get Touch points bezier.addlinetopoint (point)//put moving coordinates into Bézier curve setneedsdisplay ()//Redraw interface}
The code for redrawing the interface is as follows (Note: Do not call the DrawRect: Method directly, call the Setneedsdisplay () method if you want to redraw it):
Override func DrawRect (rect:cgrect) {for I in 0..<allline.count {let tmpdic = allline[i] let tmpcolor = tmpdic["COLOR"] as! Uicolor let tmpwidth = tmpdic["LineWidth"] as! CGFloat let tmppath = tmpdic["line"] as! Uibezierpath Tmpcolor.setstroke () tmppath.linewidth = Tmpwidth tmppath.stroke () }}
The above is almost the entire content of the drawing board, not much, and it is not difficult to understand.
Let's talk about how to use it. Create an instance of MyView in the controller, MyView is the drawing board mentioned above.
Class Viewcontroller:uiviewcontroller { private let Drawingboard = MyView ()//Custom view, which is the drawing board part private Let MYSL Ider = UISlider ()//slide bar, control line width private Let mysegment = Uisegmentedcontrol (items: ["Red", "Black", "green"])//Segment controller, control line color
private Let backbtn = UIButton (type:. Custom) private Let savebtn = UIButton (type:. Custom) private Let forwardbtn = UIButton (type:. Custom)}
The property settings for these UI controls are nothing to say, just set frame, text, title, Titlecolor, BackgroundColor and so on, not to repeat.
It's easy for us to say that these controls respond to events.
Response event for the slider bar:
Func Onclickslider (slider:uislider) { drawingboard.linewidth = slider.value}
Response events for segmented controllers:
Func onclicksegment (segment:uisegmentedcontrol) { switch segment.selectedsegmentindex {case 0: Drawingboard.color = Uicolor.redcolor () Case 1: drawingboard.color = Uicolor.blackcolor () Case 2: Drawingboard.color = Uicolor.greencolor () default: Drawingboard.color = Uicolor.redcolor () }}
Response events for the back and Forward buttons:
Func Onclickback (Button:uibutton) { drawingboard.backimage ()}func Onclickforward (Button:uibutton) { Drawingboard.forwardimage ()}
Finally, save the feature to the album.
Func Onclicksave (Button:uibutton) { uigraphicsbeginimagecontext (drawingBoard.bounds.size)//Start capturing drawing board View.layer.renderInContext (Uigraphicsgetcurrentcontext ()!) Let Img:uiimage = Uigraphicsgetimagefromcurrentimagecontext ()//Captured image Uigraphicsendimagecontext ()//End intercept Uiimagewritetosavedphotosalbum (IMG, nil, nil, nil)//Save the captured image in the album// and finally prompt the user to save a successful let alert = Uialertview.init (title: "Save Photo Success", message: "You have stored your photos in a picture library and opened the photo program to see them.") ", delegate:self, cancelbuttontitle:" OK ") alert.show ()}
Maybe some classmates do not know how to add response events? Then we'll take the back button response to the event to give aChestnut:
Backbtn.addtarget (Self, Action:selector ("Onclickback:"), forControlEvents:. Touchupinside)
Full source Please see my github:https://github.com/963239327/lznbezierdrawingboard don't forget to click on the star in the upper right corner!
swift-Bezier curves for drawing boards && saving to albums