There was a time not update the blog update today an article on a recent function used in the work, briefly describe: We know that the testers in the test client product, when there is a problem or BUG, had first screenshot of the page, then select an album from the screenshot, add a description into the TD library or directly by e-mail to the developer, in order to facilitate the development of personnel changes, process cumbersome . By introducing the following features, you can easily let the testers when it came to the BUG, shake the device, then automatically capture and save the sandbox application in. After saving the screenshot after the sandbox, you can customize the feedback page of a problem, describe the issue (Description You can use a third-party platforms such as hearing fly voice, to achieve the effect of voice recording), will be sent with the information and description page screenshot to developers (can be e-mail, it can also be sent directly to the background).
Let's look at how the function is implemented.
First, define a category: ShakeAndCutter
UIViewController + ShakeAndCutter.h file Source:
#import <UIKit/UIKit.h>
@interface UIViewController (ShakeAndCutter)
@end
UIViewController + ShakeAndCutter.m file Source:
1 #import "UIViewController+ShakeAndCutter.h" 2 #import <QuartzCore/QuartzCore.h> 3 #import "TestFeedbackViewController.h" 4 5 @implementation UIViewController (ShakeAndCutter) 6 7 - (BOOL)canBecomeFirstResponder 8 { 9 return YES; 10 } 11 12 #pragma mark - 摇一摇动作处理 13 14 - (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event 15 { 16 NSLog(@"began"); 17 } 18 19 - (void)motionCancelled:(UIEventSubtype)motion withEvent:(UIEvent *)event 20 { 21 NSLog(@"cancel"); 22 } 23 24 - (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event 25 { 26 NSLog(@"end"); 27 [self cutterViewToDocument]; 28 29 //This is the feedback from the problem definition page, or go directly to the page message sent by the system 30 TestFeedbackViewController testFeedbackViewController * = [[[TestFeedbackViewController the alloc] initWithNibName: @ " TestFeedbackViewController " the bundle: nil] the autorelease]; 31 is [self.navigationController pushViewController : Animated testFeedbackViewController: YES]; 32 } 33 is 34 is #pragma Mark - processing screenshots 35 36 - ( void ) cutterViewToDocument 37 [ { 38 is the UIWindow screenWindow * = [[sharedApplication the UIApplication] keyWindow]; 39 40 UIGraphicsBeginImageContext(screenWindow.frame.size); 41 [screenWindow.layer renderInContext:UIGraphicsGetCurrentContext()]; 42 UIImage *screenShot = UIGraphicsGetImageFromCurrentImageContext(); 43 UIGraphicsEndImageContext(); 44 45 NSData *screenShotPNG = UIImagePNGRepresentation(screenShot); 46 NSError *error = nil; 47 [screenShotPNG writeToFile:[[NSHomeDirectory() stringByAppendingPathComponent:@"Documents"] stringByAppendingPathComponent:@"error.png"] options:NSAtomicWrite error:&error]; 48 } 49 50 @end
At this point, shake and screenshot function has been completed, then how to use it in the application?
- For IOS6.0 above devices, only you need to project pch introduction header file #import "UIViewController + ShakeAndCutter.h" can ( I IOS6.0.1 , IOS6.1.5 , IOS7.0.6 has been tested on the device ) , after the completion of this test, you only need this line of code or comments can be deleted;
- For IOS6.0 following equipment, the page needs to implement a shake effect, it is possible to add the following code (do not have IOS6.0 following equipment, if any, everyone, to help verify it, thank you very much):
1.viewDidLoad method, add two lines of code:
1 [[UIApplication sharedApplication] setApplicationSupportsShakeToEdit:YES]; 2 [self becomeFirstResponder];
2.viewDidAppear method, add a line:
1 [self becomeFirstResponder];
3.viewDidDisappear method, add a line:
1 [self resignFirstResponder];
Of course, the above features, you can also achieve other effects: for example, the issue of user feedback, etc., can be based on specific application requirements.
Here, the sample code then attach message sent to the function:
MailViewController.h file Source:
1 #import <UIKit/UIKit.h> 2 #import <MessageUI/MessageUI.h> 3 #import<MessageUI/MFMailComposeViewController.h> 4 5 @interface MailViewController : UIViewController<MFMailComposeViewControllerDelegate, 6 MFMessageComposeViewControllerDelegate> 7 { 8 UIButton *shareToMailButton; 9 } 10 11 @end
MailViewController.m file Source:
1 #import "MailViewController.h" 2 #import "Constants.h" 3 4 @interface MailViewController () 5 6 @end 7 8 @implementation MailViewController 9 10 - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 11 { 12 self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; 13 if (self) { 14 // Custom initialization 15 } 16 return self; 17 } 18 19 - (void)viewDidLoad 20 { 21 [super viewDidLoad]; 22 // Do any additional setup after loading the view. 23 24 self.title = @"Bug反馈"; 25 26 shareToMailButton = [self buttonWithFrame:CGRectMake(20, 100, 280, 40) action:@selector(btnClicked:) withTag:1000]; 27 [shareToMailButton setTitle:@"Bug反馈" forState:UIControlStateNormal]; 28 } 29 30 - (void)didReceiveMemoryWarning 31 { 32 [super didReceiveMemoryWarning]; 33 // Dispose of any resources that can be recreated. 34 } 35 36 #pragma mark - 自定义方法 37 38 - (void)btnClicked:(id)sender 39 { 40 UIButton *btnSender = (UIButton *)sender; 41 42 Switch (btnSender.tag) 43 is { 44 is Case 1000 : // share mailbox 45 { 46 is [Self showMailPicker]; 47 BREAK ; 48 } 49 default : 50 BREAK ; 51 is } 52 is } 53 is 54 is / * ****** ************************************************** ********************** 55 * method name: buttonWithFrame: Action: 56 is * function: initialize the page button, and the view to the page 57 * input parameters: 58 * 输出参数: 59 ******************************************************************************/ 60 - (UIButton *)buttonWithFrame:(CGRect)frame action:(SEL)action withTag:(int)tag 61 { 62 UIImage *buttonBackgroundImage = [[UIImage imageNamed:@"button_background.png"] stretchableImageWithLeftCapWidth:5 topCapHeight:5]; 63 UIImage *disabledButtonBackgroundImage = [[UIImage imageNamed:@"button_background_disabled.png"] stretchableImageWithLeftCapWidth:5 topCapHeight:5]; 64 65 UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; 66 button.frame = frame; 67 [button setBackgroundImage:buttonBackgroundImage forState:UIControlStateNormal]; 68 [button setBackgroundImage:disabledButtonBackgroundImage forState:UIControlStateDisabled]; 69 [button setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; 70 [button setTitleColor:[UIColor grayColor] forState:UIControlStateDisabled]; 71 [button addTarget:self action:action forControlEvents:UIControlEventTouchUpInside]; 72 button.tag = tag; 73 [self.view addSubview:button]; 74 75 return button; 76 } 77 78 - (void)showMailPicker 79 { 80 Class mailClass = (NSClassFromString(@"MFMailComposeViewController")); 81 82 if (mailClass !=nil) 83 { 84 if ([mailClass canSendMail]) 85 { 86 [self displayMailComposerSheet]; 87 } 88 else 89 { 90 the UIAlertView * Alert = [[the UIAlertView the alloc] the initWithTitle: @ "" Message: @ " device does not support mail function " the delegate : Self cancelButtonTitle: @ " OK " otherButtonTitles: nil]; 91 is [Alert Show]; 92 [Alert Release ]; 93 } 94 } 95 the else 96 { 97 98 } 99 100 } 101 102 - ( void ) displayMailComposerSheet 103 { 104 * Picker = the MFMailComposeViewController [[the MFMailComposeViewController the alloc] the init]; 105 106 // automatically delegate method called after setting the picker, successful completion or failure of the method 107 picker.mailComposeDelegate = Self; 108 // add topics 109 [picker the setSubject: @ " the Bug feedback " ]; 110 // Add recipient 111 NSArray toRecipients * = [NSArray arrayWithObject: @ " [email protected] " ]; 112 // Note: You can also add more than one recipient, the code shown below : 113 // NSArray toRecipients * = [NSArray arrayWithObjects: @ "[email protected]", @ "[email protected]", nil]; 114 // Add Cc 115 // NSArray ccRecipients * = [NSArray arrayWithObjects: @ "[email protected]", @ "[email protected]", nil]; 1 16 // Add Bcc 117 // NSArray * bccRecipients = [NSArray arrayWithObject: @ "[email protected]"]; 1 18 119 [Picker setToRecipients: toRecipients]; 120 // [Picker setCcRecipients: ccRecipients]; 121 // [Picker setBccRecipients: bccRecipients]; 122 // send pictures attachments (annex other formats can be converted, said NSData are the first type, and then set the appropriate mimeType can, such as txt type @ "text / txt", doc type @ "text / doc", pdf type @ "file / pdf "etc.) 123 * = MyData NSData [NSData dataWithContentsOfFile: [[NSHomeDirectory () stringByAppendingPathComponent: @ " Documents " ] stringByAppendingPathComponent: @ " error.png " ]]; 124 [Picker addAttachmentData: mimeType myData: @ " Image / JPEG " fileName: @ " error .png " ]; 125 NSString emailBody * = [NSString stringWithFormat: @" <P> text does not show all </ P> " ]; 126 127 // write the address of the image directly in the HTML code 128 // NSString * emailBody = [NSString stringWithFormat: @ "<img src='http://p2.so.qhimg.com/t0130e3288d86929b97.jpg' /><p>我分享了图片</p>"]; 129 130 [picker setMessageBody:emailBody isHTML:YES]; 131 [self presentModalViewController:picker animated:YES]; 132 [picker release]; 133 } 134 135 136 - (void)mailComposeController:(MFMailComposeViewController*)controller 137 didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error 138 { 139 switch (result) 140 { 141 case MFMailComposeResultCancelled: 142 NSLog ( @ " the Result: Mail sending canceled " ); // message Send Cancel 143 BREAK ; 144 Case MFMailComposeResultSaved: 145 NSLog ( @ " the Result: Mail saved " ); // message successfully saved 146 BREAK ; 147 Case MFMailComposeResultSent: 148 NSLog ( @ " the Result: sent Mail " ); // message sent successfully 149 BREAK ; 150 Case MFMailComposeResultFailed: 151 NSLog(@"Result: Mail sending failed"); // 邮件发送失败 152 break; 153 default: 154 NSLog(@"Result: Mail not sent"); 155 break; 156 } 157 [self dismissModalViewControllerAnimated:YES]; 158 } 159 160 - (void)messageComposeViewController:(MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult)result 161 { 162 NSLog(@"messageComposeViewController"); 163 } 164 165 @end
Reproduced in: https: //www.cnblogs.com/eagle927183/p/shakeandcutter.html