[BS] 小知识点总结-03
1.Autolayout中“constrain to margins”
Autolayout中的页面边距的问题ios8以后的UIView增加了layoutMargins属性,在Storyboard/IB中使用AutoLayout布局时,一般都取消勾选“constrain to margins”,如果勾选,即使你在约束里设置某个控件的上下左右均为0,当查看其真实坐标时,发现x=16,y=20,而且控件的右侧离self.view的最右边也有16point的间距,下边没有间隙。故一般取消勾选即可。
2.
2.1 modal出来的控制器使用下面2个方法都能将其关闭,这两种写法有什么区别啊?
[self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
[self dismissViewControllerAnimated:YES completion:nil];
2.2
window.rootViewController = tabBarController; //window特有方法,rootVC将与window同生同死
【tabBarController addChildViewController:navController】; //@property(nonatomic,copy) NSArray *viewControllers;
navController= [UINavigationController alloc] initWithRootViewController:viewController]; //rootVC被加入导航栈最底部,即navController.viewControllers的第一个元素,与navC同生同死。相当于Sb中Embed in NavigationController。
注意:
(1) 以上关系中,viewController的view会被自动添加到以window为基础的UI层级中(注意self.view并没有被直接加到window上,二者之间还有6/7个视图层级)。
(2) navC和tabC都有切换页面的功能,都有viewControllers属性,又有childViewControllers属性(二者的值完全相同,后者readonly)。而普通的viewController都只有childViewControllers属性,没有viewControllers属性。
(3) tabBar上面超过5个按钮,那么系统会自动将第5个按钮变为“更多”,第5个及以后的按钮就被放进“more”中。The "More" navigation controller will not be returned by -viewControllers, but it may be returned by -selectedViewController.
3. UIView.subviews
所有的UIView都有一个subviews数组属性,管理着它的所有子视图,可以通过以下方法在某个位置插入子视图
UIView *view = [[UIView alloc]initWithFrame:self.view.frame];
view.backgroundColor = [UIColor greenColor];
[self.view insertSubview:view atIndex:0];
4. 自定义UI控件init方法
//从Xib创建会调用如下两个方法
//最先调用
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
if (self = [super initWithCoder:aDecoder]) {
}
return self;
}
//接着调用
- (void)awakeFromNib { }
//最后调用
- (void)drawRect:(CGRect)rect {
[super drawRect:rect];
} //完全代码创建
//先调用
- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
}
return self;
}
//然后调用
- (void)drawRect:(CGRect)rect {
[super drawRect:rect];
}
5.设置UI控件圆角方法
5.1代码设置(需要获取该控件的引用)
self.loginButton.layer.cornerRadius = 5;
self.loginButton.layer.masksToBounds = YES; //bounds默认是不可见的,只有盖住它才可见。
5.2在Xib中利用KVC直接设值
6.
不管UITextField加载self.view哪个子视图里,在任何一个方法中调用[self.view endEditing]; 都可以把界面上弹出的所有的键盘收回去。
通过修改某UI控件的约束来实现动画,在修改完约束后,在[UIView animateWithDuration:1.0 animations:^{ [self.view layoutIfNeeded]; }];中不一定非要用该UI控件的父视图来调用layoutIfNeeded方法,最简单的通用方法是直接让self.view重新布局。
7. 设置背景色的3种方法
titlesView.backgroundColor = [UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:0.5]; //通用
titlesView.backgroundColor = [[UIColor whiteColor]colorWithAlphaComponent:0.5]; //设置常见颜色及Alpha
titlesView.backgroundColor = [UIColor colorWithWhite:1.0 alpha:0.5]; //特殊用法:设置RGB相同的灰色及Alpha
/*
+ (UIColor *)blackColor; // 0.0 white
+ (UIColor *)darkGrayColor; // 0.333 white
+ (UIColor *)lightGrayColor; // 0.667 white
+ (UIColor *)whiteColor; // 1.0 white
+ (UIColor *)grayColor; // 0.5 white
+ (UIColor *)clearColor; // 0.0 white, 0.0 alpha
*/
8. 计算文本框宽高的2种方法
NSDictionary *textDict = @{ NSFontAttributeName:[UIFont systemFontOfSize:12] };
//方法1:
CGFloat maxW = self.contentView.frame.size.width - 2* margin; //限定最大的宽度为:cell宽度-2*margin
CGRect textRect = [textStr boundingRectWithSize:CGSizeMake(maxW, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:textDict context:nil]; //如果不限制宽高,就写(MAXFLOAT, MAXFLOAT)
//方法2:
//计算文本框宽高,不设置最大宽度限制,所有文字显示在一横行上(等价于上一种方法不限制宽高)
CGSize textSize = [text sizeWithAttributes:attrDict];
9. 根据文字调整宽高sizeToFit:
[label sizeToFit]; [button sizeToFit];//调整里面的图片框和Label [button.titleLabel sizeToFit];
注意:调用sizeToFit会让控件的size立马有值,产生和[self.view layoutIfNeed]类似的效果。
10.
取消scrollView和tableView自动布局向下偏移64,要用当前控制器的属性self.automaticallyAdjustsScrollViewInsets = NO;
注意:该属性是视图控制器的属性,并不是scrollView和tableView的属性。因误以为是scrollView和tableView的属性,在敲代码时Xcode死活没提示。郁闷了一阵,下次不在此栽跟头了。
//以下写法报错(UIView并没有该属性)
scrollView.automaticallyAdjustsScrollViewInsets = NO; //直接编译报错
tableView.automaticallyAdjustsScrollViewInsets = NO; //直接编译报错
//以下属性用于关闭UIView的Autoresizing,一般是在使用AutoLayout给该UIView添加约束前使用。注意别和视图控制器的automaticallyAdjustsScrollViewInsets属性混淆了。
tableView.translatesAutoresizingMaskIntoConstraints = NO;
scrollView.translatesAutoresizingMaskIntoConstraints = NO;
11.
//scrollView子控件的frame是参考contentSize左上角(0,0)点来设定的,与scrollView坐标没有关系。
12. 关于scrollView的一些方法:
a.通过设置offSet让scrollView匀速滚动:[scrollView setContentOffset:offset animated:YES];
b.监听setContentOffset停止滚动的时刻:
//该方法专门监控setContentOffset: animated:方法后的滚动
- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView { }
c. 监听用户拖动后,停止滚动的时刻:
//带Decelerating的方法特指:用户拖拽过后的减速(用户不施力是匀速滚动)
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView { }
13. scrollView.pagingEnabled = YES; //启用分页(拖动时要么滚动一整页,要么不滚动,跟contentOffset有关)
14. 注意UI控件的viewWithTag:方法(如[self.view viewWithTag:0]),会返回view的视图层级中与给定tag匹配的view,也包含view自身在内。所有的UI控件不设置tag值,默认是0。
Return: The view in the receiver’s hierarchy whose tag property matches the value in the tag parameter.
14.
tableVC会自动调整tableView顶部内边距为64(状态栏20+导航栏44),即使设置tableViewController.automaticallyAdjustsScrollViewInsets = NO;仍然会被设置向下偏移20(状态栏宽度)。如果想让tableView顶格,需手动设置frame的y = 0;
//打印继承自scrollView的相关偏移属性
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(@"tableView.frame:%@",NSStringFromCGRect(tableView.frame));
NSLog(@"tableView.contentInsets:%@",NSStringFromUIEdgeInsets(tableView.contentInset));//tableVC会自动调整tableView顶部内边距为64
NSLog(@"tableView.contentOffset:%@",NSStringFromCGPoint(tableView.contentOffset));
NSLog(@"tableView.contentSize:%@",NSStringFromCGSize(tableView.contentSize));
} -- ::34.622 . 待办清单ToDoList[:] *** -[NSKeyedUnarchiver initForReadingWithData:]: data is NULL
-- ::03.588 . 待办清单ToDoList[:] tableView.frame:{{, }, {, }}
-- ::03.588 . 待办清单ToDoList[:] tableView.contentInsets:{, , , }
-- ::03.588 . 待办清单ToDoList[:] tableView.contentOffset:{, -}
-- ::03.588 . 待办清单ToDoList[:] tableView.contentSize:{, }
15. 设置了tableView的内边距,同时也需要设置滚动条的内边距,否则不协调。
//设置tableView内边距(此代码必须放到addSubview之前,一显示页面才会生效)
tableView.contentInset = UIEdgeInsetsMake(CGRectGetMaxY(self.titlesView.frame), 0, self.tabBarController.tabBar.height, 0);
//设置滚动条的内边距
tableView.scrollIndicatorInsets = tableView.contentInset;
16.
//如果导航栏是半透明的,mj_header在停止刷新后虽然自动隐藏了,但是会被看到。这是只需要设置mj_header允许自动改变透明度即可
self.tableView.mj_header.automaticallyChangeAlpha = YES;
17. 使用MJRefreshAutoNormalFooter时的问题
使用如下代码添加footer刷新:self.tableView.mj_footer = [MJRefreshAutoNormalFooter footerWithRefreshingTarget:self refreshingAction:@selector(loadMoreTopics)]; 在数据尚未返回,或者加载失败footer都会跑到最顶部。
解决方法1: 第一次进来或者每次reloadData否会调一次numberOfRowsInSection:在此方法中控制footer是否隐藏 self.tableView.mj_header.hidden = (self.topics.count == 0);
解决方法2:直接使用[MJRefreshBackFooter footerWithRefreshingBlock:^(void)refreshingBlock];比较省事,数据为出现或加载失败,footer都会自动隐藏在最下方看不见的地方。
18.
SVProgressHUD 只需要在第一次尝试的时候采用默认黑色Mask的样式,以后就不需要设置了。
//提示用户加载失败
[SVProgressHUD setDefaultMaskType:SVProgressHUDMaskTypeBlack];
19.
因UIViewController有这样一个分类,所以对于所有的视图控制器只要是最底层是tabBarController,不管中间隔着多少个控制器,都可以拿到该属性。vc.tabBarController和vc.navigationController属性类似。
@interface UIViewController (UITabBarControllerItem)
@property(null_resettable, nonatomic, strong) UITabBarItem *tabBarItem; // Automatically created lazily with the view controller's title if it's not set explicitly.
@property(nullable, nonatomic, readonly, strong) UITabBarController *tabBarController; // If the view controller has a tab bar controller as its ancestor, return it. Returns nil otherwise.
@end
20. 设置ios素材图片的拉伸模式
21.
在布局时如果发现某个控件frame尺寸设置正确,但显示出来却不是想要的尺寸frame,一般很可能是因为autoresizing自动伸缩属性(只能设置自身和superView的关系)的影响。解决方法: iconImageView.autoresizingMask = UIViewAutoresizingNone;
22. UIImageView两种创建方法:
//1.常规方法:
UIImageView *imgView = [[UIImageView alloc]init]; imgView.image = [UIImage imageNamed:@"angle"];
//2.创建和image同等尺寸的imageView
UIImageView *imgView1 = [[UIImageView alloc]initWithImage:@"angle"];
23.
Xib中加载起来的视图控制器的self.view尺寸是(600,600),此时如果想拿到真实的屏幕尺寸,只能通过[UIScreen mainScreen].bounds来获取屏幕尺寸的准确值。
//WZShowViewController.h/.m/.xib测试结果如下:
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(@"self.view:%@",self.view);
} //打印结果:self.view:<UIView: 0x7fb72d2ab860; frame = (0 0; 600 600);
24.将UIImage保存到相册:
UIImageWriteToSavedPhotosAlbum(self.imageView.image, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);
//苹果推荐使用image:didFinishSavingWithError:contextInfo:
- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo{
if (error) {
[SVProgressHUD showErrorWithStatus:@"保存失败"];
} else {
[SVProgressHUD showSuccessWithStatus:@"保存成功"];
}
}
25. 九宫格的写法
NSArray *images = @[@"video",@"picture",@"text",@"audio",@"publish-review",@"offline"];
NSArray *titles = @[@"视频",@"图片",@"文字",@"声音",@"审核",@"离线"]; CGFloat buttonW = ;
CGFloat buttonH = buttonW + ;
CGFloat leadingMargin = ; //第一个按钮距屏幕左边沿举例
NSInteger colomns = ; //每行3个按钮
NSInteger rows = (images.count % colomns == ) ? (images.count / colomns) : (images.count/colomns + ); //计算有多少行
CGFloat maginX = (screenW - * leadingMargin - colomns * buttonW) / (colomns - ); //x方向间距
CGFloat maginY = ; //y方向间距
CGFloat row1Y = (screenH - buttonH * rows - maginY * (rows - )) * 0.5; //垂直居中 for (int i = ; i < images.count; i++) { WZVerticalButton *button = [[WZVerticalButton alloc]init];
[button setImage:[UIImage imageNamed:images[i]] forState:UIControlStateNormal];
[button setTitle:titles[i] forState:UIControlStateNormal];
[button setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; button.x = leadingMargin + (i % colomns) * (buttonW + maginX);
button.y = row1Y + (i / colomns) * (buttonH + maginY);
button.width = buttonW;
button.height = buttonH; [self.view addSubview:button]; }
26.
将CGPoint类型包装成对象[NSValue valueWithCGPoint:CGPointMake(100, 100)];
27. 新建window并显示
UIWindow *window = [[UIWindow alloc]init];
window.hidden = NO;
Note1:想让新建的window显示出来,只需要设置hidden = NO;即可。窗口是老大,别人添加到它上面,它自己想显示,直接取消隐藏即可。
Note2: [window makeKeyAndVisible]; 等价于 [window makeKeyWindow]; window.hidden = NO;
Note3: 每个窗口的触摸事件是独立的,不会向后穿透。
Note4: 同级别的window,最后设置hidden=NO;的窗口显示在最上面。窗口有3种级别:Normal < StatusBar < Alert 级别。将一个window的windowLevel设置为statusBar级别,然后设置和状态栏一样的frame,相当于自定义状态栏。
28.
(1). 设置view的边框和阴影
(2).
view.layer.masksToBounds = YES; 官方解释:A Boolean indicating whether sublayers are clipped to the layer’s bounds. 设置YES, 则view内部的子layer都会被view.layer.bound所裁剪。 实现阴影效果时,必须设为NO,否则阴影效果消失。设置ImageLayer并显示边框时,必须将masksToBounds设为NO,否则子layer会露出来。
(3).
只要设置layer.cornerRadius=10; 和 layer.borderWidth=3; 就可以显示圆角,和layer.masksToBounds无关,该属性仅影响子layer是否被裁剪。
29.
(1) 利用transform属性可以对UIView控件进行平移Translation、缩放scale、旋转rotation
struct CGAffineTransform {
CGFloat a, b, c, d;
CGFloat tx, ty;
};
创建一个CGAffineTransform类型的transform属性
在某个transform的基础上进行叠加
CG_EXTERN const CGAffineTransform CGAffineTransformIdentity /* The identity transform: [ 1 0 0 1 0 0 ]. */
(2) 可以给UIView.layer添加transform.transition、transform.scale、transform.rotation核心动画
CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
anim.toValue = @0.5;
anim.repeatCount = MAXFLOAT;
[self.view.layer addAnimation:anim forKey:nil];
30. 让layoutSubViews方法中某段代码只执行一次
//1.使用内部全局BOOL变量记录代码是否被执行过
static BOOL excuted = NO; //定义内部全局变量
- (void)layoutSubviews{
if (excuted == NO) {
NSLog(@"该代码只会被执行一次!");
}
excuted = YES; //全局变量和程序同生同死,只要程序没有重启,下次执行layoutSubviews方法,excuted = YES;中间的代码不会被执行
}
//2.使用dispatch_once
static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ });
[BS] 小知识点总结-03的更多相关文章
- [BS] 小知识点总结-05
[BS] 小知识点总结-05 1. 不论UIWindow的rootViewController是navC.tabBarC还是VC,也不管modalVC和rootVC中间隔着多少个VC,但是modal出 ...
- [BS] 小知识点总结-04
1. ios新知识学习思路: 在开发过程中如果遇到某种新需求以前从未做过,例如改变textField的Placeholder颜色,有如下思路和途径: 1.1 在Storyboard/Xib辅助编辑器A ...
- [BS] 小知识点总结-02
1. dispatch_GCD 可让某操作延迟x秒执行 //模拟网速慢,延迟3s返回数据(就会导致右侧数据和左侧标签不对应) dispatch_after(dispatch_time(DISPATC ...
- [BS] 小知识点总结-01
1. UIImageView *imgView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"MainTitle&quo ...
- android 小知识点
小知识点总结 1. android中MotionEvent.ACTION_CANCEL事件如何被触发? 对于这个问题,android文档的说明很简短,想看明白很难.国外一网页说的还比较详细,写在这里分 ...
- 刚接触Linux,菜鸟必备的小知识点(一)
身为一个将要大四的学生,而且还是学计算机的没有接触过linux简直是羞愧难当.这个假期做了一个软件测试员,必须要熟悉linux的操作,所以对于我这个菜鸟我也就说几点比较重要的小知识点吧. 第一.cd指 ...
- Java学习过程中的总结的小知识点(长期更新)
Java学习过程中的总结的小知识点 (主要是自己不会的知识和容易搞错的东西) 计算某个程序运行的时间 long stime=System.currentTimeMillis(); copy3(file ...
- 【转】HTML5的小知识点小集合
html5的小知识点小集合 html5知识 1. Doctype作用?标准模式与兼容模式各有什么区别? (1).<!DOCTYPE>声明位于位于HTML文档中的第一行,处于<h ...
- AngularJS的小知识点
小知识点:$scope和$rootScope (1)每次使用ngController指令,都会调用控制器的创建函数,创建出一个控制器对象. (2)每次创建一个控制器对象,AngularJS都会创建一个 ...
随机推荐
- Leetcode | substr()
求子串当然最经典的就是KMP算法了.brute force算法在leetcode上貌似也有一些技巧. brute force: char* StrStr(const char *str, const ...
- POJ 1185 经典状压dp
做了很久的题 有注释 #include<stdio.h> #include<string.h> #include<algorithm> #include<ma ...
- Memcached 笔记与总结(2)编译 php-memcache 扩展
环境:CentOS 6.6 + Apache 2.2.21 + PHP 5.3.10 php-memcache 是 php 写的 memcached 的客户端,以扩展的形式发布. 对于正在运行的 ph ...
- 优秀而又实用的PHP工具集锦
优秀而又实用的PHP工具集锦 浏览:1141 发布日期:2013/09/04 分类:技术分享 PHP是目前实用最为广泛的服务器端开源脚本语言之一,很多优秀的开源程序都是基于PHP构建的,比如大名鼎 ...
- Ruby--正则
1. 只取数字(用的是字符串替换) gsub(/[^0-9]/, “”)
- REST性能测试方案
1.REST简介 REST(代表性状态传输,Representational State Transfer)是一种Web服务设计模型.REST定义了一组体系架构原则,您可以根据这些原则设计以系统资源为 ...
- laravel paginate动态分页
1.router Route::get('product', function(){ $products = App\Product::paginate(10); return view('produ ...
- freemarker 自定义标签
1.编写标签类 package com.pccw.business.fnd.common.filegen; import java.io.IOException; import java.io.Wri ...
- [have_fun] 好玩哒小游戏又来啦
联机贪吃蛇,相互厮杀,试一下吧! http://splix.io/
- linux实现c多进程
线程(thread)技术早在60年代就被提出,但真正应用多线程到操作系统中去,是在80年代中期,solaris是这方面的佼佼者.传统的Unix也支持线程的概念,但是在一个进程(process)中只允许 ...