Browse Source

PDFView(ios) - 水印加背景demo

yangliuhua 2 years ago
parent
commit
79e32c1a27

+ 49 - 1
PDFViewer.xcodeproj/project.pbxproj

@@ -7,12 +7,20 @@
 	objects = {
 
 /* Begin PBXBuildFile section */
+		C92BA1912963CAB4009954EF /* UIImage+TintColor.m in Sources */ = {isa = PBXBuildFile; fileRef = C92BA1902963CAB4009954EF /* UIImage+TintColor.m */; };
+		C92BA1942963F806009954EF /* CPDFDrawBackgroundView.m in Sources */ = {isa = PBXBuildFile; fileRef = C92BA1932963F806009954EF /* CPDFDrawBackgroundView.m */; };
+		C92BA1972963F84B009954EF /* CPDFDrawImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = C92BA1962963F84B009954EF /* CPDFDrawImageView.m */; };
+		C92BA19A29651CA3009954EF /* CPDFBackgroundModel.m in Sources */ = {isa = PBXBuildFile; fileRef = C92BA19929651CA3009954EF /* CPDFBackgroundModel.m */; };
 		C96150D2295400B00020F445 /* CPDFDrawView.m in Sources */ = {isa = PBXBuildFile; fileRef = C96150D1295400B00020F445 /* CPDFDrawView.m */; };
 		C96150D529554F660020F445 /* CPDFClipView.m in Sources */ = {isa = PBXBuildFile; fileRef = C96150D429554F660020F445 /* CPDFClipView.m */; };
 		C96384932949E2020055CCCA /* ComPDFKit.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = C96384922949E2020055CCCA /* ComPDFKit.xcframework */; };
 		C9638496294ACC240055CCCA /* CPDFAddViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = C9638495294ACC240055CCCA /* CPDFAddViewController.m */; };
 		C96D13932924793800CC92C7 /* btn_more.png in Resources */ = {isa = PBXBuildFile; fileRef = C96D13922924793800CC92C7 /* btn_more.png */; };
 		C97E91682959B96C007F6943 /* CPDFEditView.m in Sources */ = {isa = PBXBuildFile; fileRef = C97E91672959B96C007F6943 /* CPDFEditView.m */; };
+		C986D3F52962857900EBD4DF /* CPDFBackgroundSettingViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = C986D3F42962857900EBD4DF /* CPDFBackgroundSettingViewController.m */; };
+		C986D3F8296288C400EBD4DF /* CPDFBackgroundPreview.m in Sources */ = {isa = PBXBuildFile; fileRef = C986D3F7296288C400EBD4DF /* CPDFBackgroundPreview.m */; };
+		C986D3FB296288F700EBD4DF /* CPDFBackgroundView.m in Sources */ = {isa = PBXBuildFile; fileRef = C986D3FA296288F700EBD4DF /* CPDFBackgroundView.m */; };
+		C986D3FE2962A70400EBD4DF /* CPDFBackgroundSettingView.m in Sources */ = {isa = PBXBuildFile; fileRef = C986D3FD2962A70400EBD4DF /* CPDFBackgroundSettingView.m */; };
 		EC62978E29220F8300D339EE /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = EC62978D29220F8300D339EE /* AppDelegate.m */; };
 		EC62979129220F8300D339EE /* SceneDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = EC62979029220F8300D339EE /* SceneDelegate.m */; };
 		EC62979429220F8300D339EE /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = EC62979329220F8300D339EE /* ViewController.m */; };
@@ -57,6 +65,14 @@
 /* End PBXCopyFilesBuildPhase section */
 
 /* Begin PBXFileReference section */
+		C92BA18F2963CAB4009954EF /* UIImage+TintColor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "UIImage+TintColor.h"; sourceTree = "<group>"; };
+		C92BA1902963CAB4009954EF /* UIImage+TintColor.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "UIImage+TintColor.m"; sourceTree = "<group>"; };
+		C92BA1922963F806009954EF /* CPDFDrawBackgroundView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CPDFDrawBackgroundView.h; sourceTree = "<group>"; };
+		C92BA1932963F806009954EF /* CPDFDrawBackgroundView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CPDFDrawBackgroundView.m; sourceTree = "<group>"; };
+		C92BA1952963F84B009954EF /* CPDFDrawImageView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CPDFDrawImageView.h; sourceTree = "<group>"; };
+		C92BA1962963F84B009954EF /* CPDFDrawImageView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CPDFDrawImageView.m; sourceTree = "<group>"; };
+		C92BA19829651CA3009954EF /* CPDFBackgroundModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CPDFBackgroundModel.h; sourceTree = "<group>"; };
+		C92BA19929651CA3009954EF /* CPDFBackgroundModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CPDFBackgroundModel.m; sourceTree = "<group>"; };
 		C96150D0295400B00020F445 /* CPDFDrawView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CPDFDrawView.h; sourceTree = "<group>"; };
 		C96150D1295400B00020F445 /* CPDFDrawView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CPDFDrawView.m; sourceTree = "<group>"; };
 		C96150D329554F660020F445 /* CPDFClipView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CPDFClipView.h; sourceTree = "<group>"; };
@@ -67,6 +83,14 @@
 		C96D13922924793800CC92C7 /* btn_more.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = btn_more.png; sourceTree = "<group>"; };
 		C97E91662959B96C007F6943 /* CPDFEditView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CPDFEditView.h; sourceTree = "<group>"; };
 		C97E91672959B96C007F6943 /* CPDFEditView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CPDFEditView.m; sourceTree = "<group>"; };
+		C986D3F32962857900EBD4DF /* CPDFBackgroundSettingViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CPDFBackgroundSettingViewController.h; sourceTree = "<group>"; };
+		C986D3F42962857900EBD4DF /* CPDFBackgroundSettingViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CPDFBackgroundSettingViewController.m; sourceTree = "<group>"; };
+		C986D3F6296288C400EBD4DF /* CPDFBackgroundPreview.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CPDFBackgroundPreview.h; sourceTree = "<group>"; };
+		C986D3F7296288C400EBD4DF /* CPDFBackgroundPreview.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CPDFBackgroundPreview.m; sourceTree = "<group>"; };
+		C986D3F9296288F700EBD4DF /* CPDFBackgroundView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CPDFBackgroundView.h; sourceTree = "<group>"; };
+		C986D3FA296288F700EBD4DF /* CPDFBackgroundView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CPDFBackgroundView.m; sourceTree = "<group>"; };
+		C986D3FC2962A70400EBD4DF /* CPDFBackgroundSettingView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CPDFBackgroundSettingView.h; sourceTree = "<group>"; };
+		C986D3FD2962A70400EBD4DF /* CPDFBackgroundSettingView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CPDFBackgroundSettingView.m; sourceTree = "<group>"; };
 		EC62978929220F8300D339EE /* PDFViewer.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = PDFViewer.app; sourceTree = BUILT_PRODUCTS_DIR; };
 		EC62978C29220F8300D339EE /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
 		EC62978D29220F8300D339EE /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
@@ -169,8 +193,8 @@
 			children = (
 				ECD0ABF62928EE9A0091B6EB /* Masonry */,
 				EC6297B52922393F00D339EE /* Controller */,
-				EC6297AD29222D3100D339EE /* Model */,
 				ECD0ABE42928ED5D0091B6EB /* View */,
+				EC6297AD29222D3100D339EE /* Model */,
 				EC62978D29220F8300D339EE /* AppDelegate.m */,
 				EC62978C29220F8300D339EE /* AppDelegate.h */,
 				EC62978F29220F8300D339EE /* SceneDelegate.h */,
@@ -193,6 +217,8 @@
 				EC6297B7292239A700D339EE /* CPDFModel.m */,
 				ECD0AC30292B56C90091B6EB /* CPDFDataModel.h */,
 				ECD0AC31292B56C90091B6EB /* CPDFDataModel.m */,
+				C92BA19829651CA3009954EF /* CPDFBackgroundModel.h */,
+				C92BA19929651CA3009954EF /* CPDFBackgroundModel.m */,
 			);
 			path = Model;
 			sourceTree = "<group>";
@@ -211,6 +237,8 @@
 				ECD0AC252928F2E50091B6EB /* CPDFImageViewController.m */,
 				C9638494294ACC240055CCCA /* CPDFAddViewController.h */,
 				C9638495294ACC240055CCCA /* CPDFAddViewController.m */,
+				C986D3F32962857900EBD4DF /* CPDFBackgroundSettingViewController.h */,
+				C986D3F42962857900EBD4DF /* CPDFBackgroundSettingViewController.m */,
 			);
 			path = Controller;
 			sourceTree = "<group>";
