IOS Simple artboard development case sharing _ios

Source: Internet
Author: User
Tags uikit

Recently in learning quartz2d, learned a simple artboard implementation, now the implementation process record.

The main point is to draw lines, screenshots, draw pictures, select pictures, and save all drawn lines.

First of all, the layout of the control on the storyboard, set constraints, and so on, the final effect is this:

Custom artboard Drawview that may be loaded from xib or created manually, so the method of creating an object needs to implement two:

#import <UIKit/UIKit.h>
 
@interface drawview:uiview
/** line width *
/@property (nonatomic, assign) Nsinteger linewidth;
 
/** color *
/@property (nonatomic, strong) Uicolor *pathcolor;
 
/** Picture * * *
@property (nonatomic, strong) UIImage *image;
 
-(void) clear;
 
-(void) undo;
-(void) awakefromnib {
   
  [self setUp];
   
}
 
-(Instancetype) initWithFrame: (CGRect) Frame {
   
  if (self = = [Super Initwithframe:frame]) {
    [self setUp];
  } return
  self;
}

The setup initialization method, the thing to do when initializing is to add a drag gesture to the artboard, or you can set the line width of the brush path here

Custom Initialization Method
-(void) setUp {
   
  //Add gesture
  uipangesturerecognizer *pan = [[Uipangesturerecognizer alloc] Initwithtarget:self Action: @selector (pan:)];
  [Self addgesturerecognizer:pan];
   
  Set the path line width when initializing
  _linewidth = 2;
   
}

Start drawing lines when you move your finger on the artboard, because the native Uibezierpath class has no way to set the path color, so you can only customize the paths class

#import <UIKit/UIKit.h>
 
@interface drawpath:uibezierpath
 
@property (nonatomic, strong) Uicolor * Pathcolor;
 
@end

When the finger moves, draw the line, the path is a custom path class

@interface Drawview ()
 
@property (nonatomic, strong) DrawPath *path;
/** Save the array of all paths *
/@property (nonatomic, strong) Nsmutablearray *patharr;
 
@end
 
//Lazy load
-(Nsmutablearray *) Patharr {
  if (_patharr = = nil) {
     
    _patharr = [Nsmutablearray array];< c23/>} return
  _patharr
}
-(void) pan: (Uipangesturerecognizer *) pan {
   
  //Get start touch point
  cgpoint STARTP = [pan locationinview:self];
   
  if (pan.state = = Uigesturerecognizerstatebegan) {
     
    //create Bezier path
    _path = [[DrawPath alloc]init];
    _path.linewidth = _linewidth;
    _path.pathcolor = _pathcolor;
     
    The path cannot be added to the array when the finger is raised, because the path has not been added to the array when the paintings line is enumerated
    [_patharr Addobject:_path];
     
    Set the starting point
    [_path MOVETOPOINT:STARTP];
     
  }
   
  Wired
  [_path ADDLINETOPOINT:STARTP];
   
  redrawing, calling the DrawRect method
  [self setneedsdisplay];
   
}

Draw a line to achieve the DrawRect method, draw lines or pictures, is the array of the path to draw all the

-(void) DrawRect: (cgrect) Rect {
   
  //Draw all paths for
  (DrawPath *path in Self.patharr) {
     
    if ([path iskindofclass:[ UIImage class]] {
      //paint
      uiimage *image = (uiimage *) path;
      [Image Drawinrect:rect];
    } else {
      //Draw line
      [Path.pathcolor set];
      [Path stroke];}}
   

When you add a picture to the artboard

-(void) SetImage: (UIImage *) Image {
   
  _image = image;
   
  [Self.patharr Addobject:image];
   
  Redraw the call DrawRect to display the picture on the artboard
  [self setneedsdisplay];

You can also encapsulate the actions of the direct update path array in the artboard

-(void) Clear {
  //erase
  [Self.patharr removeallobjects];
   
  [Self setneedsdisplay];
   
}
 
-(void) Undo {
  //revoke
  [Self.patharr removelastobject];
   
  [Self setneedsdisplay];
}

In the controller:

@interface Viewcontroller () <uiimagepickercontrollerdelegate, uinavigationcontrollerdelegate>
@property (Weak, nonatomic) Iboutlet Drawview *drawview;
@end

Implement several buttons on the artboard:

-(Ibaction) clear: (ID) Sender {//clearing screen [_drawview cleared];
   
}-(Ibaction) Undo: (ID) Sender {//Undo [_drawview Undo];
  }-(Ibaction) Eraser: (ID) Sender {//erase is to set the color of the path to the background color of the artboard, false _drawview.pathcolor = _drawview.backgroundcolor;
   
_drawview.linewidth = 20;
   
}-(Ibaction) Changelinewidth: (UISlider *) Sender {//Change the path line width _drawview.linewidth = sender.value;
   
}-(Ibaction) ChangeColor: (UIButton *) Sender {//change path color _drawview.pathcolor = Sender.backgroundcolor; }-(Ibaction) Pickphoto: (ID) Sender {//SELECT Photo//Pop-up system album Uiimagepickercontroller *picker = [[Uiimagepickercontroll
   
  ER Alloc]init]; Set the source of the selection controller uiimagepickercontrollersourcetypesavedphotosalbum: Photo Gallery Picker.sourcetype =
   
  Uiimagepickercontrollersourcetypesavedphotosalbum;
   
  Set Agent picker.delegate = self;
   
Modal out controller [self presentviewcontroller:picker animated:yes completion:nil]; }-(void) Imagepickercontroller: (Uiimagepickercontroller *) Picker diDfinishpickingmediawithinfo: (nsdictionary<nsstring *,id> *) Info {//Get selected picture UIImage *image = Info[uiimagepic
   
  Kercontrolleroriginalimage];
   
  Create a view imagehandleview that handles the picture *handleview = [[Imagehandleview alloc]initwithframe:self.drawview.bounds];
  Handleview.handlecompletionblock = ^ (UIImage *image) {_drawview.image = image;
   
  };
   
  [Self.drawview Addsubview:handleview];
   
  Draw the picture on the artboard handleview.image = image;
   
  _drawview.image = image;
  Dismiss [self dismissviewcontrolleranimated:yes completion:nil];
   
NSLog (@ "%@", info);
    }-(Ibaction) Save: (ID) Sender {[UIView animatewithduration:0.15 animations:^{//save content on current artboard//open context
     
    Uigraphicsbeginimagecontextwithoptions (_drawview.bounds.size, NO, 0);
     
    Gets the bitmap context cgcontextref CTX = Uigraphicsgetcurrentcontext ();
     
    Renders the layer on the control to the context [_drawview.layer renderincontext:ctx]; Gets the picture in the context uiimage *image = UigraphicsgetimagefromcurrEntimagecontext ();
     
    Closes the context uigraphicsendimagecontext (); Save picture to album Uiimagewritetosavedphotosalbum (image, Self, @selector (image:didFinishSavingWithError:contextInfo:), nil)
     
    ;
  Self.drawView.alpha = 0;
    } completion:^ (BOOL finished) {[UIView animatewithduration:0.15 animations:^{self.drawView.alpha = 1;
  }];
   
}]; The method must be this one, not casually written-(void) Image: (UIImage *) image didfinishsavingwitherror: (nserror *) error ContextInfo: (void *)
   
ContextInfo {NSLog (@ "save Success");
 }

Select the picture from the album after the picture is displayed on the artboard but has not yet been rendered to the layer, this time need to move the picture to zoom rotation of these operations, but UIImage can not stretch the rotation of these operations, Uiimageview, So the solution is to customize a view to deal specifically with the operation of the picture, put a uiimageview on the custom view, and set the image from the photo album to Uiimageview, so that the custom view operation Uiiamgeview.

#import <UIKit/UIKit.h>
 
@interface imagehandleview:uiview
/** Pictures * * *
@property (nonatomic, Strong) UIImage *image;
 
/** block */
@property (nonatomic, strong) void (^handlecompletionblock) (UIImage *image);
@end
#import "ImageHandleView.h" @interface Imagehandleview () <UIGestureRecognizerDelegate>/** image */@property (
 
