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属性

view.transform = CGAffineTransformMakeTranslation(CGFloat tx,  CGFloat ty) ;
view.transform = CGAffineTransformMakeScale(CGFloat sx, CGFloat sy);
view.transform = CGAffineTransformMakeRotation(CGFloat angle)  //注意:angle是弧度制,并不是角度制

在某个transform的基础上进行叠加

CGAffineTransform CGAffineTransformTranslate(CGAffineTransform t, CGFloat tx, CGFloat ty);
CGAffineTransform CGAffineTransformScale(CGAffineTransform t, CGFloat sx, CGFloat sy);
CGAffineTransform CGAffineTransformRotate(CGAffineTransform t, CGFloat angle);
 
清空之前设置的transform属性    view.transform = CGAffineTransformIdentity;

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的更多相关文章

  1. [BS] 小知识点总结-05

    [BS] 小知识点总结-05 1. 不论UIWindow的rootViewController是navC.tabBarC还是VC,也不管modalVC和rootVC中间隔着多少个VC,但是modal出 ...

  2. [BS] 小知识点总结-04

    1. ios新知识学习思路: 在开发过程中如果遇到某种新需求以前从未做过,例如改变textField的Placeholder颜色,有如下思路和途径: 1.1 在Storyboard/Xib辅助编辑器A ...

  3. [BS] 小知识点总结-02

    1.  dispatch_GCD 可让某操作延迟x秒执行 //模拟网速慢,延迟3s返回数据(就会导致右侧数据和左侧标签不对应) dispatch_after(dispatch_time(DISPATC ...

  4. [BS] 小知识点总结-01

    1. UIImageView *imgView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"MainTitle&quo ...

  5. android 小知识点

    小知识点总结 1. android中MotionEvent.ACTION_CANCEL事件如何被触发? 对于这个问题,android文档的说明很简短,想看明白很难.国外一网页说的还比较详细,写在这里分 ...

  6. 刚接触Linux,菜鸟必备的小知识点(一)

    身为一个将要大四的学生,而且还是学计算机的没有接触过linux简直是羞愧难当.这个假期做了一个软件测试员,必须要熟悉linux的操作,所以对于我这个菜鸟我也就说几点比较重要的小知识点吧. 第一.cd指 ...

  7. Java学习过程中的总结的小知识点(长期更新)

    Java学习过程中的总结的小知识点 (主要是自己不会的知识和容易搞错的东西) 计算某个程序运行的时间 long stime=System.currentTimeMillis(); copy3(file ...

  8. 【转】HTML5的小知识点小集合

    html5的小知识点小集合 html5知识   1.  Doctype作用?标准模式与兼容模式各有什么区别? (1).<!DOCTYPE>声明位于位于HTML文档中的第一行,处于<h ...

  9. AngularJS的小知识点

    小知识点:$scope和$rootScope (1)每次使用ngController指令,都会调用控制器的创建函数,创建出一个控制器对象. (2)每次创建一个控制器对象,AngularJS都会创建一个 ...

随机推荐

  1. Leetcode | substr()

    求子串当然最经典的就是KMP算法了.brute force算法在leetcode上貌似也有一些技巧. brute force: char* StrStr(const char *str, const ...

  2. POJ 1185 经典状压dp

    做了很久的题 有注释 #include<stdio.h> #include<string.h> #include<algorithm> #include<ma ...

  3. Memcached 笔记与总结(2)编译 php-memcache 扩展

    环境:CentOS 6.6 + Apache 2.2.21 + PHP 5.3.10 php-memcache 是 php 写的 memcached 的客户端,以扩展的形式发布. 对于正在运行的 ph ...

  4. 优秀而又实用的PHP工具集锦

    优秀而又实用的PHP工具集锦   浏览:1141 发布日期:2013/09/04 分类:技术分享 PHP是目前实用最为广泛的服务器端开源脚本语言之一,很多优秀的开源程序都是基于PHP构建的,比如大名鼎 ...

  5. Ruby--正则

    1. 只取数字(用的是字符串替换) gsub(/[^0-9]/, “”)

  6. REST性能测试方案

    1.REST简介 REST(代表性状态传输,Representational State Transfer)是一种Web服务设计模型.REST定义了一组体系架构原则,您可以根据这些原则设计以系统资源为 ...

  7. laravel paginate动态分页

    1.router Route::get('product', function(){ $products = App\Product::paginate(10); return view('produ ...

  8. freemarker 自定义标签

    1.编写标签类 package com.pccw.business.fnd.common.filegen; import java.io.IOException; import java.io.Wri ...

  9. [have_fun] 好玩哒小游戏又来啦

    联机贪吃蛇,相互厮杀,试一下吧! http://splix.io/

  10. linux实现c多进程

    线程(thread)技术早在60年代就被提出,但真正应用多线程到操作系统中去,是在80年代中期,solaris是这方面的佼佼者.传统的Unix也支持线程的概念,但是在一个进程(process)中只允许 ...