#总结 swift 语言
1.创建一个控件的两种方式
从 xib(storyboard) 加载
一定会调用
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
从 xib(storyboard) 加载
一定会调用
override init(frame: CGRect) {
super.init(frame: frame)
}
此时也一定要实现
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
因为 一个自定义的控件类 A中有部分或者所有的子控件都是通过代码创建的.如果 xib 中某个控件也使用了 A, 很有可能导致子控件显示不全,或者部分控件无法控制,或者界面凌乱.自定义的控件类也有可能要求只允许通过代码创建—因此为了防止这种事情发生在 init?(coder aDecoder: NSCoder) 方法中,当xib 使用了只能通过代码创建的类,就会抛出一个错误以提示用法错误
2.button 按照背景图片设置大小
- 添加图片后,调用 sizeToFit 方法
3.重写layoutSubViews 方法时注意点
- layoutSubViews 方法中一定要调用父类的layoutSubViews 方法,否则会出现各种问题
4.控件使用 center 确定位置问题
- 开发中子控件的 center 尽量不要使用父控件的 center 计算,因为参照物不同
- UIView 中控件的 frame 和 center 都是相对于父控件的,参照物是父控件, bounds 的参照物是自身
- 例如 控件 A 包含 B,B 包含 C
- B 的 center 是(50,50)
- 此时如果设置 C 的 center 等于 B 的 center, 那么 C 就会在 A 的(100,100)处
- B 的 center 是(50,50)
5.监听事件找不到私有方法
- 监听事件要执行的方法,在 Swift 中如果使用private修饰的话,运行循环是找不到这个方法的
- 因为 Swift 是静态语言,会在编译的时候就决定某个方法某个类有什么方法,而 private 修饰的方法,在运行的时候,运行循环是找不到的
- OC 是基于消息机制动态语言
- 在 private 前用@ objc 修饰就可以解决这个问题
6.约束更新动画
setNeedsLayout与 laoutIfNeeded 的区别
* setNeedsLayout 设置需要重新布局(系统会在合适的时间去布局)
* laoutIfNeeded 如果需要重新布局,系统会立马布局
7.awakFromNib 与 init(coder:)的区别
- awakeFromNib 表示所有子控件都已经连线成功
- 意味着所有子控件都已经通过 xib 加载完成,都是有值的
- 在 init(coder:)中.子控件尚未连线
- 意味着子控件尚未完成加载,不能在此方法中正确的获取子控件
8.控制器 push 时右边黑影问题
当设置viewController.hidesBottomBarWhenPushed = true后,控制区 push 时有可能会在右上角闪过黑影
解决办法:
给 tabBar 设置一个背景图片就好了
9.使用 autolayout 就必须关闭 autoresizing
10.Swift 中协议
- protocol 开头
- 必须实现基协议
- NSObjectProtocol
- 如果不继承基协议,定义的 Delegate 对象就不能使用 weak 修饰
- 实现协议
- 与继承类方式相同,在:后添加协议类
- 必须实现协议中必须实现的方法
11.Swift 项目名中文开头,数字结尾问题
Swift 项目名中文开头,运行时会报错,很难找到
解决办法:把 productName 改为英文名字
墙裂建议:使用英文作为项目名或者只用中文
12.@noescape 修饰的闭包
- 在闭包中使用属性都需要使用 self.XX 属性
- @noescape 修饰的闭包调用外部变量时,不需要使用 self,
因为它修饰的闭包不会传入到其他类中,仅限于闭包出现的地方调用
13.Swift 与 OC 混编
- Swift 调用 OC -> 只要在桥接文件里面导入需要调用的 OC 的头文件就可以了
- OC 调用 Swift -> 只要在OC的类中 import “ProductName-Swift.h” 就可以了
- 自已创建 BridgeHeader –> 找到 BuildSetting -> 搜索
bridg
–> 配置桥接文件路径
14.webView加载某个网页(请求)时,会回调的方法
func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool
15.Swift提取公共语句
- 如果想向 OC 中的 pch 文件一样,在一个文件里写例如屏幕宽度,导入某些头文件,甚至定义一些公用方法, swift 有一个比较简单的方式
- 创建一个 Swift 文件即可–类似于 OC 中的 pch
- 创建的文件不需要定义类,直接在导入 UIKit 文件后面写公用的属性,常量,方法就行了,因为 swift 中文件是全局公用的
16.scrollView滚动时与 pagecontroll 联动页数问题
当滚动到一个页面,超过屏幕的一半时,此时pageControl也指示到该页
* 假设当前 scrollView 的滚动方向为横向滚动,滚动位置 offsetX, scrollView 的宽为 width
* 那么当前页数的计算公式 currentPage = Int((offsetX/ width) + 0.5)
* 在计算结果上加0.5是变相的做了四舍五入操作,例如当前offsetX/ width的结果是0.5(或者大于0.5的数),那么此时新的一页(第1页,前面是第0页)就占据了屏幕的一半以上,所以指示器也应该指示到该页,加上0.5后就相当于四舍五入到该页了
17.设置 button 文字与图片的距离
设置 iamgeViewEdgeInsets或者 titleEdgeInsets
18.计算当前时间经过 N 秒后的时间
使用 dateByAddingTimeInterval(double)
19.上传到 appStore 被拒后不能再上传该版本问题
- 如果在上传到 appStore 时,1.0被拒后,不能再提交1.0,只能shagn上加
- 解决办法如果修改了 build 后就可以再提交1.0了
20.重写了 setValue 后一定要调用父类的 setValue
21.swift 的 属性set 方法
- swift 中如果给一个属性设置值,会调用它的 didSet
- swift 中在 init 中设置属性,不会调用属性中的 didset 方法
22.tableView 自动计算行高
要设置以下两个属性:
- self.tableView.estimatedRowHeight = 150 设置预估行高
- self.tableView.rowHeight = UITableViewAutomaticDimension 这个属性可以使系统根据 cell 内容自动计算行高
23.在 xib 给 scrollView 设置约束报错问题
解决方案
- 要把所有添加的子控件添加到一个大的 UIView 上
设置该 UIView 的约束与 scrollView 边界间距都为0,而且如果垂直滚动,约束 horizon居中还有高度与最后一个子控件的下边界对齐
24.自定义 barButtonItem后无法左右滑动控制器
解决方法:重新设置手势识别代理
- 事例代码
override func viewDidLoad() {
super.viewDidLoad()
self.interactivePopGestureRecognizer?.delegate = self
}
附加问题 当回到只有一个控制器时,手势仍然能用,但是会导致无法 push 控制器
解决办法
只需要实现一个代理方法
gestureRecognizerShouldBegin(gestureRecognizer: UIGestureRecognizer) -> Bool
,判断当前是否只有一个控制器,没有才能识别滑动手势事例代码
func gestureRecognizerShouldBegin(gestureRecognizer: UIGestureRecognizer) -> Bool {
if childViewControllers.count == 1{
return false
}
return true
}
25.点击导航栏顶部时, tableview无法自动滚动到第一条
默认情况下是会滚动到第一条的
原因:
- 当 tableview 中还有 scrollView 活着 collectionView 时,就不会滚动了
- 因为点击顶部时,只能识别一个基于 ScrollView 的控件,此时多个,因此无法判断该滚动哪一个
解决办法: :实现collectionView的scrollToTop 方法,返回为 false 即可
25.collectionView 的 item 的大小
设置为一个无限循环小数(例如1.333333333333…)时,其大小就不固定,从而导致item 布局错乱
解决办法:item的大小设置为一个确定值,如果计算的是一个无限循环小数 A,把A进行转换,先转化为 int 型B 值–>干掉小数位,再把 B 转化为 float 型值 C, 这样就能解决问题
26.imageView 的图片按照 imageView 的大小填充
- 设置为等比例缩放填充
- 超出部分剪切掉---解决imageView 大小变化乱象
27.网络单张图片按照大小等比例显示
• 要知道图片的大小
○ 首先要下载图片到本地
○ 需要将请求单张图片的数据都返回之后再调用刷新 tableview 的闭包
○ 使用调度组来下载图片,因为首页微博可能有十条微博有单张图片,所以要下载十次
○ 使用 SDWebImage 下载图片
○ 如果是单张图片,那么就缓存,
○ 根据图片的 size 设置 collectionView 的 size 和 itemSize
○ 如果图片太窄,需要判断一下,并调整其宽度
○ 过宽和过高处理