@@ -233,6 +261,18 @@
 				C96150D429554F660020F445 /* CPDFClipView.m */,
 				C97E91662959B96C007F6943 /* CPDFEditView.h */,
 				C97E91672959B96C007F6943 /* CPDFEditView.m */,
+				C986D3F6296288C400EBD4DF /* CPDFBackgroundPreview.h */,
+				C986D3F7296288C400EBD4DF /* CPDFBackgroundPreview.m */,
+				C986D3F9296288F700EBD4DF /* CPDFBackgroundView.h */,
+				C986D3FA296288F700EBD4DF /* CPDFBackgroundView.m */,
+				C986D3FC2962A70400EBD4DF /* CPDFBackgroundSettingView.h */,
+				C986D3FD2962A70400EBD4DF /* CPDFBackgroundSettingView.m */,
+				C92BA1922963F806009954EF /* CPDFDrawBackgroundView.h */,
+				C92BA1932963F806009954EF /* CPDFDrawBackgroundView.m */,
+				C92BA1952963F84B009954EF /* CPDFDrawImageView.h */,
+				C92BA1962963F84B009954EF /* CPDFDrawImageView.m */,
+				C92BA18F2963CAB4009954EF /* UIImage+TintColor.h */,
+				C92BA1902963CAB4009954EF /* UIImage+TintColor.m */,
 			);
 			path = View;
 			sourceTree = "<group>";
@@ -361,22 +401,30 @@
 				C9638496294ACC240055CCCA /* CPDFAddViewController.m in Sources */,
 				ECD0AC1D2928EECB0091B6EB /* MASViewAttribute.m in Sources */,
 				ECD0AC182928EECB0091B6EB /* MASCompositeConstraint.m in Sources */,
+				C986D3FE2962A70400EBD4DF /* CPDFBackgroundSettingView.m in Sources */,
 				ECD0AC1C2928EECB0091B6EB /* View+MASAdditions.m in Sources */,
 				C96150D529554F660020F445 /* CPDFClipView.m in Sources */,
 				ECD0AC152928EECB0091B6EB /* MASLayoutConstraint.m in Sources */,
 				EC62978E29220F8300D339EE /* AppDelegate.m in Sources */,
 				EC62979F29220F8400D339EE /* main.m in Sources */,
 				EC6297BD292239C200D339EE /* CPDFListController.m in Sources */,
+				C92BA1942963F806009954EF /* CPDFDrawBackgroundView.m in Sources */,
+				C986D3F52962857900EBD4DF /* CPDFBackgroundSettingViewController.m in Sources */,
 				ECD0AC132928EECB0091B6EB /* MASConstraintMaker.m in Sources */,
 				ECD0AC1A2928EECB0091B6EB /* ViewController+MASAdditions.m in Sources */,
 				ECD0AC142928EECB0091B6EB /* NSLayoutConstraint+MASDebugAdditions.m in Sources */,
 				ECD0AC162928EECB0091B6EB /* NSArray+MASAdditions.m in Sources */,
+				C986D3FB296288F700EBD4DF /* CPDFBackgroundView.m in Sources */,
+				C92BA19A29651CA3009954EF /* CPDFBackgroundModel.m in Sources */,
 				ECD0AC192928EECB0091B6EB /* MASViewConstraint.m in Sources */,
 				EC62979129220F8300D339EE /* SceneDelegate.m in Sources */,
+				C92BA1972963F84B009954EF /* CPDFDrawImageView.m in Sources */,
 				ECD0ABF52928ED9A0091B6EB /* CPDFImagePreview.m in Sources */,
 				ECD0AC32292B56C90091B6EB /* CPDFDataModel.m in Sources */,
 				ECD0ABF42928ED9A0091B6EB /* CPDFTextView.m in Sources */,
 				ECD0ABF32928ED9A0091B6EB /* CPDFImageView.m in Sources */,
