1.UITabBar选中的图片默认渲染颜色为蓝色 如果不想改变图片的颜色 可做如下操作
或者找到对应的图片 如图所示 最下面的 Render As → Original Image
2.通过appearance统一设置所有UITabBarItem的文字属性
方法后面带有UI_APPEARANCE_SELECTOR的方法都可以通过appearance的对象来统一设置
3.通过代码自定义的控件,需要重写- (instancetype)initWithFrame:(CGRect)frame方法
4.UI控件的坐标及大小可以通过为UIView类添加Category 来实现
需要注意 :在分类中声明只会生成方法的声明 不会生成方法的实现和带有下划线的成员变量 需要手写setter 和 getter方法 width height x y
5.自定义打印 在pch文件内
如果是调试阶段#define DXYLog(...) NSLog(__VA_ARGS__)
如果是发布程序 #define DXYLog(...)
7.
8.
9.DXTTabBarViewController是继承自UINavigationController 命名的时候没有注意 - -
如果使用[UINavigationBar appearance]方法设置,那么所有的自定义的导航栏都会改变
注: 像appearance这种一次性设置的方法最好放在initialize中设置,在viewDidLoad里调用次数取决于生成该类对象的个数
证明如图:
只打印一次
打印了4次
宏定义如下图
10. #ffff00 代表红色 R 对应 ff G 对应 ff B 对应 00 24bit 每个8bit 2位
11.水平居中就是使文字在这行、单元格、编辑范围内处在中间;垂直居中就是使文字在这列、单元格、编辑范围内处在中间。
12.UIlabel 约束宽度后 可以自适应高度 注:自动换行
13.在sb或xib上 若在UILabel上文字需要换行显示 做法:option键 + 回车键 效果如图
14.
15.利用正则表达式验证邮箱是否正确
16.KVO实现原理
基于Runtime运行时实现 动态生成继承自被观察对象的之类,调用被观察属性的setter方法 内部再调用observeValueForKeypath
当某个类的对象第一次被观察时 系统就会在运行期动态地创建该类的一个派生类 在这个派生类中任何被观察属性的setter方法 派生类在被重写的setter方法实现真正的通知机制(Person → NSKVONotifying_Person)
17.是否可以把比较耗时的操作放在NSNotificationCenter中 不可以,通知中心所做的操作在主线程 比较耗时的一般开启一个线程单独去跑
18.
打印结果如下
19.
20.
21.
22.获取图片的后缀名 来判断是否隐藏gif标志
效果如下
25.pop是由facebook开发的
/**
pop和Core Animation的区别
1.Core Animation的动画只能添加到layer上
2.pop的动画能添加到任何对象
3.pop的底层并非基于Core Animation,是基于CADisplayLink
4.Core Animation的动画仅仅是表象 并不会真正修改对象的frame\size
5.pop的动画实时修改对象的属性,真正修改了对象属性
*/
//- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
//
// POPSpringAnimation *animation = [POPSpringAnimation animationWithPropertyNamed:kPOPViewCenter];
// animation.fromValue = [NSValue valueWithCGPoint:CGPointMake(100, 100)];
// animation.toValue = [NSValue valueWithCGPoint:CGPointMake(200, 200)];
// animation.springBounciness = 20;
// animation.springSpeed = 20;
// animation.beginTime = CACurrentMediaTime() + 1;
// [self.sloganView pop_addAnimation:animation forKey:nil];
//}
26.
25. window.windowLevel 优先级高于statusBar 会遮住状态栏
注:达到半透明效果 能看清后面的内容 可创建一个新的window 下面视图的点击事件就都隔离开了
UIWindow *window;
- (void)buttonClick:(UIButton *)button {
/** 窗口级别
UIWindowLevelNormal < UIWindowLevelStatusBar < UIWindowLevelAlert
*/
window = [[UIWindow alloc] init];
window.frame = CGRectMake(0, 0, 375, 20);
window.backgroundColor = [UIColor cyanColor];
window.windowLevel = UIWindowLevelStatusBar;
window.hidden = NO;
/** 计算label的宽度 */
CGFloat messageW = [message sizeWithAttributes:@{NSFontAttributeName : [UIFont systemFontOfSize:12]}].width;
28.UIAlertController的用法
- (IBAction)more:(id)sender {
UIAlertController *alertC = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:(UIAlertControllerStyleActionSheet)];
UIAlertAction *collectAction = [UIAlertAction actionWithTitle:@"收藏" style:(UIAlertActionStyleDefault) handler:nil];
UIAlertAction *reportAction = [UIAlertAction actionWithTitle:@"举报" style:(UIAlertActionStyleDefault) handler:nil];
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:(UIAlertActionStyleCancel) handler:nil];
[alertC addAction:collectAction];
[alertC addAction:reportAction];
[alertC addAction:cancelAction];
[[UIApplication sharedApplication].keyWindow.rootViewController presentViewController:alertC animated:YES completion:nil];
}
29.在控制器将要销毁的时候要移除观察者 取消AFNetworking执行的所有任务
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
/** 恢复帖子的top_cmt */
if (self.save_top_cmt) {
self.model.top_cmt = self.save_top_cmt;
[self.model setValue:@0 forKeyPath:@"cellHeight"];
}
/** 取消所有任务 */
// [self.manager.tasks makeObjectsPerformSelector:@selector(cancel)] (这个方法不够彻底 取消之前旧任务 新任务可执行);
[self.manager invalidateSessionCancelingTasks:YES];
}
30.继承控件具备UIMenuController
/** 系统自带UIMenuController的控件有 UITextfield UITextView UIWebView */
/** 重写UILabel让label具备该功能 */
#import "DXYLabel.h"
@implementation DXYLabel
- (void)awakeFromNib {
[self setUp];
}
- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
[self setUp];
}
return self;
}
- (void)setUp {
self.userInteractionEnabled = YES;
[self addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(labelClick)]];
}
- (void)labelClick {
/** 1.让label成为第一响应者 (作用是:告诉UIMenuController支持哪些操作,这些操作如何处理) */
[self becomeFirstResponder];
/** 2.显示MenuController */
UIMenuController *menu = [UIMenuController sharedMenuController];
/** targetRect:menuController需要指向的矩形框
targetView:以target的左上角为坐标原点
*/
[menu setTargetRect:self.bounds inView:self];
[menu setMenuVisible:YES animated:YES];
}
/** 让label有资格成为第一响应者 */
- (BOOL)canBecomeFirstResponder {
return YES;
}
/** label能执行哪些操作(比如copy,paste等等) */
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
if (action == @selector(cut:) || action == @selector(paste:) || action == @selector(copy:)) return YES;
return NO;
}
- (void)cut:(UIMenuController *)sender {
[self copy:sender];
/** 清空文字 */
self.text = nil;
}
- (void)copy:(UIMenuController *)sender {
/** 将自己的文字复制到粘贴板 */
UIPasteboard *board = [UIPasteboard generalPasteboard];
board.string = self.text;
}
- (void)paste:(UIMenuController *)sender {
/** 将粘贴板复制到自己的文字 */
UIPasteboard *board = [UIPasteboard generalPasteboard];
self.text = board.string;
}
31.UITabBarController可通过属性找到当前的索引值 和 当前选中的控制器
32.如果你设置某些东西的时候没有实现应有效果 可以考虑强制更新一下试试
/** 强制更新 */
[self.navigationController.navigationBar layoutIfNeeded];
34.setNeedsDisplay:会在恰当的时候自动调用drawRect方法
setNeedsLayout:会在恰当的时候调用layoutSubViews方法
35.如果控制器是从xib创建的,在viewDidLoad里拿到的size是初始化时的尺寸
36.
/** VC 模态出 addVC */
[VC presentViewController:addVC animated:YES completion:nil];
/** 通过属性找出对应的控制器 */
addVC.presentingViewController -> VC
VC.presentationController -> addVC
37.拿到一个数组中所有对象的某一属性
第一种:遍历
NSMutableArray *tags = [NSMutableArray array];
for (DXYTagButton *button in self.tagButtons) {
[tags addObject:button.currentTitle];
}
第二种:KVC
NSArray *tags = [self.tagButtons valueForKeyPath:@"currentTitle"];
- (void)layoutSubviews方法里,在创建完子控件后,执行
/** 重新布局子控件 */
[selfsetNeedsLayout];
就会调用- (void)layoutSubviews方法,重新布局
39.
/** 如果滑动移除控制器的功能失效 清空代理(让导航控制器重新设置这个功能) */
self.interactivePopGestureRecognizer.delegate = nil;
40.沙盒文件路径
NSString *sanBox = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
41.通过block遍历
/** 找出高度最短的一列 */
__block NSInteger destColumn = 0;
__block CGFloat minColumnHeight = MAXFLOAT;
[self.columnHeights enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
CGFloat columnHeight = [(NSNumber *)obj doubleValue];
if (columnHeight < minColumnHeight) {
minColumnHeight = columnHeight;
destColumn = idx;
}
}];
/** 更换tabBar self.tabBar 只读特性 不能直接赋值 可以使用KVC*/
// self.tabBar = [[DXYTabBar alloc] init];
[self setValue:[[DXYTabBar alloc] init] forKeyPath:@"tabBar"];