SignatureViewController.m 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. //
  2. // SignatureViewController.m
  3. // RedAnt ERP Mobile
  4. //
  5. // Created by Ray on 14-8-7.
  6. // Copyright (c) 2014年 United Software Applications, Inc. All rights reserved.
  7. //
  8. #define INTNUMBERS @"0123456789\n"
  9. #import "SignatureViewController.h"
  10. #import "RAUtils.h"
  11. //#import "const.h"
  12. @interface SignatureViewController ()
  13. @end
  14. @implementation SignatureViewController
  15. + (instancetype)ra_signatureViewControllerWithCompletion:(void (^)(UIImage *))blk {
  16. SignatureViewController * vc =[ [UIStoryboard storyboardWithName:@"signature"
  17. bundle:[NSBundle mainBundle]]
  18. instantiateViewControllerWithIdentifier:@"SignatureViewController"];
  19. vc.onReturnImg = blk;
  20. return vc;
  21. }
  22. - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
  23. {
  24. self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
  25. if (self) {
  26. // Custom initialization
  27. }
  28. return self;
  29. }
  30. -(BOOL) shouldAutorotate
  31. {
  32. return false;
  33. }
  34. - (void)onBackClick:(UIButton *)sender {
  35. [self.navigationController popViewControllerAnimated:FALSE];
  36. }
  37. - (void)viewDidLoad
  38. {
  39. [super viewDidLoad];
  40. self.navigationItem.title = self.title;
  41. // ==========================================
  42. // 1. 導航欄外觀修復 (防止變黑/透明)
  43. // ==========================================
  44. if (@available(iOS 15.0, *)) {
  45. UINavigationBarAppearance *appearance = [[UINavigationBarAppearance alloc] init];
  46. [appearance configureWithOpaqueBackground]; // 強制不透明
  47. appearance.backgroundColor = [UIColor whiteColor]; // 背景白
  48. appearance.titleTextAttributes = @{NSForegroundColorAttributeName: [UIColor blackColor]};
  49. self.navigationController.navigationBar.standardAppearance = appearance;
  50. self.navigationController.navigationBar.scrollEdgeAppearance = appearance;
  51. } else {
  52. self.navigationController.navigationBar.barTintColor = [UIColor whiteColor];
  53. self.navigationController.navigationBar.translucent = NO;
  54. }
  55. // ==========================================
  56. // 2. 視圖佈局修復 (防止黑邊)
  57. // ==========================================
  58. // 禁止頂部延伸(避開導航欄),允許其他方向延伸(鋪滿底部)
  59. self.edgesForExtendedLayout = UIRectEdgeAll & ~UIRectEdgeTop;
  60. // 設置底色為白,防止加載時透出黑色
  61. self.view.backgroundColor = [UIColor whiteColor];
  62. // ==========================================
  63. // 3. 初始化畫板 (使用 Auto Layout)
  64. // ==========================================
  65. if(self.linewidth == 0)
  66. self.linewidth = 5;
  67. EAGLContext *context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
  68. // 【修改重點】初始化傳 CGRectZero,並關閉 Autoresizing 轉換
  69. self.signatureView = [[SignatureView alloc] initWithFrame:CGRectZero context:context];
  70. self.signatureView.translatesAutoresizingMaskIntoConstraints = NO;
  71. self.signatureView.backgroundColor = [UIColor whiteColor];
  72. // 設置邊框樣式
  73. self.signatureView.layer.borderColor = [UIColor darkGrayColor].CGColor;
  74. self.signatureView.layer.borderWidth = 1.0;
  75. [self.view addSubview:self.signatureView];
  76. // 【修改重點】添加約束,將畫板強行釘死在父視圖的四個邊緣
  77. // 這樣無論屏幕多長,它都會自動拉伸填滿,徹底消除底部黑邊
  78. [NSLayoutConstraint activateConstraints:@[
  79. [self.signatureView.topAnchor constraintEqualToAnchor:self.view.topAnchor],
  80. [self.signatureView.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor],
  81. [self.signatureView.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
  82. [self.signatureView.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor]
  83. ]];
  84. // ==========================================
  85. // 4. 導航欄按鈕設置 (保持原有邏輯)
  86. // ==========================================
  87. UIBarButtonItem *closeButton = [[UIBarButtonItem alloc] initWithImage:[[UIImage imageNamed:@"back"] imageWithRenderingMode:UIImageRenderingModeAutomatic]
  88. style:UIBarButtonItemStylePlain
  89. target:self
  90. action:@selector(onBackClick:)];
  91. self.navigationItem.leftBarButtonItem = closeButton;
  92. UIBarButtonItem *clearBtn = [[UIBarButtonItem alloc] initWithImage:[[UIImage imageNamed:@"clear"] imageWithRenderingMode:UIImageRenderingModeAutomatic]
  93. style:UIBarButtonItemStylePlain
  94. target:self
  95. action:@selector(onClear:)];
  96. UIBarButtonItem *doneBtn = [[UIBarButtonItem alloc] initWithImage:[[UIImage imageNamed:@"save"] imageWithRenderingMode:UIImageRenderingModeAutomatic]
  97. style:UIBarButtonItemStylePlain
  98. target:self
  99. action:@selector(onDone:)];
  100. UIBarButtonItem *settingBtn = [[UIBarButtonItem alloc] initWithImage:[[UIImage imageNamed:@"signature_setting"] imageWithRenderingMode:UIImageRenderingModeAutomatic]
  101. style:UIBarButtonItemStylePlain
  102. target:self
  103. action:@selector(onSetting:)];
  104. if (UIDevice.currentDevice.userInterfaceIdiom == UIUserInterfaceIdiomPhone) {
  105. self.navigationItem.rightBarButtonItems = [NSArray arrayWithObjects:doneBtn, clearBtn, nil];
  106. } else {
  107. self.navigationItem.rightBarButtonItems = [NSArray arrayWithObjects:doneBtn, clearBtn, settingBtn, nil];
  108. }
  109. [self.navigationController.navigationBar layoutIfNeeded];
  110. // 設置畫筆參數
  111. [self.signatureView setLineWidth:self.linewidth];
  112. self.signatureView.foregroundLineColor = [UIColor colorWithRed:0.204 green:0.596 blue:0.859 alpha:1.000];
  113. }
  114. - (UIImage *)addImage:(UIImage *)image size:(CGSize )size {
  115. UIGraphicsBeginImageContext(size);
  116. UIImage *cleanImage = UIGraphicsGetImageFromCurrentImageContext();
  117. // Draw image1
  118. [image drawInRect:CGRectMake((size.width-image.size.width)/2,(size.height-image.size.height)/2, image.size.width, image.size.height)];
  119. // Draw image2
  120. [cleanImage drawInRect:CGRectMake(0, 0, cleanImage.size.width, cleanImage.size.height)];
  121. UIImage *resultingImage = UIGraphicsGetImageFromCurrentImageContext();
  122. UIGraphicsEndImageContext();
  123. return resultingImage;
  124. }
  125. - (void)onSetting:(UIButton *)sender {
  126. UIAlertController *alertControl = [UIAlertController alertControllerWithTitle:@"Change line width" message:nil preferredStyle:UIAlertControllerStyleAlert];
  127. //block代码块取代了delegate
  128. [alertControl addTextFieldWithConfigurationHandler:^(UITextField *textField) {
  129. textField.text = [NSString stringWithFormat:@"%d",self.linewidth];
  130. textField.keyboardType=UIKeyboardTypeNumberPad;
  131. textField.delegate = self;
  132. }];
  133. UIAlertAction *actionOne = [UIAlertAction actionWithTitle:@"Save" style:UIAlertActionStyleDestructive handler:^(UIAlertAction *action) {
  134. if(self.linewidth>16||self.linewidth<1)
  135. {
  136. int newlinewidth = 0;
  137. if(self.linewidth>16)
  138. {
  139. self.linewidth = 16;
  140. newlinewidth=16;
  141. }
  142. else if(self.linewidth<1)
  143. {
  144. self.linewidth = 1;
  145. newlinewidth=1;
  146. }
  147. [RAUtils message_box:@"Line width should between 1 and 16" message:[NSString stringWithFormat:@"Line width has been set to %d.",newlinewidth] completion:nil];
  148. }
  149. [self.signatureView setLineWidth:self.linewidth];
  150. }];
  151. UIAlertAction *alertthree = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
  152. // DebugLog(@"Cancel");
  153. }];
  154. [alertControl addAction:actionOne];
  155. [alertControl addAction:alertthree];
  156. //UIAlertControllerStyle类型为UIAlertControllerStyleAlert可以添加addTextFieldWithConfigurationHandler:^(UITextField *textField)
  157. [self presentViewController:alertControl animated:YES completion:nil];
  158. }
  159. - (void)onDone:(UIButton *)sender {
  160. DebugLog(@"onDone");
  161. UIImage* img = [self.signatureView signatureImage];
  162. // return ;
  163. // CGSize imgsize = img.size;
  164. NSData* data = [self.signatureView signatureData];
  165. if (self.Signaturedelegate && [self.Signaturedelegate respondsToSelector:@selector(SignatureVCReturnImage:indexPath:)]) {
  166. [self.Signaturedelegate SignatureVCReturnImage:img indexPath:self.indexPath];
  167. }
  168. if (self.Signaturedelegate && [self.Signaturedelegate respondsToSelector:@selector(SignatureVCReturnData:indexPath:)]) {
  169. [self.Signaturedelegate SignatureVCReturnData:data indexPath:self.indexPath];
  170. }
  171. [self.navigationController popViewControllerAnimated:true];
  172. if(self.onReturnImg)
  173. self.onReturnImg(img);
  174. // [self.aBNewPersonNav dismissViewControllerAnimated:true completion:^{
  175. // ;
  176. // }];
  177. }
  178. - (void)onClear:(UIButton *)sender {
  179. [self.signatureView clear];
  180. }
  181. - (void)didReceiveMemoryWarning
  182. {
  183. [super didReceiveMemoryWarning];
  184. // Dispose of any resources that can be recreated.
  185. }
  186. #pragma mark textField delegate
  187. -(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
  188. NSCharacterSet *cs;
  189. cs = [[NSCharacterSet characterSetWithCharactersInString:INTNUMBERS]invertedSet];
  190. NSString *filtered = [[string componentsSeparatedByCharactersInSet:cs]componentsJoinedByString:@""];
  191. BOOL canChange = [string isEqualToString:filtered];
  192. return canChange;
  193. }
  194. - (void)textFieldDidEndEditing:(UITextField *)textField
  195. {
  196. self.linewidth = [textField.text intValue];
  197. }
  198. //- (void)textFieldDidBeginEditing:(UITextField *)textField
  199. //{
  200. // DebugLog(@"textField shouldChangeCharactersInRange");
  201. //
  202. // self.lastedit = textField;
  203. // UITableViewCell *cell = (UITableViewCell *) textField.superview.superview;
  204. // self.lastedit_from = [self.editorTable indexPathForCell:cell];
  205. //}
  206. /*
  207. #pragma mark - Navigation
  208. // In a storyboard-based application, you will often want to do a little preparation before navigation
  209. - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
  210. {
  211. // Get the new view controller using [segue destinationViewController].
  212. // Pass the selected object to the new view controller.
  213. }
  214. */
  215. //- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
  216. // self.signatureView.frame = self.view.bounds;
  217. //}
  218. - (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
  219. [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
  220. [coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> _Nonnull context) {
  221. // what ever you want to prepare
  222. } completion:^(id<UIViewControllerTransitionCoordinatorContext> _Nonnull context) {
  223. self.signatureView.frame = self.view.bounds;
  224. }];
  225. }
  226. @end