+				C986D3F8296288C400EBD4DF /* CPDFBackgroundPreview.m in Sources */,
+				C92BA1912963CAB4009954EF /* UIImage+TintColor.m in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};

+ 4 - 4
PDFViewer/Controller/CPDFAddViewController.m

@@ -46,7 +46,7 @@
 
 #pragma mark - Initializers
 
-- (instancetype)initWithDocument:(CPDFDocument *)document{
+- (instancetype)initWithDocument:(CPDFDocument *)document {
     self = [super init];
     if (self) {
         _document = document;
@@ -92,7 +92,7 @@
 
 - (void)addConstraint {
     
-    if ([UIDevice currentDevice].orientation == UIDeviceOrientationLandscapeRight || [UIDevice currentDevice].orientation == UIDeviceOrientationLandscapeLeft || [UIDevice currentDevice].orientation == UIDeviceOrientationPortraitUpsideDown) {
+    if ([UIDevice currentDevice].orientation == UIDeviceOrientationLandscapeRight || [UIDevice currentDevice].orientation == UIDeviceOrientationLandscapeLeft || [UIDevice currentDevice].orientation == UIDeviceOrientationPortraitUpsideDown || (self.view.frame.size.width > self.view.frame.size.height)) {
         [self addSideConstraint];
     } else {
         [self addNomalConstraint];
@@ -124,7 +124,7 @@
         make.bottom.equalTo(self.view.mas_bottom).offset(-74);
     }];
     [_textViewController.textPreview mas_remakeConstraints:^(MASConstraintMaker *make) {
-        make.top.equalTo(self.segmentedControl.mas_bottom).offset(10);
+        make.top.equalTo(self.segmentedControl.mas_bottom).offset(0);
         make.right.equalTo(_textViewController.textView.mas_left).offset(-5);
         make.left.equalTo(self.view.mas_left).offset(0);
         make.bottom.equalTo(self.view.mas_bottom).offset(-34);
@@ -137,7 +137,7 @@
         make.bottom.equalTo(self.view.mas_bottom).offset(-74);
     }];
     [_imageViewController.imagePreview mas_remakeConstraints:^(MASConstraintMaker *make) {
-        make.top.equalTo(self.segmentedControl.mas_bottom).offset(10);
+        make.top.equalTo(self.segmentedControl.mas_bottom).offset(0);
         make.right.equalTo(_imageViewController.imageView.mas_left).offset(-5);
         make.left.equalTo(self.view.mas_left).offset(0);
         make.bottom.equalTo(self.view.mas_bottom).offset(-34);

+ 31 - 0
PDFViewer/Controller/CPDFBackgroundSettingViewController.h

@@ -0,0 +1,31 @@
+//
+//  CPDFBackgroundSettingViewController.h
+//  PDFViewer
+//
+//  Created by kdanmobile_2 on 2023/1/2.
+//
+
+#import <UIKit/UIKit.h>
+#import <ComPDFKit/ComPDFKit.h>
+#import "CPDFBackgroundModel.h"
+
+
+NS_ASSUME_NONNULL_BEGIN
+
+@protocol BackgroundDataModelDelegate <NSObject>
+
+- (void)changeBackgroundModel:(CPDFBackgroundModel *)dataModel;
+- (void)deleteBackgroundModel;
+
+@end
+
+@interface CPDFBackgroundSettingViewController : UIViewController
+
+@property (nonatomic,strong) CPDFDocument *document;
+@property (nonatomic,strong) id<BackgroundDataModelDelegate> delegate;
+
+- (instancetype)initWithDocument:(CPDFDocument *)document;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 400 - 0
PDFViewer/Controller/CPDFBackgroundSettingViewController.m

@@ -0,0 +1,400 @@
+//
+//  CPDFBackgroundSettingViewController.m
+//  PDFViewer
+//
+//  Created by kdanmobile_2 on 2023/1/2.
+//
+
+#import "CPDFBackgroundSettingViewController.h"
+#import "CPDFBackgroundView.h"
+#import "CPDFBackgroundPreview.h"
+#import "CPDFBackgroundSettingView.h"
+#import "CPDFDrawBackgroundView.h"
+#import "CPDFDrawImageView.h"
+#import "Masonry.h"
+#import "UIImage+TintColor.h"
+
+@interface CPDFBackgroundSettingViewController () <UIImagePickerControllerDelegate,UINavigationControllerDelegate,UITextFieldDelegate>
+
+@property (nonatomic,strong) CPDFBackgroundView *backgroundView;
+@property (nonatomic,strong) CPDFBackgroundPreview *backgroundPreView;
+@property (nonatomic,strong) CPDFBackgroundSettingView *backgroudSettingView;
+@property (nonatomic,strong) CPDFDrawImageView *drawImageView;
+@property (nonatomic,strong) CPDFDrawBackgroundView *drawBackgroundView;
+@property (nonatomic,strong) CPDFBackgroundModel *dataModel;
+@property (nonatomic,assign) CGSize imageSize;
+@property (nonatomic,strong) UIImage *image;
+
+@end
+
+@implementation CPDFBackgroundSettingViewController
+
+- (void)viewDidLoad {
+    [super viewDidLoad];
+    
+    UIBarButtonItem *doneBtn = [[UIBarButtonItem alloc] initWithTitle:@"Done" style:UIBarButtonItemStylePlain target:self action:@selector(onClickedDoneBtn)];
+    
+    UIBarButtonItem *editBtn = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemEdit target:self action:@selector(editClick)];
+    
+    UIBarButtonItem *deleteBtn = [[UIBarButtonItem alloc] initWithTitle:@"Delete" style:UIBarButtonItemStylePlain target:self action:@selector(deleteClick)];
+    
+    self.navigationItem.rightBarButtonItems = @[doneBtn, editBtn, deleteBtn];
+     
+    [self initDataMoel];
+    [self createView];
+    [self addConstraint];
+    [self addTargets];
+}
+
+#pragma mark - Initializers
+
+- (instancetype)initWithDocument:(CPDFDocument *)document {
+    self = [super init];
+    if (self) {
+        _document = document;
+        
+        CPDFPage *pdfPage = [document pageAtIndex:0];
+        CGSize imageSize = [document pageSizeAtIndex:0];
+        _image = [pdfPage thumbnailOfSize:imageSize];
+        _imageSize = imageSize;
+    }
+    return self;
+}
+
+- (void)createView {
+    _backgroundView = [[CPDFBackgroundView alloc] init];
+    [self.view addSubview:_backgroundView];
+    
+    _backgroundPreView = [[CPDFBackgroundPreview alloc] init];
+    [self.view addSubview:_backgroundPreView];
+    
+    _backgroundPreView.documentView.image = self.image;
+    
+    _drawBackgroundView = [[CPDFDrawBackgroundView alloc] initWithFrame:CGRectMake(0, 40, 393, 598.333)];
+    _drawBackgroundView.dataModel = self.dataModel;
+    [self.backgroundPreView addSubview:_drawBackgroundView];
+    
+    _drawImageView      = [[CPDFDrawImageView alloc] initWithFrame:CGRectMake(0, 40, 393, 598.333)];
+    [_drawImageView setImage:_image];
+    [self.backgroundPreView addSubview:_drawImageView];
+}
+
+- (void)initDataMoel {
+    _dataModel = [[CPDFBackgroundModel alloc] init];
+    _dataModel.backgroundColor = [UIColor whiteColor];
+    _dataModel.backgroudScale = 1.0f;
+    _dataModel.backgroundOpacity = 1.0f;
+    _dataModel.backgroundRotation = 0.0f;
+    _dataModel.verticalSpacing = 0.0f;
+    _dataModel.horizontalSpacing = 0.0f;
+}
+
+- (void)addConstraint {
+    if ([UIDevice currentDevice].orientation == UIDeviceOrientationLandscapeRight || [UIDevice currentDevice].orientation == UIDeviceOrientationLandscapeLeft || [UIDevice currentDevice].orientation == UIDeviceOrientationPortraitUpsideDown || (self.view.frame.size.width > self.view.frame.size.height)) {
+        [self addSideConstraint];
+    } else {
+        [self addNomalConstraint];
+    }
+}
+
+- (void)addSideConstraint {
+    [_backgroundView mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.bottom.equalTo(self.view.mas_bottom).offset(-5);
+        make.left.equalTo(self.view.mas_left);
+        make.right.equalTo(self.view.mas_right);
+        make.height.mas_equalTo(70);
+    }];
+    
+    [_backgroundPreView mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.top.equalTo(self.view.mas_top).offset(43.6);
+        make.left.equalTo(self.view.mas_left);
+        make.right.equalTo(self.view.mas_right);
+        make.bottom.equalTo(self.backgroundView.mas_top);
+    }];
+    
+    [_backgroundPreView.documentView mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.top.equalTo(self.view.mas_top).offset(43.6);
+        make.bottom.equalTo(self.backgroundPreView.mas_bottom);
+        make.centerX.equalTo(self.backgroundPreView.mas_centerX);
+        make.width.mas_equalTo(233);
+    }];
+    
+    [_drawBackgroundView mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.top.equalTo(self.backgroundPreView.documentView.mas_top);
+        make.bottom.equalTo(self.backgroundPreView.documentView.mas_bottom);
+        make.left.equalTo(self.backgroundPreView.documentView.mas_left);
+        make.right.equalTo(self.backgroundPreView.documentView.mas_right);
+    }];
+    [_drawImageView mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.top.equalTo(self.backgroundPreView.documentView.mas_top);
+        make.bottom.equalTo(self.backgroundPreView.documentView.mas_bottom);
+        make.left.equalTo(self.backgroundPreView.documentView.mas_left);
+        make.right.equalTo(self.backgroundPreView.documentView.mas_right);
+    }];
+}
+
+- (void)addNomalConstraint {
+    [_backgroundView mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.bottom.equalTo(self.view.mas_bottom).offset(-20);
+        make.left.equalTo(self.view.mas_left);
+        make.right.equalTo(self.view.mas_right);
+        make.height.mas_equalTo(70);
+    }];
+    
+    [_backgroundPreView mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.top.equalTo(self.view.mas_top).offset(83.6);
+        make.left.equalTo(self.view.mas_left);
+        make.right.equalTo(self.view.mas_right);
+        make.bottom.equalTo(self.backgroundView.mas_top);
+    }];
+    
+    [_backgroundPreView.documentView mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.left.equalTo(self.backgroundPreView.mas_left);
+        make.top.equalTo(self.backgroundPreView.mas_top).offset(40);
+        make.bottom.equalTo(self.backgroundPreView.mas_bottom).offset(-40);
+        make.width.mas_equalTo(393);
+    }];
+}
+
+- (void)addTargets {
+    [_backgroundView.selectBtn addTarget:self action:@selector(onSelectBtnClicked:) forControlEvents:UIControlEventTouchDown];
+    
+    for (NSInteger i = 0; i < _backgroundView.colorArray.count; ++i) {
+        [_backgroundView.colorArray[i] addTarget:self action:@selector(onColorBtnClicked:) forControlEvents:UIControlEventTouchDown];
+    }
+}
+
+#pragma mark - Actions
+
+- (void)onClickedDoneBtn {
+    [self.delegate changeBackgroundModel:self.dataModel];
+    
+    [self.navigationController popViewControllerAnimated:YES];
+}
+
+- (void)editClick {
+    
+    if (!([_backgroudSettingView isDescendantOfView:self.view])) {
+        _backgroudSettingView = [[CPDFBackgroundSettingView alloc] init];
+        
+        _backgroudSettingView.verticalField.delegate = self;
+        _backgroudSettingView.horizontalField.delegate = self;
+        
+        [self.view addSubview:_backgroudSettingView];
+        
+        [_backgroudSettingView mas_makeConstraints:^(MASConstraintMaker *make) {
+            make.centerX.equalTo(self.backgroundPreView.mas_centerX);
+            make.centerY.equalTo(self.backgroundPreView.mas_centerY);
+            make.height.mas_equalTo(330);
+            make.width.mas_equalTo(320);
+        }];
+        
+        [UIView animateWithDuration:0.2 delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^{
+            self.backgroudSettingView.center = CGPointMake(self.backgroudSettingView.center.x, self.backgroudSettingView.center.y - 300);
+        } completion:nil];
+        
+        [_backgroudSettingView.pageBtn addTarget:self action:@selector(onSelectPageRange:) forControlEvents:UIControlEventTouchUpInside];
+        [_backgroudSettingView.doneBtn addTarget:self action:@selector(doneClick:) forControlEvents:UIControlEventTouchUpInside];
+        [_backgroudSettingView.cancelBtn addTarget:self action:@selector(cancelClick:) forControlEvents:UIControlEventTouchUpInside];
+        
+        [_backgroudSettingView.opacitySlider addTarget:self action:@selector(onOpacityChanged:) forControlEvents:UIControlEventValueChanged];
+        [_backgroudSettingView.scaleSlider addTarget:self action:@selector(onScaleChanged:) forControlEvents:UIControlEventValueChanged];
+        [_backgroudSettingView.rotationSlider addTarget:self action:@selector(onRotationChanged:) forControlEvents:UIControlEventValueChanged];
+        
+        [_backgroudSettingView.horizontalField addTarget:self action:@selector(horizontalChange:) forControlEvents:UIControlEventEditingDidEnd];
+        [_backgroudSettingView.verticalField addTarget:self action:@selector(verticalChage:) forControlEvents:UIControlEventEditingDidEnd];
+    }
+}
+
+- (void)deleteClick {
+    [self.delegate deleteBackgroundModel];
+    
+    [self.navigationController popViewControllerAnimated:YES];
+}
+
+#pragma mark - UI Functions
+
+- (void)onColorBtnClicked:(UIButton *)btn {
+    
+    _dataModel.backgroundColor = btn.backgroundColor;
+    _drawBackgroundView.dataModel = self.dataModel;
+    [_drawBackgroundView setNeedsDisplay];
+    
+//    _backgroundPreView.documentView.image = [_image imageWithTintColor:btn.backgroundColor];
+}
+
+- (void)onSelectBtnClicked:(UIButton *)sender {
+    UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
+    imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
+    imagePicker.delegate = self;
+    imagePicker.allowsEditing = YES;
+    [self presentViewController:imagePicker animated:YES completion:nil];
+}
+
+- (void)onSelectPageRange:(UIButton *)btn {
+    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet];
+    UIAlertAction *defaultRange = [UIAlertAction actionWithTitle:@"All Pages" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
+        self.backgroudSettingView.rangeLabel.text = @"Page Range: ALL";
+        }];
+    UIAlertAction *customRange = [UIAlertAction actionWithTitle:@"Custom" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
+        [self createCustomRangeAlert];
+        }];
+    UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
+            
+        }];
+    [alertController addAction:defaultRange];
+    [alertController addAction:customRange];
+    [alertController addAction:cancelAction];
+    [self presentViewController:alertController animated:YES completion:nil];
+}
+
+- (void)createCustomRangeAlert {
+    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Custom Page Range" message:nil preferredStyle:UIAlertControllerStyleAlert];
+    
+    [alertController addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
+        textField.placeholder = @"such as:1,3-5,10";
+    }];
+    [alertController addAction:[UIAlertAction actionWithTitle:@"Done" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
+        
+        self.dataModel.pageString = alertController.textFields.firstObject.text;
+        self.backgroudSettingView.rangeLabel.text = @"Page Range:Custom";
+    }]];
+    [alertController addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
+    }]];
+    [self presentViewController:alertController animated:YES completion:nil];
+}
+
+- (void)doneClick:(UIButton *)btn {
+    _drawBackgroundView.dataModel = self.dataModel;
+    
+    [_drawBackgroundView setNeedsDisplay];
+    [_backgroudSettingView removeFromSuperview];
+}
+
+- (void)cancelClick:(UIButton *)btn {
+    [_backgroudSettingView removeFromSuperview];
+}
+
+- (void)onOpacityChanged:(UISlider *)sender {
+    _dataModel.backgroundOpacity = 1 - sender.value;
+}
+
+- (void)onScaleChanged:(UISlider *)sender {
+    _dataModel.backgroudScale = sender.value;
+}
+
+- (void)onRotationChanged:(UISlider *)sender {
+    _dataModel.backgroundRotation = sender.value * 180 / M_PI;
+}
+
+- (void)horizontalChange:(UITextField *)text {
+    _dataModel.horizontalSpacing = [text.text floatValue];
+}
+
+- (void)verticalChage:(UITextField *)text {
+    _dataModel.verticalSpacing = [text.text floatValue];
+}
+
+#pragma mark - Orientation
+
+- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
+    [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
+    if ([UIDevice currentDevice].orientation == UIDeviceOrientationLandscapeRight) {
+        
+        [_backgroundView mas_remakeConstraints:^(MASConstraintMaker *make) {
+            make.bottom.equalTo(self.view.mas_bottom).offset(-5);
+            make.left.equalTo(self.view.mas_left);
+            make.right.equalTo(self.view.mas_right);
+            make.height.mas_equalTo(70);
+        }];
+        
+        [_backgroundPreView mas_remakeConstraints:^(MASConstraintMaker *make) {
+            make.top.equalTo(self.view.mas_top).offset(43.6);
+            make.left.equalTo(self.view.mas_left);
+            make.right.equalTo(self.view.mas_right);
+            make.bottom.equalTo(self.backgroundView.mas_top);
+        }];
+        
+        [_backgroundPreView.documentView mas_remakeConstraints:^(MASConstraintMaker *make) {
+            make.top.equalTo(self.backgroundPreView.mas_top);
+            make.bottom.equalTo(self.backgroundPreView.mas_bottom);
+            make.centerX.equalTo(self.backgroundPreView.mas_centerX);
+            make.width.mas_equalTo(233);
+        }];
+        
+        [_drawBackgroundView mas_remakeConstraints:^(MASConstraintMaker *make) {
+            make.top.equalTo(self.backgroundPreView.documentView.mas_top);
+            make.bottom.equalTo(self.backgroundPreView.documentView.mas_bottom);
+            make.left.equalTo(self.backgroundPreView.documentView.mas_left);
+            make.right.equalTo(self.backgroundPreView.documentView.mas_right);
+        }];
+        [_drawImageView mas_remakeConstraints:^(MASConstraintMaker *make) {
+            make.top.equalTo(self.backgroundPreView.documentView.mas_top);
+            make.bottom.equalTo(self.backgroundPreView.documentView.mas_bottom);
+            make.left.equalTo(self.backgroundPreView.documentView.mas_left);
+            make.right.equalTo(self.backgroundPreView.documentView.mas_right);
+        }];
+    } else if ([UIDevice currentDevice].orientation == UIDeviceOrientationPortrait) {
+        
+        [_backgroundView mas_remakeConstraints:^(MASConstraintMaker *make) {
+            make.bottom.equalTo(self.view.mas_bottom).offset(-20);
+            make.left.equalTo(self.view.mas_left);
+            make.right.equalTo(self.view.mas_right);
+            make.height.mas_equalTo(70);
+        }];
+        
+        [_backgroundPreView mas_remakeConstraints:^(MASConstraintMaker *make) {
+            make.top.equalTo(self.view.mas_top).offset(83.6);
+            make.left.equalTo(self.view.mas_left);
+            make.right.equalTo(self.view.mas_right);
+            make.bottom.equalTo(self.backgroundView.mas_top);
+        }];
+        
+        [_backgroundPreView.documentView mas_remakeConstraints:^(MASConstraintMaker *make) {
+            make.left.equalTo(self.view.mas_left);
+            make.top.equalTo(self.view.mas_top).offset(123.6);
+            make.bottom.equalTo(self.backgroundPreView.mas_bottom).offset(-40);
+            make.width.mas_equalTo(393);
+        }];
+    }
+    
+    [_drawBackgroundView setNeedsDisplay];
+}
+
+#pragma mark - UIImagePickerControllerDelegate
+
+- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<UIImagePickerControllerInfoKey,id> *)info {
+    UIImage *image = info[UIImagePickerControllerOriginalImage];
+    CGSize size;
+    size.width = self.backgroundPreView.documentView.frame.size.width;
+    size.height = self.backgroundPreView.documentView.frame.size.height;
+//    _backgroundPreView.imageView.image = [self imageWithImageSimple:image scaledToSize:size];
+    _dataModel.image = [self imageWithImageSimple:image scaledToSize:_imageSize];
+    [_backgroundPreView.imageView sizeToFit];
+    
+    [picker dismissViewControllerAnimated:YES completion:nil];
+    [_drawBackgroundView setNeedsDisplay];
+}
+
+- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
+    [picker dismissViewControllerAnimated:YES completion:nil];
+}
+
+- (UIImage *)imageWithImageSimple:(UIImage *)image scaledToSize:(CGSize)newSize
+{
+    UIGraphicsBeginImageContext(newSize);
+    [image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
+    UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
+    UIGraphicsEndImageContext();
+    return newImage;
+}
+
+#pragma mark - UITextFieldDelegate
+
+- (BOOL)textFieldShouldReturn:(UITextField *)textField {
+    [textField resignFirstResponder];
+    
+    return YES;
+}
+
+@end

+ 38 - 2
PDFViewer/Controller/CPDFImageViewController.m

@@ -51,6 +51,8 @@
     _shadowWaterLabel = [[UILabel alloc] initWithFrame:CGRectMake(97.5, 143.333, 28, 28)];
 }
 
+#pragma mark - Orientation
+
 - (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
     [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
     
@@ -64,12 +66,26 @@
             make.bottom.equalTo(self.view.mas_bottom).offset(-40);
         }];
         [_imagePreview mas_remakeConstraints:^(MASConstraintMaker *make) {
-            make.top.equalTo(self.view.mas_top).offset(10);
+            make.top.equalTo(self.view.mas_top).offset(0);
             make.right.equalTo(_imageView.mas_left).offset(-5);
             make.left.equalTo(self.view.mas_left).offset(0);
             make.bottom.equalTo(self.view.mas_bottom).offset(0);
         }];
-        
+    
+        if ([_drawView isDescendantOfView:self.view]) {
+            [_drawView mas_remakeConstraints:^(MASConstraintMaker *make) {
+                make.top.equalTo(self.view.mas_top).offset(0);
+                make.right.equalTo(_imageView.mas_left).offset(-5);
+                make.left.equalTo(self.view.mas_left).offset(0);
+                make.bottom.equalTo(self.view.mas_bottom).offset(0);
+            }];
+            [_cliView mas_remakeConstraints:^(MASConstraintMaker *make) {
+                make.top.equalTo(self.view.mas_top).offset(0);
+                make.right.equalTo(_imageView.mas_left).offset(-5);
+                make.left.equalTo(self.view.mas_left).offset(0);
+                make.bottom.equalTo(self.view.mas_bottom).offset(0);
+            }];
+        }
     } else if ([UIDevice currentDevice].orientation == UIDeviceOrientationPortrait) {
         [_imagePreview mas_remakeConstraints:^(MASConstraintMaker *make) {
             make.top.equalTo(self.view.mas_top).offset(0);
@@ -82,6 +98,26 @@
             make.width.equalTo(_imagePreview.mas_width);
             make.bottom.equalTo(self.view.mas_bottom).offset(0);
         }];
+        
+        if ([_drawView isDescendantOfView:self.view]) {
+            [_drawView mas_remakeConstraints:^(MASConstraintMaker *make) {
+                make.top.equalTo(self.view.mas_top).offset(0);
+                make.width.equalTo(self.view.mas_width);
+                make.bottom.equalTo(self.view.mas_bottom).offset(-205);
+            }];
+            [_cliView mas_remakeConstraints:^(MASConstraintMaker *make) {
+                make.top.equalTo(self.view.mas_top).offset(0);
+                make.width.equalTo(self.view.mas_width);
+                make.bottom.equalTo(self.view.mas_bottom).offset(-205);
+            }];
+        }
+    }
+    
+    if ([_drawView isDescendantOfView:self.view]) {
+        [_drawView setDocumentViewRect:_imagePreview.documentView.frame];
+        [_drawView setWaterLabelRect:_imagePreview.watermarkView.frame];
+        [_drawView setNeedsDisplay];
+        [_cliView setNeedsDisplay];
     }
 }
 

+ 36 - 1
PDFViewer/Controller/CPDFTextViewController.m

@@ -134,6 +134,7 @@
         
         [_textPreview.watermarkLabel sizeToFit];
         [_shadowWaterLabel sizeToFit];
+        
         [_dataModel setWatermarkScale:sender.value / 24];
     }
     
@@ -284,12 +285,27 @@
             make.bottom.equalTo(self.view.mas_bottom).offset(-40);
         }];
         [_textPreview mas_remakeConstraints:^(MASConstraintMaker *make) {
-            make.top.equalTo(self.view.mas_top).offset(10);
+            make.top.equalTo(self.view.mas_top).offset(0);
             make.right.equalTo(_textView.mas_left).offset(-5);
             make.left.equalTo(self.view.mas_left).offset(0);
             make.bottom.equalTo(self.view.mas_bottom).offset(0);
         }];
         
+        if ([_drawView isDescendantOfView:self.view]) {
+            [_drawView mas_remakeConstraints:^(MASConstraintMaker *make) {
+                make.top.equalTo(self.view.mas_top).offset(0);
+                make.right.equalTo(_textView.mas_left).offset(-5);
+                make.left.equalTo(self.view.mas_left).offset(0);
+                make.bottom.equalTo(self.view.mas_bottom).offset(0);
+            }];
+            [_cliView mas_remakeConstraints:^(MASConstraintMaker *make) {
+                make.top.equalTo(self.view.mas_top).offset(0);
+                make.right.equalTo(_textView.mas_left).offset(-5);
+                make.left.equalTo(self.view.mas_left).offset(0);
+                make.bottom.equalTo(self.view.mas_bottom).offset(0);
+            }];
+        }
+        
     } else if ([UIDevice currentDevice].orientation == UIDeviceOrientationPortrait) {
         [_textPreview mas_remakeConstraints:^(MASConstraintMaker *make) {
             make.top.equalTo(self.view.mas_top).offset(0);
@@ -302,6 +318,25 @@
             make.bottom.equalTo(self.view.mas_bottom).offset(0);
         }];
         
+        if ([_drawView isDescendantOfView:self.view]) {
+            [_drawView mas_remakeConstraints:^(MASConstraintMaker *make) {
+                make.top.equalTo(self.view.mas_top).offset(0);
+                make.width.equalTo(self.view.mas_width);
+                make.bottom.equalTo(self.view.mas_bottom).offset(-205);
+            }];
+            [_cliView mas_remakeConstraints:^(MASConstraintMaker *make) {
+                make.top.equalTo(self.view.mas_top).offset(0);
+                make.width.equalTo(self.view.mas_width);
+                make.bottom.equalTo(self.view.mas_bottom).offset(-205);
+            }];
+        }
+    }
+    
+    if ([_drawView isDescendantOfView:self.view]) {
+        [_drawView setDocumentViewRect:_textPreview.documentView.frame];
+        [_drawView setWaterLabelRect:_textPreview.watermarkLabel.frame];
+        [_drawView setNeedsDisplay];
+        [_cliView setNeedsDisplay];
     }
 }
 

+ 59 - 1
PDFViewer/Controller/CPDFViewController.m

@@ -15,16 +15,19 @@
 #import "CPDFTextView.h"
 #import "CPDFImageView.h"
 #import "CPDFDataModel.h"
+#import "CPDFBackgroundModel.h"
 #import "Masonry.h"
 #import "CPDFAddViewController.h"
+#import "CPDFBackgroundSettingViewController.h"
 
-@interface CPDFViewController () <UIActionSheetDelegate,WaterMarkModelDataDelegate>
+@interface CPDFViewController () <UIActionSheetDelegate,WaterMarkModelDataDelegate,BackgroundDataModelDelegate>
 
 @property (nonatomic,strong) CPDFView *pdfView;
 @property (nonatomic,strong) CPDFDocument *pdfDocument;
 @property (nonatomic,strong) CPDFWatermark *textWatermark;
 @property (nonatomic,strong) CPDFWatermark *imageWatermark;
 @property (nonatomic,strong) CPDFAddViewController *addWaterMarkViewController;
+@property (nonatomic,strong) CPDFBackgroundSettingViewController * addBackgroundViewController;
 @property (nonatomic,strong) UIImage *image;
 @property (nonatomic,assign) CGSize imageSize;
 
@@ -75,12 +78,24 @@
     UIAlertAction *addHeaderfooterAction = [UIAlertAction actionWithTitle:@"Add Headerfooter" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
             NSLog(@"addHeaderfooterAction");
         }];
+    
+    UIAlertAction *addBackgroundAction = [UIAlertAction actionWithTitle:@"Add Background" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
+        self.addBackgroundViewController = [[CPDFBackgroundSettingViewController alloc] initWithDocument:self.pdfDocument];
+        self.addBackgroundViewController.delegate = self;
+        
+        [self.navigationController pushViewController:self.addBackgroundViewController animated:YES];
+        
+        }];
+    
     UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
             
         }];
+    
     [alertController addAction:addWatermarkAction];
     [alertController addAction:addHeaderfooterAction];
+    [alertController addAction:addBackgroundAction];
     [alertController addAction:cancelAction];
+    
     [self presentViewController:alertController animated:YES completion:nil];
 }
 
@@ -162,4 +177,47 @@
     [self.view addSubview:_pdfView];
 }
 
+#pragma mark - BackgroundDataModelDelegate
+
+- (void)changeBackgroundModel:(CPDFBackgroundModel *)dataModel {
+    CPDFBackground *pageBackground = [_pdfDocument background];
+    
+    pageBackground.color = dataModel.backgroundColor;
+    pageBackground.scale = dataModel.backgroudScale;
+    pageBackground.rotation = dataModel.backgroundRotation;
+    pageBackground.opacity = dataModel.backgroundOpacity;
+    pageBackground.pageString = dataModel.pageString;
+    pageBackground.xOffset = dataModel.horizontalSpacing;
+    pageBackground.yOffset = dataModel.verticalSpacing;
+    pageBackground.isAllowsView = YES;
+    pageBackground.isAllowsPrint = YES;
+    [pageBackground setImage:dataModel.image];
+    
+    [pageBackground update];
+    
+    NSURL *url = [NSURL fileURLWithPath:_path];
+    [_pdfView.document writeToURL:url];
+    
+    _pdfDocument = [[CPDFDocument alloc] initWithURL:url];
+    _pdfView = [[CPDFView alloc] initWithFrame:self.view.bounds];
+    _pdfView.document = _pdfDocument;
+    _pdfView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
+    [self.view addSubview:_pdfView];
+}
+
+- (void)deleteBackgroundModel {
+    CPDFBackground *pageBackground = [_pdfDocument background];
+    
+    [pageBackground clear];
+    
+    NSURL *url = [NSURL fileURLWithPath:_path];
+    [_pdfView.document writeToURL:url];
+    
+    _pdfDocument = [[CPDFDocument alloc] initWithURL:url];
+    _pdfView = [[CPDFView alloc] initWithFrame:self.view.bounds];
+    _pdfView.document = _pdfDocument;
+    _pdfView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
+    [self.view addSubview:_pdfView];
+}
+
 @end

+ 29 - 0
PDFViewer/Model/CPDFBackgroundModel.h

@@ -0,0 +1,29 @@
+//
+//  CPDFBackgroundModel.h
+//  PDFViewer
+//
+//  Created by kdanmobile_2 on 2023/1/4.
+//
+
+#import <Foundation/Foundation.h>
+#import <UIKit/UIKit.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface CPDFBackgroundModel : NSObject
+
+@property (nonatomic,strong) UIColor *backgroundColor;
+
+@property (nonatomic,assign) CGFloat backgroundOpacity;
+@property (nonatomic,assign) CGFloat backgroudScale;
+@property (nonatomic,assign) NSString *pageString;
+@property (nonatomic,assign) CGFloat tx;
+@property (nonatomic,assign) CGFloat ty;
+@property (nonatomic,assign) CGFloat backgroundRotation;
+@property (nonatomic,strong) UIImage *image;
+@property (nonatomic,assign) CGFloat verticalSpacing;
+@property (nonatomic,assign) CGFloat horizontalSpacing;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 12 - 0
PDFViewer/Model/CPDFBackgroundModel.m

@@ -0,0 +1,12 @@
+//
+//  CPDFBackgroundModel.m
+//  PDFViewer
+//
+//  Created by kdanmobile_2 on 2023/1/4.
+//
+
+#import "CPDFBackgroundModel.h"
+
+@implementation CPDFBackgroundModel
+
+@end

+ 20 - 0
PDFViewer/View/CPDFBackgroundPreview.h

@@ -0,0 +1,20 @@
+//
+//  CPDFBackgroundPreview.h
+//  PDFViewer
+//
+//  Created by kdanmobile_2 on 2023/1/2.
+//
+
+#import <UIKit/UIKit.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface CPDFBackgroundPreview : UIView
+
+@property (nonatomic,strong) UIImageView *documentView;
+@property (nonatomic,strong) UIImageView *imageView;
+@property (nonatomic,strong) UIColor *tintColor;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 43 - 0
PDFViewer/View/CPDFBackgroundPreview.m

@@ -0,0 +1,43 @@
+//
+//  CPDFBackgroundPreview.m
+//  PDFViewer
+//
+//  Created by kdanmobile_2 on 2023/1/2.
+//
+
+#import "CPDFBackgroundPreview.h"
+#import "Masonry.h"
+
+@implementation CPDFBackgroundPreview
+
+- (instancetype)initWithFrame:(CGRect)frame {
+    self = [super initWithFrame:frame];
+    
+    if (self) {
+        _documentView = [[UIImageView alloc] init];
+        [self addSubview:_documentView];
+        
+        _imageView = [[UIImageView alloc] init];
+        [self addSubview:_imageView];
+        
+        self.backgroundColor = [UIColor systemGray5Color];
+    }
+    
+    return self;
+}
+
+- (void)drawRect:(CGRect)rect {
+    [super drawRect:rect];
+    
+    _imageView.layer.borderColor = UIColor.blueColor.CGColor;
+    _imageView.layer.borderWidth = 1;
+    [_imageView sizeToFit];
+    _imageView.contentMode = UIViewContentModeScaleAspectFit;
+    
+    CGRect frame = _imageView.frame;
+    frame.origin = CGPointMake(_documentView.bounds.size.width / 2 - _imageView.frame.size.width / 2, _documentView.bounds.size.height / 2 - _imageView.frame.size.height / 2);
+    
+    _imageView.frame = frame;
+}
+
+@end

+ 32 - 0
PDFViewer/View/CPDFBackgroundSettingView.h

@@ -0,0 +1,32 @@
+//
+//  CPDFBackgroundSettingView.h
+//  PDFViewer
+//
+//  Created by kdanmobile_2 on 2023/1/2.
+//
+
+#import <UIKit/UIKit.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface CPDFBackgroundSettingView : UIView
+
+@property (nonatomic,strong) UILabel *titleLabel;
+@property (nonatomic,strong) UISlider *scaleSlider;
+@property (nonatomic,strong) UISlider *opacitySlider;
+@property (nonatomic,strong) UISlider *rotationSlider;
+@property (nonatomic,strong) UILabel *rotationlabel;
+@property (nonatomic,strong) UILabel *textLabel;
+@property (nonatomic,strong) UILabel *opacityLabel;
+@property (nonatomic,strong) UILabel *rangeLabel;
+@property (nonatomic,strong) UITextField *verticalField;
+@property (nonatomic,strong) UITextField *horizontalField;
+@property (nonatomic,strong) UILabel *verticalLabel;
+@property (nonatomic,strong) UILabel *horizontalLabel;
+@property (nonatomic,strong) UIButton *pageBtn;
+@property (nonatomic,strong) UIButton *doneBtn;
+@property (nonatomic,strong) UIButton *cancelBtn;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 163 - 0
PDFViewer/View/CPDFBackgroundSettingView.m

@@ -0,0 +1,163 @@
+//
+//  CPDFBackgroundSettingView.m
+//  PDFViewer
+//
+//  Created by kdanmobile_2 on 2023/1/2.
+//
+
+#import "CPDFBackgroundSettingView.h"
+#import "Masonry.h"
+
+@implementation CPDFBackgroundSettingView
+
+- (instancetype)initWithFrame:(CGRect)frame {
+    self = [super initWithFrame:frame];
+    if (self) {
+        _opacitySlider = [[UISlider alloc] init];
+        _scaleSlider = [[UISlider alloc] init];
+        _rotationSlider = [[UISlider alloc] init];
+        
+        [self addSubview:_opacitySlider];
+        [self addSubview:_scaleSlider];
+        [self addSubview:_rotationSlider];
+        
+        _rotationlabel = [[UILabel alloc] init];
+        _rangeLabel = [[UILabel alloc] init];
+        _textLabel = [[UILabel alloc] init];
+        _opacityLabel = [[UILabel alloc] init];
+        _titleLabel = [[UILabel alloc] init];
+        
+        [self addSubview:_textLabel];
+        [self addSubview:_opacityLabel];
+        [self addSubview:_rangeLabel];
+        [self addSubview:_rotationlabel];
+        [self addSubview:_titleLabel];
+        
+        _verticalField = [[UITextField alloc] init];
+        _verticalField.borderStyle = UITextBorderStyleRoundedRect;
+        _verticalLabel = [[UILabel alloc] init];
+        _horizontalField = [[UITextField alloc] init];
+        _horizontalField.borderStyle = UITextBorderStyleRoundedRect;
+        _horizontalLabel = [[UILabel alloc] init];
+        _pageBtn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
+        
+        [self addSubview:_verticalLabel];
+        [self addSubview:_verticalField];
+        [self addSubview:_horizontalField];
+        [self addSubview:_horizontalLabel];
+        [self addSubview:_pageBtn];
+        
+        _doneBtn = [[UIButton alloc] init];
+        _cancelBtn = [[UIButton alloc] init];
+        
+        [self addSubview:_doneBtn];
+        [self addSubview:_cancelBtn];
+        
+        self.backgroundColor = [UIColor systemGray6Color];
+    }
+    
+    return self;
+}
+
+- (void)drawRect:(CGRect)rect {
+    
+    _titleLabel.frame = CGRectMake(5, 5, 180, 50);
+    _rangeLabel.frame = CGRectMake(5, 165, 150, 30);
+    _textLabel.frame = CGRectMake(5, 95, 90, 30);
+    _opacityLabel.frame = CGRectMake(5, 60, 90, 30);
+    _rotationlabel.frame = CGRectMake(5, 130, 90, 30);
+    
+    [self addConstraint];
+    [self assignData];
+}
+
+- (void)addConstraint {
+    [_verticalField mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.right.equalTo(self.mas_right).offset(-15);
+        make.top.equalTo(self.pageBtn.mas_bottom).offset(10);
+        make.width.equalTo(@80);
+        make.height.equalTo(@30);
+    }];
+    [_verticalLabel mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.right.equalTo(self.mas_right).offset(-95);
+        make.top.equalTo(self.pageBtn.mas_bottom).offset(10);
+        make.width.equalTo(@20);
+        make.height.equalTo(@30);
+    }];
+    [_horizontalField mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.left.equalTo(self.mas_left).offset(25);
+        make.top.equalTo(self.pageBtn.mas_bottom).offset(10);
+        make.width.equalTo(@80);
+        make.height.equalTo(@30);
+    }];
+    [_horizontalLabel mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.left.equalTo(self.mas_left).offset(5);
+        make.top.equalTo(self.pageBtn.mas_bottom).offset(10);
+        make.width.equalTo(@20);
+        make.height.equalTo(@30);
+    }];
+    [_scaleSlider mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.right.equalTo(self.mas_right).offset(-15);
+        make.left.equalTo(_textLabel.mas_right).offset(0);
+        make.top.equalTo(self.mas_top).offset(95);
+        make.height.equalTo(@30);
+    }];
+    [_opacitySlider mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.right.equalTo(self.mas_right).offset(-15);
+        make.left.equalTo(_opacityLabel.mas_right).offset(0);
+        make.top.equalTo(self.mas_top).offset(60);
+        make.height.equalTo(@30);
+    }];
+    [_rotationSlider mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.right.equalTo(self.mas_right).offset(-15);
+        make.left.equalTo(_rotationlabel.mas_right).offset(0);
+        make.top.equalTo(_scaleSlider.mas_bottom).offset(5);
+    }];
+    
+    [_pageBtn mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.right.equalTo(self.mas_right).offset(-15);
+        make.top.equalTo(self.rotationSlider.mas_bottom).offset(5);
+        make.left.equalTo(_rangeLabel.mas_right);
+        make.height.equalTo(@35);
+    }];
+    
+    [_doneBtn mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.right.equalTo(self.mas_right).offset(-15);
+        make.top.equalTo(_horizontalField.mas_bottom).offset(25);
+        make.height.mas_equalTo(30);
+        make.width.mas_equalTo(80);
+    }];
+    
+    [_cancelBtn mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.right.equalTo(self.mas_right).offset(-110);
+        make.top.equalTo(_horizontalField.mas_bottom).offset(25);
+        make.height.mas_equalTo(30);
+        make.width.mas_equalTo(80);
+    }];
+}
+
+- (void)assignData {
+    _rangeLabel.text = @"Page Range";
+    _rangeLabel.font = [UIFont systemFontOfSize:15];
+    _titleLabel.text = @"Background Edit";
+    _rotationlabel.text = @"Rotation";
+    _textLabel.text = @"Scale";
+    _opacityLabel.text = @"Opacity";
+    _verticalLabel.text = @"Y:";
+    _horizontalLabel.text = @"X:";
+    
+    _scaleSlider.minimumValue = 0.2;
+    _scaleSlider.maximumValue = 1;
+    _scaleSlider.value = 1;
+    
+    _rotationSlider.minimumValue = 0;
+    _rotationSlider.maximumValue = M_PI;
+    
+    [_pageBtn setTitle:@"Page Range" forState:UIControlStateNormal];
+    [_doneBtn setTitle:@"Done" forState:UIControlStateNormal];
+    [_doneBtn setTitleColor:UIColor.systemBlueColor forState:UIControlStateNormal];
+    [_cancelBtn setTitle:@"Cancel" forState:UIControlStateNormal];
+    [_cancelBtn setTitleColor:UIColor.systemBlueColor forState:UIControlStateNormal];
+}
+
+@end

+ 22 - 0
PDFViewer/View/CPDFBackgroundView.h

@@ -0,0 +1,22 @@
+//
+//  CPDFBackgroundView.h
+//  PDFViewer
+//
+//  Created by kdanmobile_2 on 2023/1/2.
+//
+
+#import <UIKit/UIKit.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface CPDFBackgroundView : UIView
+
+@property (nonatomic,strong) UIButton *colorBtn;
+@property (nonatomic,strong) UILabel *colorLabel;
+@property (nonatomic,strong) UIButton *selectBtn;
+@property (nonatomic,strong) UILabel *imageLabel;
+@property (nonatomic,strong) NSMutableArray *colorArray;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 93 - 0
PDFViewer/View/CPDFBackgroundView.m

@@ -0,0 +1,93 @@
+//
+//  CPDFBackgroundView.m
+//  PDFViewer
+//
+//  Created by kdanmobile_2 on 2023/1/2.
+//
+
+#define KBUTTON_WIDTH 28
+#define KBUTTON_HEIGHT 28
+
+#import "CPDFBackgroundView.h"
+#import "Masonry.h"
+
+@implementation CPDFBackgroundView
+
+- (instancetype)initWithFrame:(CGRect)frame {
+    self = [super initWithFrame:frame];
+    
+    if (self) {
+        _imageLabel = [[UILabel alloc] init];
+        [self addSubview:_imageLabel];
+        
+        _selectBtn = [[UIButton alloc] init];
+        [self addSubview:_selectBtn];
+        
+        _colorLabel = [[UILabel alloc] init];
+        [self addSubview:_colorLabel];
+        
+        _colorArray = [NSMutableArray array];
+        for (NSInteger i = 0; i < 8; ++i) {
+            _colorBtn = [UIButton buttonWithType:UIButtonTypeSystem];
+            [_colorArray addObject:_colorBtn];
+            [self addSubview:_colorBtn];
+        }
+    }
+    
+    return self;
+}
+
+- (void)drawRect:(CGRect)rect {
+    [super drawRect:rect];
+    
+    _colorLabel.frame = CGRectMake(10, 5, 50, 30);
+    _colorLabel.text = @"Color";
+    _imageLabel.frame = CGRectMake(10, 40, 150, 30);
+    _imageLabel.text = @"Image";
+    
+    for (NSInteger i = 0; i < _colorArray.count; i++) {
+        [[[self colorArray][i] layer] setCornerRadius:KBUTTON_WIDTH / 2];
+        [[[self colorArray][i] layer] setMasksToBounds:YES];
+        [[_colorArray[i] layer] setBorderWidth:0.5f];
+        [[_colorArray[i] layer] setBorderColor:UIColor.systemGray4Color.CGColor];
+    }
+    
+    [_colorArray[0] setBackgroundColor:[UIColor redColor]];
+    [_colorArray[1] setBackgroundColor:[UIColor orangeColor]];
+    [_colorArray[2] setBackgroundColor:[UIColor yellowColor]];
+    [_colorArray[3] setBackgroundColor:[UIColor greenColor]];
+    [_colorArray[4] setBackgroundColor:[UIColor blueColor]];
+    [_colorArray[5] setBackgroundColor:[UIColor brownColor]];
+    [_colorArray[6] setBackgroundColor:[UIColor purpleColor]];
+    [_colorArray[7] setBackgroundColor:[UIColor whiteColor]];
+    
+    _selectBtn.layer.borderWidth = 1.0;
+    _selectBtn.layer.borderColor = UIColor.systemGray4Color.CGColor;
+    [_selectBtn setTitle:@"Select Image" forState:UIControlStateNormal];
+    [_selectBtn setTitleColor:UIColor.blackColor forState:UIControlStateNormal];
+    _selectBtn.layer.cornerRadius = 7;
+    
+    [self addConstraint];
+}
+ 
+- (void)addConstraint {
+    NSInteger offset = 10;
+    for (NSInteger i = 0; i < _colorArray.count; ++i) {
+        [_colorArray[i] mas_makeConstraints:^(MASConstraintMaker *make) {
+            make.right.equalTo(self.mas_right).offset( - offset);
+            make.top.equalTo(self.mas_top).offset(5);
+            make.width.equalTo(@KBUTTON_WIDTH);
+            make.height.equalTo(@KBUTTON_HEIGHT);
+        }];
+        offset += 40;
+    }
+    
+    [_selectBtn mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.right.equalTo(self.mas_right).offset(-15);
+        make.top.equalTo(self.colorLabel.mas_bottom).offset(5);
+        make.width.mas_equalTo(180);
+        make.height.equalTo(@35);
+    }];
+}
+
+@end

+ 19 - 0
PDFViewer/View/CPDFDrawBackgroundView.h

@@ -0,0 +1,19 @@
+//
+//  CPDFDrawBackgroundView.h
+//  PDFViewer
+//
+//  Created by kdanmobile_2 on 2023/1/3.
+//
+
+#import <UIKit/UIKit.h>
+#import "CPDFBackgroundModel.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface CPDFDrawBackgroundView : UIView
+
+@property (nonatomic,strong) CPDFBackgroundModel *dataModel;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 55 - 0
PDFViewer/View/CPDFDrawBackgroundView.m

@@ -0,0 +1,55 @@
+//
+//  CPDFDrawBackgroundView.m
+//  PDFViewer
+//
+//  Created by kdanmobile_2 on 2023/1/3.
+//
+
+#import "CPDFDrawBackgroundView.h"
+
+@implementation CPDFDrawBackgroundView
+
+- (instancetype)initWithFrame:(CGRect)frame {
+    self = [super initWithFrame:frame];
+    
+    if (self) {
+        self.backgroundColor = [UIColor whiteColor];
+    }
+    
+    return self;
+}
+
+- (void)drawRect:(CGRect)rect {
+    [super drawRect:rect];
+    
+    CGContextRef context = UIGraphicsGetCurrentContext();
+    
+    [self showDraw:context];
+}
+
+- (void)showDraw:(CGContextRef)context {
+    CGContextSetFillColorWithColor(context, self.dataModel.backgroundColor.CGColor);
+    
+    CGContextSetAlpha(context, self.dataModel.backgroundOpacity);
+    
+    CGFloat ctm = (self.dataModel.backgroundRotation * M_PI) / 180;
+    CGFloat centerWidth = self.bounds.size.width / 2;
+    CGFloat centerHeigth = self.bounds.size.height / 2;
+    
+    CGContextTranslateCTM(context, self.dataModel.horizontalSpacing, - self.dataModel.verticalSpacing);
+
+    CGContextTranslateCTM(context, centerWidth, centerHeigth);
+    CGContextRotateCTM(context, ctm);
+    
+    CGContextScaleCTM(context, self.dataModel.backgroudScale, self.dataModel.backgroudScale);
+    if (_dataModel.image) {
+        [_dataModel.image drawInRect:CGRectMake(- centerWidth,  - centerHeigth, self.frame.size.width,self.frame.size.height) blendMode:kCGBlendModeNormal alpha:self.dataModel.backgroundOpacity];
+    } else {
+        CGContextFillRect(context, CGRectMake( - centerWidth, - centerHeigth, self.bounds.size.width, self.bounds.size.height));
+    }
+    
+    CGContextRotateCTM(context, -ctm);
+    CGContextTranslateCTM(context, - centerWidth, - centerHeigth);
+}
+
+@end

+ 18 - 0
PDFViewer/View/CPDFDrawImageView.h

@@ -0,0 +1,18 @@
+//
+//  CPDFDrawImageView.h
+//  PDFViewer
+//
+//  Created by kdanmobile_2 on 2023/1/3.
+//
+
+#import <UIKit/UIKit.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface CPDFDrawImageView : UIView
+
+@property (nonatomic,strong) UIImage *image;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 76 - 0
PDFViewer/View/CPDFDrawImageView.m

@@ -0,0 +1,76 @@
+//
+//  CPDFDrawImageView.m
+//  PDFViewer
+//
+//  Created by kdanmobile_2 on 2023/1/3.
+//
+
+#import "CPDFDrawImageView.h"
+
+@implementation CPDFDrawImageView
+
+- (instancetype)initWithFrame:(CGRect)frame {
+    self = [super initWithFrame:frame];
+    
+    if (self) {
+        self.backgroundColor = [UIColor clearColor];
+    }
+    
+    return self;
+}
+
+- (void)drawRect:(CGRect)rect {
+    CGContextRef context = UIGraphicsGetCurrentContext();
+    
+    [self showDraw:context];
+}
+
+- (void)showDraw:(CGContextRef)context {
+    UIImage *newImage = [self imageToTransparent:_image];
+    
+    [newImage drawInRect:self.bounds blendMode:kCGBlendModeNormal alpha:1.0f];
+}
+
+- (UIImage*) imageToTransparent:(UIImage*) image {
+    const int imageWidth = image.size.width;
+    const int imageHeight = image.size.height;
+    size_t bytesPerRow = imageWidth * 4;
+    uint32_t *rgbImageBuf = (uint32_t *)malloc(bytesPerRow * imageHeight);
+    
+    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
+    CGContextRef context = CGBitmapContextCreate(rgbImageBuf, imageWidth, imageHeight, 8, bytesPerRow, colorSpace
+                                                 , kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipLast);
+    
+    CGContextDrawImage(context, CGRectMake(0, 0, imageWidth, imageHeight), image.CGImage);
+    
+    int pixelNum = imageWidth * imageHeight;
+    uint32_t* pCurPtr = rgbImageBuf;
+    for (int i = 0; i < pixelNum; i++, pCurPtr++)
+    {
+        if ((*pCurPtr & 0x65815A00) == 0x65815a00)
+        {
+            uint8_t* ptr = (uint8_t*)pCurPtr;
+            ptr[0] = 0;
+        }
+    }
+
+    CGDataProviderRef dataProvider =CGDataProviderCreateWithData(NULL, rgbImageBuf, bytesPerRow * imageHeight, ProviderReleaseData);
+    CGImageRef imageRef = CGImageCreate(imageWidth, imageHeight,8, 32, bytesPerRow, colorSpace,
+                                        kCGImageAlphaLast |kCGBitmapByteOrder32Little, dataProvider,
+                                        NULL, true,kCGRenderingIntentDefault);
+    CGDataProviderRelease(dataProvider);
+
+    UIImage* resultUIImage = [UIImage imageWithCGImage:imageRef];
+
+    CGImageRelease(imageRef);
+    CGContextRelease(context);
+    CGColorSpaceRelease(colorSpace);
+
+    return resultUIImage;
+}
+
+ void ProviderReleaseData(void *info, const void *data, size_t size) {
+     free((void *) data);
+}
+
+@end

+ 21 - 0
PDFViewer/View/UIImage+TintColor.h

@@ -0,0 +1,21 @@
+//
+//  UIImage+TintColor.h
+//  PDFViewer
+//
+//  Created by kdanmobile_2 on 2023/1/3.
+//
+
+#import <UIKit/UIKit.h>
+#import "CPDFDataModel.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface UIImage (TintColor)
+
+@property (nonatomic,strong) CPDFDataModel *datamodel;
+
+- (UIImage *)imageWithTintColor:(UIColor *)tintColor;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 51 - 0
PDFViewer/View/UIImage+TintColor.m

@@ -0,0 +1,51 @@
+//
+//  UIImage+TintColor.m
+//  PDFViewer
+//
+//  Created by kdanmobile_2 on 2023/1/3.
+//
+
+#import "UIImage+TintColor.h"
+
+@implementation UIImage (TintColor)
+
+- (UIImage *)imageWithTintColor:(UIColor *)tintColor {
+    UIGraphicsBeginImageContextWithOptions(self.size, NO, 0.0f);
+
+    [tintColor setFill];
+    
+    CGRect bounds = CGRectMake(0, 0, self.size.width, self.size.height);
+    UIRectFill(bounds);
+    
+    [self drawInRect:bounds blendMode:kCGBlendModeDestinationIn alpha:0.3f];
+    
+    [self drawInRect:bounds blendMode:kCGBlendModeOverlay alpha:2.0f];
+    
+    UIImage *tintImage = UIGraphicsGetImageFromCurrentImageContext();
+    UIGraphicsEndImageContext();
+    
+    return tintImage;
+}
+
+- (void)setDatamodel:(CPDFDataModel *)datamodel {
+    self.datamodel = datamodel;
+}
+
+- (CPDFDataModel *)datamodel {
+    return self.datamodel;
+}
+
+- (CGRect)rotateRect:(CGRect)rect {
+    CGAffineTransform tranform_1 = CGAffineTransformMakeTranslation(- self.size.width / 2,  - self.size.height / 2);
+    CGRect rect_1 = CGRectApplyAffineTransform(rect,tranform_1);
+    
+    CGAffineTransform tranform_2 = CGAffineTransformMakeRotation(M_PI / 8);
+    CGRect rect_2 = CGRectApplyAffineTransform(rect_1,tranform_2);
+    
+    CGAffineTransform tranform_3 = CGAffineTransformMakeTranslation(- self.size.width / 2,  - self.size.height / 2);
+    CGRect rect_3 = CGRectApplyAffineTransform(rect_2,tranform_3);
+    
+    return rect_3;
+}
+
+@end