AVAudio 参考
1.1 AVAudioSessionCategory
几个选项参考:
AVAudioSessionCategoryAmbient
只用于播放音乐时,并且可以和QQ音乐同时播放,比如玩游戏的时候还想听QQ音乐的歌,那么把游戏播放背景音就设置成这种类别。同时,当用户锁屏或者静音时也会随着静音,这种类别基本使用所有App的背景场景。
AVAudioSessionCategorySoloAmbient
也是只用于播放,但是和"AVAudioSessionCategoryAmbient"不同的是,用了它就别想听QQ音乐了,比如不希望QQ音乐干扰的App,类似节奏大师。同样当用户锁屏或者静音时也会随着静音,锁屏了就玩不了节奏大师了。
AVAudioSessionCategoryPlayback
如果锁屏了还想听声音怎么办?用这个类别,比如App本身就是播放器,同时当App播放时,其他类似QQ音乐就不能播放了。所以这种类别一般用于播放器类App
AVAudioSessionCategoryRecord
有了播放器,肯定要录音机,比如微信语音的录制,就要用到这个类别,既然要安静的录音,肯定不希望有QQ音乐了,所以其他播放声音会中断。想想微信语音的场景,就知道什么时候用他了。
AVAudioSessionCategoryPlayAndRecord
如果既想播放又想录制该用什么模式呢?比如VoIP,打电话这种场景,PlayAndRecord就是专门为这样的场景设计的 。
AVAudioSessionCategoryMultiRoute
想象一个DJ用的App,手机连着HDMI到扬声器播放当前的音乐,然后耳机里面播放下一曲,这种常人不理解的场景,这个类别可以支持多个设备输入输出。
AVAudioSessionCategoryAudioProcessing
主要用于音频格式处理,一般可以配合AudioUnit进行使用
更多详见
通过设置active
为YES
激活Session
,设置为NO
解除Session
的激活状态。BOOL返回值表示是否成功,如果失败的话可以通过NSError
的error.localizedDescription
查看出错原因。
- (BOOL)setActive:(BOOL)active error:(NSError * _Nullable *)outError;
注意: 因为
AVAudioSession
会影响其他App的表现,当自己App的Session
被激活,其他App的就会被解除激活,如何要让自己的Session
解除激活后恢复其他App Session的激活状态呢?
- (BOOL)setActive:(BOOL)active withOptions:(AVAudioSessionSetActiveOptions)options error:(NSError * _Nullable *)outError;
这里的options传入 AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation
即可。 当然,也可以通过otherAudioPlaying
变量来提前判断当前是否有其他App在播放音频。
2.1 AVAudioSessionMode
AVAudioSessionModeDefault
每种类别默认的就是这个模式,所有要想还原的话,就设置成这个模式。
AVAudioSessionModeVoiceChat
主要用于VoIP场景,此时系统会选择最佳的输入设备,比如插上耳机就使用耳机上的麦克风进行采集。此时有个副作用,他会设置类别的选项为AVAudioSessionCategoryOptionAllowBluetooth
从而支持蓝牙耳机。
AVAudioSessionModeVideoChat
主要用于视频通话,比如QQ视频、FaceTime。时系统也会选择最佳的输入设备,比如插上耳机就使用耳机上的麦克风进行采集并且会设置类别的选项为
AVAudioSessionCategoryOptionAllowBluetooth
和 AVAudioSessionCategoryOptionDefaultToSpeaker
AVAudioSessionModeGameChat
适用于游戏App的采集和播放,比如“GKVoiceChat”对象,一般不需要手动设置
坐标转换
/// 将像素point由point所在视图转换到目标视图view中,返回在目标视图view中的像素值
- (CGPoint)convertPoint:(CGPoint)point toView:(UIView *)view;
/// 将像素point从view中转换到当前视图中,返回在当前视图中的像素值
- (CGPoint)convertPoint:(CGPoint)point fromView:(UIView *)view;
/// 将rect由rect所在视图转换到目标视图view中,返回在目标视图view中的rect
- (CGRect)convertRect:(CGRect)rect toView:(UIView *)view;
/// 将rect从view中转换到当前视图中,返回在当前视图中的rect
- (CGRect)convertRect:(CGRect)rect fromView:(UIView *)view;
plist文件转json文件
plutil -convert json name.plist -o name.json
Label文字后面添加图片
NSTextAttachment *attch = [[NSTextAttachment alloc] init];
attch.image = [UIImage imageNamed:@"imagename"];
attch.bounds = CGRectMake(10, -1, 7, 12);
NSAttributedString *string = [NSAttributedString attributedStringWithAttachment:attch];
NSString *text = targetPlan.title;
NSMutableAttributedString *attri = [[NSMutableAttributedString alloc] initWithString:text];
[attri addAttribute:NSForegroundColorAttributeName value:RGBA(74,74,91,1) range:NSMakeRange(0, attri.length)];
[attri addAttribute:NSFontAttributeName value:PingFangRegularFont(15) range:NSMakeRange(0, attri.length)];
[attri insertAttributedString:string atIndex:text.length];
self.titleLabel.attributedText = attri;
OC注入JS失败
错误描述:
Error Domain=WKErrorDomain Code=4 "A JavaScript exception occurred" UserInfo={WKJavaScriptExceptionLineNumber=1, WKJavaScriptExceptionMessage=ReferenceError: Can't find variable: web, WKJavaScriptExceptionColumnNumber=4, WKJavaScriptExceptionSourceURL=about:blank, NSLocalizedDescription=A JavaScript exception occurred}
错误原因: 数组转json字符串时options选成NSJSONWritingPrettyPrinted
而不是kNilOptions
导致,下面是正确的注入方法:
// 数组转化成JSON字符串
NSData *data = [NSJSONSerialization dataWithJSONObject:array options:kNilOptions error:nil];
NSString *paraStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSString *method = [NSString stringWithFormat:@"%@('%@')", @"web.getSmallWeightDate", paraStr];
[webView evaluateJavaScript:method completionHandler:^(id _Nullable response, NSError * _Nullable error) {
}];
修改textView或者textField 光标的大小
继承自UITextView 重写父类方法
@implementation CustomTextView
- (CGRect)caretRectForPosition:(UITextPosition *)position {
CGRect originalRect = [super caretRectForPosition:position];
originalRect.size.height = self.font.lineHeight - 8;
originalRect.size.width = 2;
return originalRect;
}
@end
NSPredicate用法之一: 数组元素为对象时,通过对象的某个属性快速筛选出数组中的对象
// 找出tips和年报的模型
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"type == 1001 OR type == 1002"];
NSArray *temp = [self.dataArray filteredArrayUsingPredicate:predicate];
if (temp.count > 0) {
_hasTips = YES;
} else {
_hasTips = NO;
}
关于NSPredicate更多高级用法,参见:iOS NSPredicate 使用详解
iOS中的谓词(NSPredicate)使用
SD图片加载渐现效果
[_ImageView sd_setImageWithURL:url placeholderImage:placeholderImage options:YYWebImageOptionAllowBackgroundTask progress:^(NSInteger receivedSize, NSInteger expectedSize, NSURL * _Nullable targetURL) {
dispatch_sync(dispatch_get_main_queue(), ^(){
[weakSelf fadeLayer:weakSelf.ImageView.layer];
});
} completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) {
}];
- (void)fadeLayer:(CALayer *)layer {
CATransition *transition = [CATransition animation];
transition.duration = 0.5;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
transition.type = kCATransitionFade;
[layer addAnimation:transition forKey:@"fade"];
}
使用pandoc为markdown生成大纲
- 下载和安装pandoc
下载地址https://github.com/jgm/pandoc/releases
Mac系统直接下载pandoc-2.5-macOS.pkg双击安装即可
- 下载和安装pandoc
- 打开终端,输入
pandoc --version
确认 pandoc 已成功安装
- 打开终端,输入
pandoc 2.5
Compiled with pandoc-types 1.17.5.4, texmath 0.11.1.2, skylighting 0.7.4
Default user data directory: /Users/wanghaobing/.pandoc
Copyright (C) 2006-2018 John MacFarlane
Web: http://pandoc.org
- 3.
cd
到存放.md
文件的文件夹目录 - 输入
pandoc -s --toc README.md -o README.md
命令,即可自动生成目录 (使用该命令默认生成三级目录)
如果想要生成4级目录,可以使用pandoc -s --toc --toc-depth=4 README.md -o README.md
命令 (README.md可以修改为你的markdown文件名)
- 输入
WKWebView头部添加自定义View, 随Webview一起滚动
WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
WKWebView *webView = [[WKWebView alloc] initWithFrame:CGRectMake(0, 0, ScreenWidth, ScreenHeight) configuration:configuration];
webView.navigationDelegate = self;
webView.multipleTouchEnabled = YES;
webView.userInteractionEnabled = YES;
webView.contentMode = UIViewContentModeScaleAspectFit;
webView.scrollView.scrollEnabled = YES;
webView.scrollView.delegate = self;
// 调整contentInset,将自定义视图添加到webView.scrollView
webView.scrollView.contentInset = UIEdgeInsetsMake(ScreenWidth, 0, 0, 0);
CustomView *customView = [[CustomView alloc] initWithFrame:CGRectMake(0, -ScreenWidth, ScreenWidth, ScreenWidth)]; //注意y值.
[webView.scrollView addSubview: customView];
[self.view addSubview:webView];
获取当天,当周,当月,当年的时间区间
double interval = 0;
NSDate *beginDate = nil;
NSDate *endDate = nil;
NSCalendar *calendar = [NSCalendar currentCalendar];
[calendar setFirstWeekday:2];//设定周一为周首日
BOOL exist = [calendar rangeOfUnit:NSCalendarUnitWeekOfYear startDate:&beginDate interval:&interval forDate:[NSDate date]];
// unit可分别修改为 NSCalendarUnitDay NSCalendarUnitWeekOfYear NSCalendarUnitMonth NSCalendarUnitYear
if (exist) {
endDate = [beginDate dateByAddingTimeInterval:interval-1];
}else {
return [NSArray array];
}
NSDateFormatter *myDateFormatter = [[NSDateFormatter alloc] init];
[myDateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
NSString *beginString = [myDateFormatter stringFromDate:beginDate];
NSString *endString = [myDateFormatter stringFromDate:endDate];
NSString *section = [NSString stringWithFormat:@"%@ ~ %@",beginString,endString];
NSLog(@"%@",section); // 2018-11-12 00:00:00 ~ 2018-11-18 23:59:59
当然,将上述方法中的 rangeOfUnit
替换为:
-
NSCalendarUnitDay
可以获取当天的时间区间2018-11-12 00:00:00 ~ 2018-11-12 23:59:59
-
NSCalendarUnitWeekOfYear
可以获取当周的时间区间2018-11-12 00:00:00 ~ 2018-11-18 23:59:59
-
NSCalendarUnitMonth
可以获取当月的时间区间2018-11-01 00:00:00 ~ 2018-11-30 23:59:59
-
NSCalendarUnitYear
可以获取当年的时间区间2018-01-01 00:00:00 ~ 2018-12-31 23:59:59
iOS 11以后系统相册选取完图片编辑页面,取消按钮很难被点击到的问题解决办法
#pragma mark - Navigation Controller Delegate
- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
if ([UIDevice currentDevice].systemVersion.floatValue < 11) {
return;
} if ([viewController isKindOfClass:NSClassFromString(@"PUPhotoPickerHostViewController")]) {
[viewController.view.subviews enumerateObjectsUsingBlock:^(__kindof UIView * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
// iOS 11之后,图片编辑界面最上层会出现一个宽度<42的view,会遮盖住左下方的cancel按钮,使cancel按钮很难被点击到,故改变该view的层级结构
if (obj.frame.size.width < 42) {
[viewController.view sendSubviewToBack:obj];
*stop = YES;
}
}];
}
}
创建一个可任意伸缩的图片
- (UIImage *)stretchableImageWithLeftCapWidth:(NSInteger)leftCapWidth topCapHeight:(NSInteger)topCapHeight
这是 UIImage 的一个实例方法,它的功能是创建一个内容可拉伸,而边角不拉伸的图片,需要两个参数,第一个是左边不拉伸区域的宽度,第二个参数是上面不拉伸的高度。根据设置的宽度和高度,将接下来的一个像素进行左右扩展和上下拉伸。
注意:可拉伸的范围都是距离leftCapWidth后的1竖排像素,和距离topCapHeight后的1横排像素
如何忽略UserInterfaceState.xcuserstate文件
首先说说它的作用:UserInterfaceState.xcuserstate是Xcode中保存的用户操作的GUI状态,如窗口位置,打开的标签页,在项目检查等展开的节点、 简单地调整大小的Xcode窗口将这个文件来改变和修改您的源代码控制系统进行标记。每个开发者此文件都会是modify状态,为了避免多个开发者的冲突那么我们最好ignore它为好!
第一步:cd 到你的工程主目录
第二步:git rm --cache */UserInterfaceState.xcuserstate
第三步:git commit -m "Never see you again, UserInterfaceState"
然后去管理工具中选中列出的untrack文件,igonre它,最后再push一下。
使用git时如何忽略UserInterfaceState.xcuserstate文件
Article list