iOS 无规律总结[UI进阶篇][编写中]http://www.jianshu.com/p/e0d5d0b9a9cf
头尾式动画(了解)
[UIView beginAnimations:nil context:nil];
准备开始动画
[UIView setAnimationDuration:5];
设置时间
[UIView commitAnimations];
提交动画(真正开始做动画)
块动画
+(void)animateWithDuration:(NSTimeInterval)duration
animations:(void (^)(void))animations
completion:(void (^__nullable)(BOOL finished))completion;
+(void)animateWithDuration:(NSTimeInterval)duration
animations:(void (^)(void))animations;
+(void)animateWithDuration:(NSTimeInterval)**duration**
delay:(NSTimeInterval)**delay**
usingSpringWithDamping:(CGFloat)**dampingRatio**
initialSpringVelocity:(CGFloat)**velocity**
options:(UIViewAnimationOptions)**options**
animations:(void (^)(void))**animations**
completion:(void (^__nullable)(BOOL finished))**completion**;
duration : 动画时间
delay : 延迟时间
dampingRatio : 阻尼系数(弹性) 越小越弹
velocity : 速率
options : 选项
animations : 做动画的代码块
completion : 动画完成的代码块 "回调"
View视图插入当前视图的上面和下面
- -(void)insertSubview:(UIView *)view belowSubview:(UIView *)siblingSubview;
- 再siblingSubview下面添加view
- -(void)insertSubview:(UIView *)view aboveSubview:(UIView *)siblingSubview;
- 再siblingSubview上面添加view
序列帧动画实现
方法1
[UIImage animatedImageWithImages:**动画数组** duration:**持续时间**]; // 可以获取一个能做动画的UIImage对象
方法2
self.imageView.animationImages = array; // 装图片的数组(需要做动画的图片数组)
self.imageView.animationDuration = 2; // 动画时间
self.imageView.animationRepeatCount = 1; // 重复次数 0 表示重复
[self.imageView startAnimating]; // 开始序列帧动画
图片浏览器-内存问题
通过imageNamed: 方法建立的图片,系统会进行缓存,程序员无法销毁.
通过imageWithContentsOfFile: 建立的图片,使用完成之后,会自动被释放.
如何选择图像方法:
常用的图像,(小的按钮/背景)素材,放在 Assets 中,使用 imageNamed 加载,性能高
临时使用的图像,放在 Bundle 中,获取其本地路径,使用 imageWithContentsOfFile 加载,使用完成立即释放!
两种加载xib的方式
从 NSBundle加载XIB,只需要在第一个参数传入 XIB 的文件名,注意:没有扩展名
方法1,iOS 2.0 的方法
UIView *appView = [[NSBundle mainBundle] loadNibNamed:@"CZAppView" owner:nil options:nil].lastObject;
方法2,iOS 4.0 的方法,做了内存优化
1.XIB 的文件名
UINib *nib = [UINib nibWithNibName:@"CZAppView" bundle:nil];
2.Bundle 名,如果传入 nil,会自动从 mainBundle 获取
UIView *appView = [nib instantiateWithOwner:nil options:nil].lastObject;
两种加载文件的方式
方法1,通过文件路径加载(本地)
NSString *path = [[NSBundle mainBundle] pathForResource:@"文件名" ofType:@"文件后缀"];
NSArray *images = [NSArray arrayWithContentsOfFile:path];
方法2,通过文件 URL 加载(本地/网络)
NSURL *url = [[NSBundle mainBundle] URLForResource:@"文件名.后缀" withExtension:nil];//或者后缀写在后面
NSArray *images = [NSArray arrayWithContentsOfURL:url];
UIScrollView
//如果要想要一个scrollView滚动,必须要设置它的滚动大小
scrollView.contentSize = pictureImage.frame.size;
//设置scrollView上左下右的间距
scrollView.contentInset = UIEdgeInsetsMake(20, 30, 40, 50);
//禁用弹簧效果
scrollView.bounces = NO;
//禁用scorllView的手动滚动
scrollView.scrollEnabled = NO;
//滚动指示器是scrollView的两个UIImageView类型的子控件。
scrollView.showsHorizontalScrollIndicator = NO;
scrollView.showsVerticalScrollIndicator = NO;
//scrollView滚动的本质就是scrollView的bounds的坐标的变化。
NSLog(@"%@",NSStringFromCGRect(self.scrollView.bounds));
ScrollView滚动动画处理
[scrollView setContentOffset: animated:YES];
调用这个方法如果animated这一参数设置为NO,或者直接设置contentOffset这个property,
delegate会收到一个scrollViewDidScroll:消息。
如果animated这一参数设置为YES,则在整个动画过程中,
delegate会收到一系列的scrollViewDidScroll:消息,
并且当动画完成时,还会收到一个scrollViewDidEndScrollingAnimation:消息。
使用UIView动画后,无论在什么时候查询contentOffset的值,得到的都是动画的最终值
而使用animated参数,可以在动画过程中得到与当前状态较为一致的contentOffset值
打印结构体
NSStringFromCGRect(self.scrollView.bounds)
UIScrollView代理方法
只要滚动scrollView就会调用这个方法
- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
NSLog(@"%s,contentOffset = %@",__FUNCTION__,NSStringFromCGPoint(scrollView.contentOffset));
}
scrollView将要开始被拖拽的时候就会调用这个方法
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{
NSLog(@"%s",__FUNCTION__);
}
scrollView将要停止拖拽的时候调用
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset{
NSLog(@"%s",__FUNCTION__);
}
scrollView已经停止拖拽的时候调用
decelerate 是否减速
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{
NSLog(@"%s,%d",__FUNCTION__,decelerate);
}
// 指定scrollView子控件的最大放大比例和最小缩小比例
self.scrollView.maximumZoomScale = 1.1;
self.scrollView.minimumZoomScale = 0.9;
// 返回需要缩放的视图
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView{
return self.pictureImage;
}
UIView 的ContentMode
UIViewContentModeScaleToFill //缩放并填充
UIViewContentModeScaleAspectFill // 保持等比缩放填充
UIViewContentModeScaleAspectFit //保持宽高比同时让图片完全显示
UIPageControl
//设置非当前的颜色
pageControl.pageIndicatorTintColor
//设置当前页的颜色
pageControl.currentPageIndicatorTintColor
//设置pageControl的总页数
pageControl.numberOfPages
代理和block
代理
1. 设置代理协议
2. 指定代理方法
3. 创建代理对象
4. 遵守代理协议 -> 代理对象赋值
5. 实现代理方法
//被optional修饰的方法,调用前需要进行判断。那样,即使代理没有实现这个方法,程序也不会崩溃
if ([self.delegate respondsToSelector:@selector(xxxx)]) {
[self.delegate xxxx];
}
//被required修饰的方法,调用之前不进行判断。那样,如果代理没有实现这个方法,程序立刻就崩溃
[self.delegate xxxx];
Block的定义格式
返回值类型(^block变量名)(形参列表) = ^(形参列表) {
};
调用Block保存的代码
block变量名(实参);
// typedef 定义的block
typedef NSString *(^myBlock)(NSString *name);
导航栏
// 隐藏顶部状态栏
- (BOOL)prefersStatusBarHidden{
return YES;
}
// 设置状态栏的样式(黑或白)
- (UIStatusBarStyle)preferredStatusBarStyle{
return UIStatusBarStyleLightContent;
}
UITableViewController
tableViewController的self.view和self.tableView是同一个对象!
添加其他子控件,相对于添加给tableView
滚动视图的时候,其他子控件会跟着滚动!
在工作中很少直接使用UITableViewController
大多数都是 UIViewController + tableView使用!
UITableView
//一共有多少组
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
//每组有多少行
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
//每一行显示的内容 //这个方法里,一定不能返回nil
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
//设置分组的头部文字
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
// 设置分组的底部文字
- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section
// tableView的样式,在tableViw创建的时候就已经确定好了,不能够修改!
UITableView *homeTableView = [[UITableView alloc]initWithFrame:CGRectZero style:UITableViewStyleGrouped];
// 错误的演示 style是一个只读属性
self.tableView.style = UITableViewStylePlain;
// Grouped 是有组头和组尾 不会悬停
// Plain 会悬停,需要设置组头信息
//设置tableView右侧的索引标签 -> 返回的字符串数组是什么样就显示什么样,跟数据源的组只有位置的关系,点第一个就是第一组
- (NSArray<NSString *> *)sectionIndexTitlesForTableView:(UITableView *)tableView
//设置 'headerView' 'FooterView' 只需要设置高度即可
tableView.tableHeaderView
tableView.tableFooterView
// 设置组头
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
// 设置组头高度
-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{
//不能写0,写0不起作用。
//0代表默认的组头高度。
return 0.1;
}
//在使用自动布局以前,如果要设置每个cell不同的高度,就需要在这里设置每个cell的高度。
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
return 60;
}
// 刷新 [1,2,3] 行 ->动画效果 同下面不可同时存在
[self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationTop];
// 插入 [1,2,3] 行 -> 动画效果
[self.tableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationBottom];
//1.设置预估行高
tableView.estimatedRowHeight = 400;
//2.设置tableView的行高为自动计算
tableView.rowHeight = UITableViewAutomaticDimension;
// 分割线
UITableViewCellSeparatorStyleNone, 没有分隔线
UITableViewCellSeparatorStyleSingleLine, 有分隔线
UITableViewCellSeparatorStyleSingleLineEtched 有内容的没有分隔线,没有内容有分隔线。
tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
// 可以调用系统的代码设置分隔线
tableView.separatorColor = [UIColor redColor];
// 可以设置分割线的位置
tableView.separatorInset = UIEdgeInsetsMake(0, 0, 0, 0);
// UIEdgeInsetsMake CGFloat top, left, bottom, right;
//当tableView被拖拽的时候,隐藏键盘
self.tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag;
//如果使用自动布局,这个方法写在viewDidLoad里是不行的。 一开始就滚动到底部
[self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:最后一行 inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:NO];
// 重写此方法实现编辑tableView 可以是插入和删除 操作的对象还是数据源
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete)
if (editingStyle == UITableViewCellEditingStyleInsert)
}
// 重写此方法,支持对cell重新排序
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath {
需要将选中的数据记录下来fromIndexPath
从集合中移除选中的数据fromIndexPath
[数组 removeObjectAtIndex:fromIndexPath.row];
将选中的数据插入到对应的位置toIndexPath
[数组 insertObject:数据 atIndex:toIndexPath.row];
}
// 侧滑显示其他按钮
- (NSArray <UITableViewRowAction *> *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath {
// MARK: - 1.删除
UITableViewRowAction *actDel = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDestructive title:@"删除" handler:^(UITableViewRowAction * _Nonnull action, NSIndexPath * _Nonnull indexPath) {
UITableViewRowActionStyleDestructive = UITableViewRowActionStyleDefault 默认是红色
}];
// MARK: - 2.插入
UITableViewRowAction *actIns = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleNormal title:@"插入" handler:^(UITableViewRowAction * _Nonnull action, NSIndexPath * _Nonnull indexPath) {
UITableViewRowActionStyleNormal 灰色
}];
}
// 是否支持移动
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
根据条件自己设定
return YES;
}
UITableViewCell
获取一个复用的Cell有两种方法:
[tableView dequeueReusableCellWithIdentifier:]
必须要对获取到的Cell进行非空判断,如果为空就需要自己定义一个cell.
[tableView dequeueReusableCellWithIdentifier: forIndexPath:];
使用之前必须要对cell进行注册。如果注册以后,可以不进行非空判断。
注册cell有三种方法:
1.使用xib进行注册
self.tableView registerNib: forCellReuseIdentifier:
//如果使用的是xib进行的注册,创建cell的时候,就会调用 [NSBundle mainBundle]loadNibName:
2.使用class类来进行注册
[self.tableView registerClass:[HMHeroCell class] forCellReuseIdentifier:cellID];
//如果使用的是class进行的注册,创建cell的时候,会调用 [class alloc]initWithStyle:defautl样式 reuseIdentifier
3.关联一个storyboard里的原型cell(prototypeCell)
//如果使用的是storyboard进行的注册,创建cell的时候,会直接加载storyboard里的原型cell.
//设置Cell右侧的箭头
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
//可以给cell右侧设置一个accessoryView.
cell.accessoryView = [[UISwitch alloc]init];
字典转模型KVC
[self setValuesForKeysWithDictionary:dict];
本质就是 -> 定义好属性,然后字典取出对应的值进行赋值.这就是为什么模型中的属性一定不能错一个字母的原因
_title = dict[@"title"];
_cars = dict[@"cars"];
16进制颜色转换成RGB
hex = 0xA3B2FF;
int red = hex & 0xFF0000 >> 16;
int green = hex & 0x00FF00 >> 8;
int blue = hex & 0x0000FF;
>>右移将一个数的各二进制位右移N位,移到右端的低位被舍弃,对于无符号数,高位补0
&按位与如果两个相应的二进制位都为1,则该位的结果值为1,否则为0
画一个 一个像素的UIView
[UIScreen mainScreen].scale 获取到屏幕的缩放比例
1 / [UIScreen mainScreen].scale 即可
UICollectionViewLayout
//如果创建的是 UICollectionViewLayout,返回的cell的方法不会被调用!!!
创建这个 UICollectionViewFlowLayout
//设置collectionVioew组与组之间的间距
self.sectionInset = UIEdgeInsetsMake(10, 10, 20, 10);
//设置同一组内,cell之间的间距。
//如果是垂直滚动,这个值代表的是水平最小间距
//如果是水平滚动,这个值代表的是垂直最小间距
self.minimumInteritemSpacing = 27.5;
//设置同一组内的"行"间距
//如果是垂直滚动,这个值代表的是垂直最小间距
//如果是水平滚动,这个值代表的是水平最小间距
self.minimumLineSpacing = 50;
//设置item的大小
self.itemSize = CGSizeMake(100,100);
//设置layout组头和组尾的大小
//水平滚动的时候,宽度起作用
//垂直滚动的时候,高度起作用
self.headerReferenceSize = CGSizeMake(30, 50);
self.footerReferenceSize = CGSizeMake(50, 30);
// 自定义FlowLayout
//这个方法在被调用的时候,collectionView已经有大小。
- (void)prepareLayout
//一定要调用父类的方法
[super prepareLayout];
// 会保存所有cell的indexPath和frame.
// 并不是一上来就把所有cell的frame都计算好,而是先计算一部分。
// 再滚动的时候,把剩下的部分给计算完,计算成以后添加到数组里。
// 它只会计算一次每个cell的大小,当再次滚动的时候,不会再重新计算,而是直接从数组里拿了数据显示到collectionView上
- (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect
UICollectionViewDelegateFlowLayout
// 可以根据indexPath返回对应Cell的大小
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
UICollectionView 组头组尾
//collectionView初始化的时候,必须要传入一个非空的布局参数!!!!
对于段头或者段尾等附加显示的元素,同样需要注册:
[collectionView registerClass:[UICollectionReusableView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"header"];
[collectionView registerClass:[UICollectionReusableView class] forSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:@"footer"];
// 数据源
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
// 进行获取
reuseView = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"header" forIndexPath:indexPath];
UIApplication基本使用
//使用UIApplication对象,可以实现应用程序级别的操作。
//例如:在桌面图标上显示消息个数、显示网络指示器、打电话、发短信、打开网页
//iOS8.0以后,如果想要应用程序上显示一个图标,必须要先注册。
if([[UIDevice currentDevice].systemVersion floatValue] >8.0){
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge categories:nil];
[app registerUserNotificationSettings:settings];
}
//设置应用程序在手机桌面上显示的消息个数
app.applicationIconBadgeNumber = 20;
//调用UIApplication的openURL方法,打开URL路径
[[UIApplication sharedApplication] openURL:url];
//显示网络连接指示器
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
// 程序的启动流程
//argc 参数的个数
//argv 参数的内容
//principalClassName 它必是UIApplication或者它的子类 nil代表的就是UIApplication
//delegateClassName 它必须遵守UIApplicationDelegate协议
return UIApplicationMain(argc, argv, @"UIApplication", @"AppDelegate");
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
//应用程序一启动时就会调用这个方法
//如果是手写代码,可以在这里设置应用程序的Window和根控制器
NSLog(@"%s",__FUNCTION__);
return YES;
}
//应用程序已经进入到后台以后会调用的方法
- (void)applicationDidEnterBackground:(UIApplication *)application {
NSLog(@"%s",__FUNCTION__);
}
//应用程序将要进入前台的调用的方法(第一次进行应用程序时,不会调用进入前台的方法)
- (void)applicationWillEnterForeground:(UIApplication *)application {
NSLog(@"%s",__FUNCTION__);
}
//应用程序已经获取焦点(用户可以交互)
- (void)applicationDidBecomeActive:(UIApplication *)application {
NSLog(@"%s",__FUNCTION__);
}
//应用程序将要失去焦点(回到桌面的那一瞬间)
- (void)applicationWillResignActive:(UIApplication *)application {
NSLog(@"%s",__FUNCTION__);
}
//应用程序将要被中止时调用
- (void)applicationWillTerminate:(UIApplication *)application {
NSLog(@"%s",__FUNCTION__);
}
**可以有两个window,给Appdelegate加一个Window属性**
第一个
//创建一个控制器
MyViewController *controller = [[MyViewController alloc]init];
controller.view.backgroundColor = [UIColor redColor];
//设置控制器为window的主控制器
window.rootViewController = controller;
//把这个window设置为主window并且可见
[window makeKeyAndVisible];
self.window = window;
第二个
self.window1 = [[UIWindow alloc]initWithFrame:CGRectMake(0, 0, 100, 200)];
MyViewController *controller1 = [[MyViewController alloc]init];
controller1.view.backgroundColor = [UIColor greenColor];
controller1.view.frame = [UIScreen mainScreen].bounds;
self.window1.rootViewController = controller1;
[self.window1 makeKeyAndVisible];
UINavController导航控制器
// 状态栏
-(UIStatusBarStyle)preferredStatusBarStyle{
return UIStatusBarStyleLightContent;
}
//导航栏的高度是44.
NSStringFromCGRect(navController.navigationBar.frame)
// 设置titleView
子控制器.navigationItem.titleView
// 设置title
self.navigationItem.title = @"红色视图";
self.navigationItem.backBarButtonItem.title = @"红色视图";
==
self.title = @"红色视图";
//设置导航栏的标题文字颜色为白色
[self.navigationBar setTitleTextAttributes:@{NSForegroundColorAttributeName:[UIColor whiteColor]}];
//设置导航条barButtonItem的颜色
// self.navigationBar.tintColor = [UIColor orangeColor];
// 设置返回的样式
self.navigationItem.backBarButtonItem
//UIBarButtonItem创建方法
系统样式
- (instancetype)initWithBarButtonSystemItem:(UIBarButtonSystemItem)systemItem target:(id)target action:(SEL)action
自定义View
- (instancetype)initWithCustomView:(UIView *)customView
自定义图片
- (instancetype)initWithImage:(UIImage *)image style:(UIBarButtonItemStyle)style target:(id)target action:(SEL)action
自定义文字
- (instancetype)initWithTitle:(NSString *)title style:(UIBarButtonItemStyle)style target:(id)target action:(SEL)action
//设置navItem的左边按钮
self.navigationItem.leftBarButtonItems = @[item1,item2,item3];
//取消半透明效果。如果修改了translucent这个属性,子控制器的坐标原点(0,0)会变化为(0,64)
self.navigationController.navigationBar.translucent = NO;
//取消导航栏下面的分隔线 导航栏中有一个ImageView控件所以会显示一条线
[self.navigationBar setBackgroundImage:[[UIImage alloc]init] forBarMetrics:UIBarMetricsDefault];
[self.navigationBar setShadowImage:[[UIImage alloc]init]];
// 这样是没有效果的
[self.navigationController.navigationBar setBackgroundImage:nil forBarMetrics:UIBarMetricsDefault];
[self.navigationController.navigationBar setShadowImage:nil];
// 导航控制器跳转
// push
[self.navigationController pushViewController:greenController animated:YES];
// pop
// 上一个
- (UIViewController *)popViewControllerAnimated:(BOOL)animated
// 指定一个
- (NSArray<__kindofUIViewController *> *)popToRootViewControllerAnimated:(BOOL)animated
// 跟控制器
- (NSArray<__kindofUIViewController *> *)popToViewController:(UIViewController *)viewController animated:(BOOL)animated
// push的时候隐藏底部TabBar 一般写在base导航控制器.根据子控制器的数量进行判断
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated{
if (self.viewControllers.count > 0) {
viewController.hidesBottomBarWhenPushed = YES;
}
[super pushViewController:viewController animated:animated];
}
图片模式
UIImage *image = [[UIImage imageNamed:@"图片名称"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
UIImageRenderingModeAlwaysTemplate// 模板
UIImageRenderingModeAlwaysOriginal// 默认
UIImageRenderingModeAutomatic// 自动
UITabBarController
// 指定子控制器
self.viewControllers =@[VC1,VC2];
self.childViewControllers 只读的,不能够赋值
controller.tabBarItem.title
controller.tabBarItem.image// 默认 ->可以设置图片模式
controller.tabBarItem.selectedImage// 选中
controller.tabBarItem.badgeValue// 小红点
图片切片
// 这个只是将要被拉伸1像素的横线or竖线,其他的地方不会发生变化
image = [image stretchableImageWithLeftCapWidth:image.size.width*0.5 topCapHeight:image.size.height * 0.7];
// 指定图片四根线组成的范围。并指定是平铺还是拉伸
image = [image resizableImageWithCapInsets:UIEdgeInsetsMake(top,left,bottom,right) resizingMode:UIImageResizingModeStretch];
UIImageResizingModeStretch// 拉伸
UIImageResizingModeTile// 平铺
Masonry
mas_lessThanOrEqualTo(...)// 小于或等于
mas_greaterThanOrEqualTo(...)// 大于or等于
// 对一组控件进行设置约束
/**
参数1 控件是水平还是垂直布局
参数2 控件之间的间距
参数3 如果是水平 -> 最左边 如果是垂直 -> 最上边
参数4 如果是水平 -> 最右边 如果是垂直 -> 最下边
*/
[数组 mas_distributeViewsAlongAxis:MASAxisTypeHorizontal withFixedSpacing:20 leadSpacing:10 tailSpacing:10];
// 控件的位置和高度
[数组 mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.equalTo(self.view);
make.height.mas_equalTo(35);
}];
// 如果你想使用self.view.subViews进行遍历布局的时候.请一定保证self.view.subViews中的对象是你需要的内容.因为控制器视图默认会带着topLayoutGuide和bottomLayoutGuide!!!
键盘
//控制中心 监测UIKeyboardWillChangeFrameNotification 键盘将要改变的信息.
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(receiveKeyboardFrameNotification:) name:UIKeyboardWillChangeFrameNotification object:nil];
//重新接收键盘信息来自控制中心.
- (void)receiveKeyboardFrameNotification:(NSNotification *)notification{
/* notification = NSConcreteNotification 0x7fe70af0abe0 {name = UIKeyboardDidChangeFrameNotification; userInfo = {
UIKeyboardAnimationCurveUserInfoKey = 7;
UIKeyboardAnimationDurationUserInfoKey = "0.25";
UIKeyboardBoundsUserInfoKey = "NSRect: {{0, 0}, {375, 258}}";
UIKeyboardCenterBeginUserInfoKey = "NSPoint: {187.5, 796}";
UIKeyboardCenterEndUserInfoKey = "NSPoint: {187.5, 538}";
UIKeyboardFrameBeginUserInfoKey = "NSRect: {{0, 667}, {375, 258}}";
UIKeyboardFrameEndUserInfoKey = "NSRect: {{0, 409}, {375, 258}}";
UIKeyboardIsLocalUserInfoKey = 1;
}}*/
//拿到键盘frame变化以后的结果
CGRect endFrame = [notification.userInfo[@"UIKeyboardFrameEndUserInfoKey"]CGRectValue];
//计算view的偏移 屏幕的高度 - 键盘frame变化以后的y值
CGFloat transform = [UIScreen mainScreen].bounds.size.height - endFrame.origin.y;
//让整个view偏移
[UIView animateWithDuration:0.25 animations:^{
self.view.transform = CGAffineTransformMakeTranslation(0, -transform);
}];
}
// 键盘消失
[self.textField resignFirstResponder];
//让self.view或者它的textFiled子控件辞去第一响应者
[self.view endEditing:YES];
通知
//接收通知需要放在发送通知之前
//observer:接收者
//selector:接收到消息以后调用的方法(带: 可以获取到NSNotification 对象)
//name:接收的通知名称
//obj:指的是发送消息的对象.nil表示不管是谁发送的消息都收
[[NSNotificationCenter defaultCenter] addObserver:接收者 selector:@selector(接收到消息以后调用的方法) name:@"接收的通知名称" object:指的是发送消息的对象];
//name:消息的名称
//object:谁发送的消息。这个方法只是单纯的发送一个消息,不能够发送消息的内容
[[NSNotificationCenter defaultCenter] postNotificationName:@"weather" object:tencent];
// 发送带消息内容的通知,可以通过接收到的通知获取userInfo中的消息内容
[[NSNotificationCenter defaultCenter] postNotificationName:@"weather" object:tencent userInfo:@{@"today":@"rainning",@"tomorrow":@"still rainning"}];
// 移除接受者
[[NSNotificationCenter defaultCenter]removeObserver接收者];
UIButton
在**storyBoard**中可以在属性栏修改Button的title Insets 和ImageInsets 调整图片和文字的位置
网友评论