Nonatomic, weak) Uiimageview *imageview; 
   
  @end @implementation Imagehandleview//Prevent touch events on the picture from passing to the artboard-(UIView *) HitTest: (cgpoint) point withevent: (Uievent *) Event {
return _imageview; }-(Uiimageview *) ImageView {if (_imageview = = nil) {Uiimageview *imagev = [[Uiimageview alloc]initwithfram
     
    E:self.bounds];
     
    _imageview = Imagev;
     
    Set Imgaeview allow interaction with the user _imageview.userinteractionenabled = YES;
     
    Add gesture [self setupgesturerecognizer];
     
  Add this imageview to the view on the image processing [self Addsubview:imagev];
return _imageview; #pragma mark-Add gesture-(void) Setupgesturerecognizer {//translate gesture uipangesturerecognizer *pan = [[Uipangesturerecogn
  Izer alloc]initwithtarget:self Action: @selector (pan:)];
   
  [_imageview Addgesturerecognizer:pan]; Rotate gesture Uirotationgesturerecognizer *rotation = [[UirotationgestuRerecognizer alloc]initwithtarget:self Action: @selector (rotation:)];
  Rotation.delegate = self;
   
  [_imageview addgesturerecognizer:rotation]; Zoom gesture Uipinchgesturerecognizer *pinch = [Uipinchgesturerecognizer alloc]initwithtarget:self action: @selector (pinch
  :)];
  Pinch.delegate = self;
   
  [_imageview Addgesturerecognizer:pinch]; Long press gesture Uilongpressgesturerecognizer *longpress = [[Uilongpressgesturerecognizer alloc]initwithtarget:self action:@
  Selector (longpress:)];
   
