拍照定制
#pragma mark - - AVCaptureVideoDataOutputSampleBufferDelegate 的方法
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection {
CFDictionaryRef metadataDict = CMCopyDictionaryOfAttachments(NULL,sampleBuffer, kCMAttachmentMode_ShouldPropagate);
NSDictionary *metadata = [[NSMutableDictionary alloc] initWithDictionary:(__bridge NSDictionary*)metadataDict];
CFRelease(metadataDict);
NSDictionary *exifMetadata = [[metadata objectForKey:(NSString *)kCGImagePropertyExifDictionary] mutableCopy];
CGFloat brightnessValue = [[exifMetadata objectForKey:(NSString *)kCGImagePropertyExifBrightnessValue] floatValue];
}
解析二维码
//解析图片中的二维码
+(NSString *)resolvingCodeStrFromImg:(UIImage *)image{
NSString *resultStr = @"";
CIDetector *detector = [CIDetector detectorOfType:CIDetectorTypeQRCode context:nil options:@{CIDetectorAccuracy: CIDetectorAccuracyHigh}];
// 获取识别结果
NSArray *features = [detector featuresInImage:[CIImage imageWithCGImage:image.CGImage]];
if (features.count > 0) {
CIQRCodeFeature *feature = [features objectAtIndex:0];
resultStr = feature.messageString;
}
return resultStr;
}
设置手势优先级
if (value) {
self.myPanGesture.enabled = NO;
[self.myPanGesture requireGestureRecognizerToFail:self.navigationController.interactivePopGestureRecognizer];
}else{
self.myPanGesture.enabled = YES;
[self.navigationController.interactivePopGestureRecognizer requireGestureRecognizerToFail:self.myPanGesture];
return;
}
访问相册权限
- (void)QRCodeScanVC:(UIViewController *)scanVC {
__weak typeof(self) weakSelf = self;
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
if (device) {
AVAuthorizationStatus status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
switch (status) {
case AVAuthorizationStatusNotDetermined: {
[AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
if (granted) {
dispatch_sync(dispatch_get_main_queue(), ^{
[weakSelf.navigationController pushViewController:scanVC animated:YES];
});
NSLog(@"用户第一次同意了访问相机权限 - - %@", [NSThread currentThread]);
} else {
NSLog(@"用户第一次拒绝了访问相机权限 - - %@", [NSThread currentThread]);
}
}];
break;
}
case AVAuthorizationStatusAuthorized: {
[weakSelf.navigationController pushViewController:scanVC animated:YES];
break;
}
case AVAuthorizationStatusDenied: {
NSString *alertStr = [NSString stringWithFormat:@"请去-> [设置 - 隐私 - 相机 - %@] 打开访问开关",currentProjectName()];
UIAlertController *alertC = [UIAlertController alertControllerWithTitle:@"温馨提示" message:alertStr preferredStyle:(UIAlertControllerStyleAlert)];
UIAlertAction *alertA = [UIAlertAction actionWithTitle:@"确定" style:(UIAlertActionStyleDefault) handler:^(UIAlertAction * _Nonnull action) {
}];
[alertC addAction:alertA];
[weakSelf presentViewController:alertC animated:YES completion:nil];
break;
}
case AVAuthorizationStatusRestricted: {
NSLog(@"因为系统原因, 无法访问相册");
break;
}
default:
break;
}
return;
}
NSLog(@"未检测到您的摄像头");
}
文件选择
// 文件选择
-(void)selectDocumentMethodAndCompleteBlock:(void(^)(NSMutableDictionary *mapInfo))completeBlock{
self.documentSelectBlock = completeBlock;
NSArray * arr= @[(__bridge NSString *)kUTTypeContent,
(__bridge NSString *)kUTTypeData,
(__bridge NSString *)kUTTypePackage,
(__bridge NSString *)kUTTypeDiskImage,
@"com.microsoft.powerpoint.ppt",
@"com.microsoft.word.doc",
@"com.microsoft.excel.xls",
@"com.microsoft.powerpoint.pptx",
@"com.microsoft.word.docx",
@"com.microsoft.excel.xlsx",
@"public.avi",
@"public.3gpp",
@"public.mpeg-4",
@"com.compuserve.gif",
@"public.jpeg",
@"public.png",
@"public.plain-text",
@"com.adobe.pdf"];
UIDocumentPickerViewController *documentPickerVC = [[UIDocumentPickerViewController alloc] initWithDocumentTypes:arr inMode:UIDocumentPickerModeOpen];
documentPickerVC.allowsMultipleSelection = NO; // 不允许选择多个
documentPickerVC.delegate = self;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.001 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self presentViewController:documentPickerVC animated:YES completion:nil];
});
}
文件保护
- (void)documentPicker:(UIDocumentPickerViewController *)controller didPickDocumentsAtURLs:(NSArray <NSURL *>*)urls{
BOOL fileUrlAuthozied = [urls.firstObject startAccessingSecurityScopedResource];
if (fileUrlAuthozied) {
//通过文件协调工具来得到新的文件地址,以此得到文件保护功能
NSFileCoordinator *fileCoordinator = [[NSFileCoordinator alloc] init];
NSError *error;
__weak typeof(self) weakSelf = self;
[fileCoordinator coordinateReadingItemAtURL:urls.firstObject options:0 error:&error byAccessor:^(NSURL *newURL) {
//读取文件
NSString *fileName = [newURL lastPathComponent];
NSError *error = nil;
NSData *fileData = [NSData dataWithContentsOfURL:newURL options:NSDataReadingMappedIfSafe error:&error];
if (error) {
//读取出错
} else {
NSLog(@"上传===%@",fileName);
NSMutableDictionary *infoDict = [NSMutableDictionary dictionary];
infoDict[@"name"] = fileName;
infoDict[@"url"] = [newURL absoluteString];
infoDict[@"data"] = fileData;
if (weakSelf.documentSelectBlock) {
weakSelf.documentSelectBlock(infoDict);
}
}
[self dismissViewControllerAnimated:YES completion:NULL];
}];
[urls.firstObject stopAccessingSecurityScopedResource];
} else {
//授权失败
}
}
控制手势应用
-(void)setupBackGesture {
UIPanGestureRecognizer *interactiveTransitionRecognizer;
interactiveTransitionRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(interactiveTransitionRecognizerAction:)];
[interactiveTransitionRecognizer requireGestureRecognizerToFail:self.interactivePopGestureRecognizer];
[self.view addGestureRecognizer:interactiveTransitionRecognizer];
self.interactiveTransitionRecognizer = interactiveTransitionRecognizer;
}
- (void)interactiveTransitionRecognizerAction:(UIPanGestureRecognizer *)gestureRecognizer {
CGPoint translation = [gestureRecognizer translationInView:gestureRecognizer.view];
CGFloat scale = 1 - fabs(translation.x / [UIScreen mainScreen].bounds.size.width);
scale = scale < 0 ? 0 : scale;
switch (gestureRecognizer.state) {
case UIGestureRecognizerStatePossible:
break;
case UIGestureRecognizerStateBegan:{
CGPoint startPoint = [gestureRecognizer locationInView:self.view];
if (startPoint.x<50) {
//1. 设置代理
self.animatedTransition = nil;
self.transitioningDelegate = self.animatedTransition;
self.animatedTransition.gestureRecognizer = gestureRecognizer;
//3.dismiss
[self dismissViewControllerAnimated:YES completion:nil];
}
}
break;
case UIGestureRecognizerStateChanged: {
break;
}
case UIGestureRecognizerStateFailed:
case UIGestureRecognizerStateCancelled:
case UIGestureRecognizerStateEnded: {
self.animatedTransition = nil;
self.animatedTransition.gestureRecognizer = nil;
}
break;
}
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch{
return self.viewControllers.count > 1;
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
return NO;
}
汉字转拼音
//汉字转拼音
+ (NSString *)transformToPinyin:(NSString *)text {
NSMutableString *mutableString = [NSMutableString stringWithString:text];
CFStringTransform((CFMutableStringRef)mutableString, NULL, kCFStringTransformToLatin, false);
mutableString = (NSMutableString *)[mutableString stringByFoldingWithOptions:NSDiacriticInsensitiveSearch locale:[NSLocale currentLocale]];
return [mutableString stringByReplacingOccurrencesOfString:@" " withString:@""];
}
图片摆动动画
//图片左右摆动方法
//view左右摆动
+ (void)shakeHorizontally:(UIView *)taget{
CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"transform.translation.x"];
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
animation.duration = 0.5;
animation.values = @[@(-12), @(12), @(-8), @(8), @(-4), @(4), @(0) ];
[taget.layer addAnimation:animation forKey:@"shake"];
}
监听键盘实现动画
//监听键盘上下
//NSNotification为UIKeyboardWillChangeFrameNotification的通知
+(void)keyboardUp:(UIView *)keyView note:(NSNotification *)note{
// 1.获取键盘的Y值
NSDictionary *dict = note.userInfo;
CGRect keyboardFrame = [dict[UIKeyboardFrameEndUserInfoKey] CGRectValue];
CGFloat keyboardY = keyboardFrame.origin.y;
// 获取动画执行时间
CGFloat duration = [dict[UIKeyboardAnimationDurationUserInfoKey]doubleValue];
// 2.计算需要移动的距离
CGFloat sizeHeight = kWindowHeight - SafeAreaTopHeight;
CGFloat translationY = keyboardY - sizeHeight;
[UIView animateWithDuration:duration delay:0.0 options:7 << 16 animations:^{
// 需要执行动画的代码
keyView.transform = CGAffineTransformMakeTranslation(0, translationY);
} completion:^(BOOL finished) {
// 动画执行完毕执行的代码
}];
}
特殊宏定义
#define init(type,args) \
@property (nonatomic,strong) type *args;
\
\
#define get(type,args) \
-(type *)args{ \
if (!_##args) { \
_##args = [type new]; \
} \
return _##args; \
}
Socket
+(BOOL)SocketTest:(NSURL *)url{
NSString * host = [url host];
NSNumber * port = [url port];
// NSError *error;
// Create socket
int socketFileDescriptor = socket(AF_INET, SOCK_STREAM, 0);
if (-1 == socketFileDescriptor) {
// error = [NSError errorWithDomain:@"Failed to create socket." code:socketFileDescriptor userInfo:nil];
return NO;
}
// Get IP address from host
struct hostent * remoteHostEnt = gethostbyname([host UTF8String]);
if (NULL == remoteHostEnt) {
close(socketFileDescriptor);
// error = [NSError errorWithDomain:@"Unable to resolve the hostname of the warehouse server." code:socketFileDescriptor userInfo:nil];
return NO;
}
struct in_addr * remoteInAddr = (struct in_addr *)remoteHostEnt->h_addr_list[0];
// Set the socket parameters
struct sockaddr_in socketParameters;
socketParameters.sin_family = AF_INET;
socketParameters.sin_addr = *remoteInAddr;
socketParameters.sin_port = htons([port intValue]);
// Connect the socket
int ret = connect(socketFileDescriptor, (struct sockaddr *) &socketParameters, sizeof(socketParameters));
if (-1 == ret) {
close(socketFileDescriptor);
// NSString * errorInfo = [NSString stringWithFormat:@" >> Failed to connect to %@:%@", host, port];
// error = [NSError errorWithDomain:errorInfo code:socketFileDescriptor userInfo:nil];
return NO;
}
NSLog(@" >> Successfully connected to %@:%@", host, port);
// Close the socket
close(socketFileDescriptor);
return YES;
}
+(BOOL)testIP:(NSURL *)url{
//第二步,通过URL创建网络请求
NSURLRequest *request = [[NSURLRequest alloc]initWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:5];
//第三步,连接服务器
NSError *error;
NSData *received = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:&error];
NSString *str = [[NSString alloc]initWithData:received encoding:NSUTF8StringEncoding];
if (str.length>0) {
return YES;
}else{
return NO;
}
}
NSUserDefaults立即生效
void saveUserRoleType(NSString *type){
[[NSUserDefaults standardUserDefaults] setObject:type forKey:@"roleType"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
修改导航栏背景颜色
/***修改导航栏背景色**/
UINavigationBar * appearance = [UINavigationBar appearance];
UIImage *navBgImage = [[self class] getNavigationBarBgImage];
[appearance setBackgroundImage:navBgImage forBarMetrics:UIBarMetricsDefault];
NSDictionary *navigationBarDic = @{NSFontAttributeName:[UIFont boldSystemFontOfSize:18.0f],
NSForegroundColorAttributeName:[OtherEasyFuncation colorWithHexString:@"#FFFFFF"]};
if (@available(iOS 15.0, *)) {
UINavigationBarAppearance *appearance = [UINavigationBarAppearance new];
[appearance configureWithOpaqueBackground];
appearance.backgroundColor = kMainColor;
appearance.backgroundImage = navBgImage;
appearance.titleTextAttributes = navigationBarDic;
self.navigationBar.standardAppearance = appearance;
self.navigationBar.scrollEdgeAppearance=self.navigationBar.standardAppearance;
} else {
self.navigationController.navigationBar.titleTextAttributes = navigationBarDic;
}
播放音频流
/*
* 播放音频流
*/
-(void)playWithVoiceData:(NSString *)voiceData andFinishBlock:(voiceFinishPlayBlock)finishBlock{
self.myFinishPlayBlock = finishBlock; //获取到block,完成播放时调用
if ([self.player isPlaying]){
[self.player stop];
}
NSError *error1 = nil;
NSData *data = [[NSData alloc] initWithBase64EncodedString:voiceData options:0];
self.player = [[AVAudioPlayer alloc] initWithData:data fileTypeHint:AVFileTypeMPEGLayer3 error:&error1];
self.player.delegate = self;
[self.player play];
}
通过data播放音频
/*
* 通过data来播放音频
*/
-(void)playWithData:(NSData *)musicData {
if ([self.player isPlaying]){
[self.player stop];
}
self.player = nil;
NSError *error1 = nil;
self.player = [[AVAudioPlayer alloc] initWithData:musicData fileTypeHint:AVFileTypeMPEGLayer3 error:&error1];
if (error1) {
NSLog(@"%@",error1);
}
[self.player play];
}
谓词
//使用谓词过滤,获取相同keyId的其他模型,都要变成unselected
NSString *predicateStr = [NSString stringWithFormat:@"keyId=='%@' AND forbidSelectedFlag==0",model.userId];
NSPredicate *pre = [NSPredicate predicateWithFormat:predicateStr];
NSArray *arrayPre = [self.dataArry filteredArrayUsingPredicate:pre];
NSLog(@"%zd",arrayPre.count);
[arrayPre enumerateObjectsUsingBlock:^(DBWOrganizationPersonModel *_Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
obj.selectedFlag = NO;
}];