微博中我学会的东西:
1.项目环境的搭建(推送,版本号,支持的iOS几版本几以上的,用与不用StoryBoard两种建立方式,APPIcon,启动图片的两种方式,还有项目类的前缀)
1.1 创建窗口:
//创建窗口
//不能使用局部变量(UIWindow *window)
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].applicationFrame];
self.window.backgroundColor = [UIColor whiteColor];
//显示窗口
[self.window makeKeyAndVisible];
1.2创建TabBar 的时候记得不要作为子视图加载到窗口,这不会支持旋转,要做为窗口的子视图加载。
1.3区分好.bounds 和 .ApplicationFrame
.bounds 是从原点(0,0)开始
.ApplicationFrame 是从图形的Frame末端开始
2.系统主流框架(TabBarController 控制导航栏)
(1)第一点封装好TabBarVC,自己的事情自己管理
(2)UITabBarController的View是 控制器一创建就加载, UIViewController 是懒加载(用到的时候才会去加载)。
(3)封装的好处,是把项目以后用到的相同的功能的抽出一类,怎么封装,自己的事情自己管理
抽方法:一个功能一个方法。
(4)如何可以让图片选中保持图片的颜色,修改图片的渲染样式:保持图片的原来的样式。
(5)如何以后项目中会用到的一个功能抽出来:
<1>创建一个类目,填写的类就是用来调用类方法的类
<2>考虑哪些是受外面的控制的,然后针对这些考虑,要创建什么对象,然后创建类方法。
<6>当项目中敲不出:UIImage 的时候,记得导入框架 <UIKit/UIKit.h>
(6)在同一个类中会重复用到的功能或则相同的功能的,记得抽出一个方法。有外界决定的属性,记得把它作为参数进行传值。要写中文的参数放在最后面。
(7)要把某一些功能设置做成全局的话, 可以在:
////什么时候调用:当程序一启动的时候就调用
////什么作用加载所有的类
//+(void)load
//{
//
//}
//什么时候调用:当程序调用这个类的时候还有它的子类的时候会调用
//什么作用:初始化类
+(void)initialize
{
}
(8)要设置模型中文字的颜色的时候,要通过设置它的文本属性才可以改变字体的颜色,(富文本:颜色,阴影,空心,图片,图文混排)
//什么时候调用:当程序一启动的时候就调用
//什么作用加载所有的类
+(void)load
{
//appearance:只要遵守UIAppearance 协议的都可以使用,比如 UIView
//设置UITabBarItem的外观标志
//appearance 在此处使用不严谨,获取整个项目中的类UITabBarItem 的外观标志
//appearanceWhenContainedIn:仅仅可以获取当前类的 UITabBarItem 的外观全局标志
UITabBarItem *item = [UITabBarItem appearanceWhenContainedIn:self, nil];
NSMutableDictionary *dic = [NSMutableDictionary dictionary];
dic[NSForegroundColorAttributeName] = [UIColor orangeColor];
[item setTitleTextAttributes:dic forState:UIControlStateSelected];
}
(9)使用id 与 instancetype 的区别
1.使用id 在以后的使用中可以使用所有的set,get方法 ,不能使用点语法
2. instancetype 可以自动识别调用它的类,并调整在该类中可以使用。
(10)要调整系统中TabBar 中子控件的位置的时候
1.自定义一个TabBar,还有要了解,显示所加载的子控件的位置是在viewWillAppear方法,但在所有加载完viewDidAppear 中,所加载的除了自己创建还有其他的控件。
(11)如何是tabBar 上的子控件
for (UIView *tabBarButton in self.subviews)
{
if ([tabBarButton isKindOfClass:NSClassFromString(@"UITabBarButton")])
{ }
}
额外的知识点:
-(BOOL) isKindOfClass: classObj(也可以通过是否有相似的字符:NSClassFromString(@“”) 是不是ObjClass 或则是它的子类)判断是否是这个类或者这个类的子类的实例
-(BOOL) isMemberOfClass: classObj 判断是否是这个类的成员
--(BOOL)respondsToSelector: classObj 是否响应指定的 类方法
--(BOOL)performSelector: classObj 对象调用指定的方法
--(BOOL)performSelector: classObj withObject : 对象调用指定的方法 ,传递参数
//[teacher isKindOfClass:[Teacher class]
-(BOOL) respondsToSelector: selector 判读实例是否有这样方法
//[teacher respondsToSelector: @selector( setName: )]
+(BOOL) instancesRespondToSelector: 判断类是否有这个方法。此方法是类方法,不能用在类的对象
//[Person instancesRespondToSelector: @selector(teach)]
(11)调整子控件的大小根背景图片一样大
1. self.plusBtn.bounds = CGRectMake(0, 0, self.plusBtn.currentBackgroundImage.size.width, self.plusBtn.currentBackgroundImage.size.height);
//sizeToFit 默认会根据背景图片,文字,或者 图片背景计算出最合适的位置。
2.【btn sizeOfFit】;
***************************************************************************************
二.自定义tabBar
1.影藏系统自带的tabBar
2.自定义一个tabBar视图
3.将用户自定义的按钮视图添加背景图片,(和选中的背景图片)
4.实现并列视图切换和选中图片的切换效果。
**********************************************************
//跳转时遇到自定义的TabBar 没有影藏时
1self.hidesBottomBarWhenPushed = YES;//这仅仅适用于系统的
2.先把自定义的TabBar 放到系统的TabBar上
3.将系统的TabBar 的子类隐藏掉
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
//移除系统自带的TabBarButton隐藏
for (UIView *tabBarButton in self.tabBar.subviews) {
if ([tabBarButton isKindOfClass:NSClassFromString(@"UITabBarButton")]) {
[tabBarButton removeFromSuperview];
}
}
}
***************************************************************************************
问题:
1.如何让只读的属性,转换可以赋值
可以利用KVC , 【 self setValue:@“” forKeyPath:@“”]; self :代表的是哪一个类 ,forKeyPath:代表的是哪一个属性 setValue :要赋值的值
2.如何让图片和字体根据当前的位置调整
1.tabBar 上的自定义子控件 btn
[btn sizeOfFit];
***************************************************************************************
//创建XIB是遇到的问题
1.利用XIB创建视图控制器的时候,创建的类的类型要和XIB一样,将Class写上对应的视图控制器,还有要将控制器的View连线
2.把 AUto—的那个勾去掉
2.self = [super init]; [super init ]; 这是OC 中一向惯用的做法,主要是为了父类在初始化的过程中防止返回的对象不同于原先创建的。
3.苹果中继承UIView 的是 : 控件 继承 NSObject : 是模型 像 : tabBarItem 一样 继承NSObject 使用的是点语法 可以调用它的属性 ;模型是用来存储数据的,当改变模型的数据的时候,可以相应的改变控件的内容。
********************************************************************************************************************
//当导航条左边的按钮换成自定义的,则会失去滑动返回的效果
1.遵守UINavigationControllerDelegate 协议
2.设置代理
3.实现
3.1//将导航返回代理暂存(自定义一个Strong 的 id 属性)viewDidLoad中
_popDelegate = self.interactivePopGestureRecognizer.delegate;
3.2/控制器跳转完成的时候调用
-(void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
if (viewController == self.viewControllers[0]) {//是根控制器的时候
self.interactivePopGestureRecognizer.delegate = _popDelegate;
}else{//不是根控制器的时候
//将滑动返回的代理清空,实现滑动返回
self.interactivePopGestureRecognizer.delegate = nil;
}
}
***************************************************************************************
//实现设置非根控制器上的导航左右两边的按钮设置
//设置导航条上的按钮
-(void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
{
//设置导航栏的内容,只有调用Push时才会设置导航控制器的上的内容,所以在push的前面设置它的前提条件,不是根视图控制器才设置它的内容
if (self.viewControllers.count != 0) {//不是跟视图控制器
//设置导航栏的内容
//设置导航控制左右两边的按钮
//左边的按钮
//当设置的左边的返回按钮覆盖以后,不能实现滑动返回手势功能
viewController.navigationItem.leftBarButtonItem = [UIBarButtonItem barButtonItemWithImage:[UIImage imageNamed:@"navigationbar_back"] highImage:[UIImage imageNamed:@"navigationbar_back_highlighted"] target:self action:@selector(backToPre) forControlEvents:UIControlEventTouchUpInside];
//右边的按钮
viewController.navigationItem.rightBarButtonItem = [UIBarButtonItem barButtonItemWithImage:[UIImage imageNamed:@"navigationbar_more"] highImage:[UIImage imageNamed:@"navigationbar_more_highlighted"] target:self action:@selector(backToRoot) forControlEvents:UIControlEventTouchUpInside];
}
// CZLog(@"%s",__func__);
[super pushViewController:viewController animated:animated];
}
-(void)backToPre
{
[self popViewControllerAnimated:YES];
}
-(void)backToRoot
{
[self popToRootViewControllerAnimated:YES];
}
**********************************************************
//设置导航上按钮的两张图片的 类方法
+ (UIBarButtonItem *)barButtonItemWithImage:(UIImage *)image highImage:(UIImage *)highImage target:(id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents
{
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
[btn setBackgroundImage:image forState:UIControlStateNormal];
[btn setBackgroundImage:highImage forState:UIControlStateHighlighted];
[btn sizeToFit];
[btn addTarget:target action:action forControlEvents:controlEvents];
return [[UIBarButtonItem alloc]initWithCustomView:btn];
}
**********************************************************
//当跳转的时候,出现系统自带的tabBarItem 的时候,(单次还是多次跳转)
1.遵守协议UINavigationControllerDelegate,设置代理
2.实现方法
//控制器即将跳转的时候调用
-(void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
//获取主窗口
UIWindow *keyWindow = [UIApplication sharedApplication].keyWindow;
//获取根控制器
UITabBarController *tabBarVC = (UITabBarController *)keyWindow.rootViewController;
//移除系统自带的tabBarItem,这个单次跳转,出现了系统自带的,可在ViewWillAppear 中实现清除 这种效果
for (UIView *subTabBarItem in tabBarVC.tabBar.subviews) {
if ([subTabBarItem isKindOfClass:NSClassFromString(@"UITabBarButton")]) {
[subTabBarItem removeFromSuperview];
}
}
}
***************************************************************************************
//注意点: tableView 与 collectionView 要加载内容记得加载在 contentView 上 ,不要加载在cell 上.
***************************************************************************************
////把昵称放到账号处,添加属性,直接取巧的归档,以后碰到的话相似的,以前有过归档的,你想保存一个属性,也可以类似的添加属性归档
***************************************************************************************
//业务思想:昵称可能会改变时,把昵称先保存起来,当每次请求昵称的时候直接赋值(因为已经获取了昵称的请求,所以不用比较,直接赋值,会更好)
***************************************************************************************
//平移动画的实现,实现以个Lable 导航控制的导航条下面下拉,过了2秒以后自动上升,移除
//显示最新的微博数
-(void)showNewStatusCount:(int)count
{
//判读当没有的时候直接不显示
if (count == 0) return;
CGFloat h = 35;
CGFloat x = 0;
CGFloat y = CGRectGetMaxY(self.navigationController.navigationBar.frame) - h;
CGFloat w = self.view.width;
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(x, y, w, h)];
label.text = [NSString stringWithFormat:@"最新的微博数为:%d",count];
label.textAlignment = NSTextAlignmentCenter;
label.textColor = [UIColor whiteColor];
label.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"timeline_new_status_background"]];
//插入导航控制器的导航条的下面
[self.navigationController.view insertSubview:label belowSubview:self.navigationController.navigationBar];
//将Lable下移
[UIView animateWithDuration:0.25 animations:^{
label.transform = CGAffineTransformMakeTranslation(0, h);
} completion:^(BOOL finished) {
//向上移动
[UIView animateWithDuration:0.25 delay:2 options:UIViewAnimationOptionCurveLinear animations:^{
//还原
label.transform = CGAffineTransformIdentity;
} completion:^(BOOL finished) {
[label removeFromSuperview];
}];
}];
}
***************************************************************************************
//重写set方法的时候,记得不可以计算子控件的Frame ,这会很耗费性能,每次调用都计算