[_imageview addgesturerecognizer:longpress]; #pragma mark-process panning gesture-(void) pan: (Uipangesturerecognizer *) Pan {//Get finger offset cgpoint TRANP = [Pan Translationi
   
  NView:self.imageView];
   
  Setting the ImageView deformation self.imageView.transform = Cgaffinetransformtranslate (Self.imageView.transform, tranp.x, TRANP.Y);
   
Reset [Pan Settranslation:cgpointzero InView:self.imageView]; #pragma mark-Process rotation gesture-(void) Rotation: (Uirotationgesturerecognizer *) Rotation {//set ImageView deformation Self.imageviEw.transform = Cgaffinetransformrotate (Self.imageView.transform, rotation.rotation);
   
Reset rotation.rotation = 0; #pragma mark-Process zoom gesture-(void) Pinch: (Uipinchgesturerecognizer *) Pinch {//set ImageView deformation self.imageView.transf
   
  ORM = Cgaffinetransformscale (Self.imageView.transform, Pinch.scale, Pinch.scale);
   
Reset Pinch.scale = 1; #pragma mark-handle long press gesture-(void) Longpress: (Uilongpressgesturerecognizer *) longpress {//Picture processing complete if (Longpress.sta Te = = Uigesturerecognizerstatebegan) {//Highlight effect [UIView animatewithduration:0.25 animations:^{Self.imag
    Eview.alpha = 0;  } completion:^ (BOOL finished) {[UIView animatewithduration:0.25 animations:^{Self.imageView.alpha =
      1; completion:^ (BOOL finished) {//Highlight to generate a new picture//Open bitmap context Uigraphicsbeginimagecontextwitho
         
        Ptions (self.bounds.size, NO, 0); Gets the bitmap context cgcontextref CTX = Uigraphicsgetcurrentcontext ();
         
        Renders the layer of the control to the context [Self.layer renderincontext:ctx];
         
        Gets the new picture from the context uiimage *image = Uigraphicsgetimagefromcurrentimagecontext ();
         
        Closes the context uigraphicsendimagecontext ();
        Call block if (_handlecompletionblock) {_handlecompletionblock (image);
         
      //Remove the parent control [self removefromsuperview];
       
    }];
     
     
  }]; #pragma mark-Gesture Agent Method <UIGestureRecognizerDelegate>-(BOOL) Gesturerecognizer: (Uigesturerecognizer *) gestu Rerecognizer Shouldrecognizesimultaneouslywithgesturerecognizer: (Uigesturerecognizer *) OtherGestureRecognizer {//
   
Yes to support multiple gestures return yes at the same time;
   
  }-(void) SetImage: (UIImage *) image {_image = image;
 
Show the picture to the uiimageview self.imageView.image = image;
 } @end

It should be noted that when the long press will be the operation of the picture drawing is a new picture on the artboard, this time need to set this image to the artboard Drawview, but this time it is necessary to deal with the image of the view to import the artboard view, so the coupling is too strong. So for the understanding of decoupling, you can use a proxy or block. I used block to save the image just generated, and then assign the value to Drawview after initializing the Imagehandleview in the controller.

The last thing you save on the artboard is to save the content from the artboard to the album. Note that the method that is executed after the save is done must be this:

Copy Code code as follows:
-(void) Image: (UIImage *) image didfinishsavingwitherror: (nserror *) error ContextInfo: (void *) ContextInfo;

The final effect diagram is this:

The above is the entire content of this article, I hope to learn about iOS program design help.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.