1、监听导航栏的frame 和 屏幕旋转起冲突,会崩溃
// 监听导航栏的frame
[self.navigationController.navigationBar addObserver:self forKeyPath:@"frame" options:NSKeyValueObservingOptionNew context:nil];
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{
NSNumber *num = change[@"new"];
NSLog(@"-----------------------------num = %@",num);
CGRect rect = num.CGRectValue;
self.navBar.frame = rect;
}
- (void)dealloc{
[self.navigationController.navigationBar removeObserver:self forKeyPath:@"frame"];
}
/**
* @author 孔凡列, 16-09-21 08:09:06
*
* 横屏
*/
NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeRight];
[[UIDevice currentDevice] setValue:value forKey:@"orientation"];
2、iOS8 的window的宽高会为0
- appDelegate 创建UIWindow的时候,需要指定window的frame,不然iOS8 的window的宽高会为0,但是iOS8以上就不会出现问题
self.window = [[UIWindow alloc] init];// 这样不行
self.window = [[UIWindow alloc] initWithFrame:CGRectMake(0,0,SCREEN_WIDTH,SCREEN_HEIGHT)];// 这样就不会出现适配问题
3、AVAudioPlayer播放超级小声或失真
- AVAudioPlayer播放声音的时候,设置volume 为 1.0 后还是超级小声,超过1.0就会失真.添加一句代码可完美解决
[[AVAudioSession sharedInstance] overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker error:nil];
4、监听横竖屏旋转,系统通知
UIDeviceOrientationDidChangeNotification
5、swift 的 NSObject
-
swift 的 NSObject 的方法都不适用了,很多都是struct 不是 class
-
String 是struct 属于 Any 不是 AnyObject,所以iskind 不能用,用is 判断
6、iOS KVO监听数组元素个数变化(数组地址改变、插入、删除、替换)
-
需要 用
mutableArrayValueForKey
获取到的可变数组(网上说控制器的数组没办法监听,其实可以的,只是一定要用mutableArrayValueForKey
) -
还有一个注意点:分类中的数组是没办法监听到的,其他都可以
7、iOS 系统字体
[UIFont systemFontSize];// 系统默认字体大小 14
[UIFont smallSystemFontSize];// 小系统字体大小 12
[UIFont labelFontSize];// 系统label字体大小 17
[UIFont buttonFontSize];// 系统button字体大小 18
8、strongSelf 和 weakSelf 的使用
总结
- 1、 在 Block 内如果需要访问 self 的方法、变量,建议使用 weakSelf。
- 2 、如果在 Block 内需要多次 访问 self,则需要使用 strongSelf。此时self不会被释放,当block执行完后,会自动释放该strongSelf
9、layoutSubviews和drawRect的调用
-
视图的内容需要重绘时可以调用
setNeedsDisplay
方法,该方法会设置该视图的displayIfNeeded
变量为 YES ,NSRunLoop 在下一次循环检中测到该值为 YES 则会自动调用drawRect
进行重绘。 -
视图的内容没有变化,但在父视图中位置变化了可以调用
setNeedsLayout
,该方法会设置该视图的layoutIfNeeded
变量为YES,NSRunLoop 在下一次循环检中测到该值为 YES 则会自动调用layoutSubViews
进行重绘。
10、AFN3.0 ipv6配置
11、取状态栏判断网络状态
注意:飞行模式和关闭移动网络都拿不到dataNetworkType;1 - 2G; 2 - 3G; 3 - 4G; 5 - WIFI
BOOL flag = NO;
UIApplication *app = [UIApplication sharedApplication];
NSArray *children = [[[app valueForKeyPath:@"statusBar"] valueForKeyPath:@"foregroundView"] subviews];
int netType = 0;
//获取到网络返回码
for (id child in children) {
NSLog(@"child = %@",NSStringFromClass([child class]));
if ([child isKindOfClass:NSClassFromString(@"UIStatusBarDataNetworkItemView")]) {
//获取到状态栏,飞行模式和关闭移动网络都拿不到dataNetworkType;1 - 2G; 2 - 3G; 3 - 4G; 5 - WIFI
netType = [[child valueForKeyPath:@"dataNetworkType"] intValue];
switch (netType) {
case 0:
flag = NO;
//无网模式
break;
default:
flag = YES;
break;
}
}
}
12、label 文字实现竖直排布
- 只需要设置
numberOfLines = 0
然后再调用sizeToFit
13、本地搭建IPv6环境测试
(OS X 10.11 新加的功能)
打开系统偏好设置-按住
option
- 点击共享-创建NAT64
14、给按钮的imageView添加动画组
注意不能设置按钮的
backgroundImage
否则没动画效果
[playBtn setImage:[UIImage imageNamed:@"voice_button_01"] forState:UIControlStateNormal];
//设置动画图片的资源
playBtn.imageView.animationImages = self.animateBtnArrM;
//设置动画的持续时间
playBtn.imageView.animationDuration = 1.5;
//设置动画的执行次数
playBtn.imageView.animationRepeatCount = MAXFLOAT;
//开始动画
[playBtn.imageView startAnimating];
15、使用SDWebImage加载gif 的问题
- 不能压缩,否则无法正常显示
加载GIF 可以 用webView 加载,UIWebView 有缓存,WKWebView 在 iOS 9 之后才有情况缓存的接口
16、滚动视图添加事件
- (UIScrollView 、UITableView、UIWebView、WKWebView、UICollectionView)界面点击事件,添加点击手势需要实现其中一个代理方法,才有点击效果
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
return YES;
}
17、cocoapod search 不到所需的库
rm ~/Library/Caches/CocoaPods/search_index.json
执行完重新 search 就行
18、设置UITextField 水印居中
UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(20, 200, 200, 30)];
textField.borderStyle = UITextBorderStyleLine;
textField.placeholder = @"hello world";
UILabel *label = [textField valueForKey:@"_placeholderLabel"];
label.textAlignment = NSTextAlignmentCenter;
[textField setValue:label forKey:@"_placeholderLabel"];
[self.view addSubview:textField];
19、优雅地隐藏显示导航栏
- 遵守协议
<UINavigationControllerDelegate>
- 设置代理
self.navigationController.delegate = self;
- 重写方法
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated{
BOOL isVC = [viewController isKindOfClass:[self class]];
[self.navigationController setNavigationBarHidden:isVC animated:YES];
}
20、OC 的 指针,swift 的表示方法:
static const void* mainQueueKey = @"mainQueue";
static void* mainQueueContext = @"mainQueue";
private let mainQueueKey = UnsafeMutablePointer<Void>.alloc(1)
private let mainQueueValue = UnsafeMutablePointer<Void>.alloc(1)
21、swift 实现KVO以及提供给OC调用
- 需要使用@dynamic 和 @objc使用,默认如果使用@dynamic swift会隐式添加@objc
22、swift 使用runtime
- 如果是纯swift类,要使用runtime需要加上@dynamic,如果是直接或者间接继承NSObject(这个还是动态执行的),就可以直接使用runtime
23、attribute((visibility (“default”)))作用
-
visibility属性是设置将本项目的函数作为库使用时的可见性。g++编译时, 加入-fvisibility=hidden参数, 会将所有默认public属性设为hidden, 导致库外文件不可见
-
如果设置了__attribute__((visibility (“default”)))的函数, 其public属性仍能对外可见, 而不是hidden。可见编译指令 -fvisibility是对所有属性符号进行处理, 而__attribute__((visibility (“default”)))是对特定函数可见性进行设置, 避免冲突。 原文地址