iOS13以后,苹果已经不允许使用launch image方式设置启动页,仅允许launch screen方式,几点注意事项:
- 只需要出2x、3x图,不再需要折腾一堆图片;
- 为了保证在所有机型上不出现图片的压缩拉伸,出图的时候需要注意, 图片的上下区域应该和视图背景色一致,尽量全白
- 为了让启动页多待一会,需要保持AppDelegate的didFinishLaunchingWithOptions函数不结束,如显示启动页的过程完成自动登录操作。
iOS13以后,苹果已经不允许使用launch image方式设置启动页,仅允许launch screen方式,几点注意事项:
而 init?(contentsOfFile: String) 使用有一些注意点。该方法的参数是图片的全路径,所以需要通过 Bundle 来获取,而且需要带上后缀名。需要注意的是,如果图片放置在 Assets.xcassets 中,Bundle 是无法获取到的,需要直接复制到项目中。
KVC的应用场景:
1.字典转模型 ,简化代码量
2.修改系统的只读变量: 例如自定义tabBar的时候,由于tabBar是只读属性,只能用KVC赋值.
3.可以任意修改一个对象的属性和变量(包括私有变量)
4.可以通过运算符层次查找对象的属性:keyPath
1
2
3
4Teacher *t = [Teacher alloc ] init];
t.chiild = [Child alloc ] init];
t.child.book = [Book alloc] init];
XBLog(@"%@",ValueForKeyPath(@"child.book"));
KVO(Key-Value Observing)监听属性值,可以用来动态更新页面
1 | import UIKit |
UIDevice.current.identifierForVendor.uuidString 是给Vendor标识用户用的,每个设备在所属同一个Vender的应用里,都有相同的值。其中的Vender是指应用提供商,但准确点说,是通过BundleID的反转的前两部分进行匹配
字符串处理函数
a. Scanner
1 | var uint64:UInt64 = 0 |
b. removeAll
1 | var str = "a:b:123" |
c. drop
1 | var str = "aaa:b:a:123" |
d. filter
1 | let cast = ["Vivien", "Marlon", "Kim", "Karl"] |
e. PersonNameComponents
NSClassFromString: 这个方法判断类是否存在;如果这个函数返回nil,原因有可能为:
a. swift 写的代码必须将“-ObjC”标志添加到“Other Linker Flags”构建设置
b. 未加载! 在Other Linker Flags 中添加配置:-all_load 加载所有
NSStringFromClass
NSSelectorFromString: 判断某个方法是否存在
NSProtocolFromString
//应用场景:第三方库版本变更? 父类中调用子类的函数?
1 | let selector = NSSelectorFromString("remove") |
Range (0..<5)、 ClosedRange (0…5)
布局方式
a. xml布局
b. 代码布局:LinearLayout
控件
a. Button
b. TextView
c. ImageView …
四大组件
a. 服务
b. activity
c. content provider
d. broadcast receiver
Context
Application
关联对象Associated Object,相关函数
1 | objc_getAssociatedObject(id _Nonnull object, const void * _Nonnull key) |
可能的应用场景:给系统控件增加属性
runtime
1 | appInit() { |
struct和class之间的抉择:
a. 默认选struct: 拷贝赋值型,影响相对较小
b. 与OC交互时,需要使用class型
c. 需要区分不同实例的时候,使用class(操作符===)
KVO/KVC/Keypath/NSKeyValueObservation !!!
单例
1 | //通用单例 |
自动打包 fastlane
故障现象:xcode log日志显示如下错误,并且相关请求出错1
2
3
4
5
6
7
8
92019-07-17 11:38:19.396278+0800 Homecare[10181:3941027] CredStore - performQuery - Error copying matching creds. Error=-25300, query={
class = inet;
"m_Limit" = "m_LimitAll";
ptcl = htps;
"r_Attributes" = 1;
sdmn = Users;
srvr = "cloud.demo.cn";
sync = syna;
}
原因:ios系统验证网站的证书出错 (ps:不过不知道什么原因,这个故障是偶现的^)
处理:无条件信任我们自己的服务器,不需要进行证书校验1
2
3
4
5
6
7
8
9
10
11
12init() {
//关闭认证
let configuration = URLSessionConfiguration.default
configuration.httpAdditionalHeaders = Alamofire.SessionManager.defaultHTTPHeaders
configuration.urlCredentialStorage = nil
let policies: [String: ServerTrustPolicy] = [
"cloud.demo.cn": .disableEvaluation
]
super.init(configuration: configuration,serverTrustPolicyManager: ServerTrustPolicyManager(policies: policies))
}
1 | let subView = UIView() |
故障现象:运行的时候发现subview自动生成了midx=0,midy=0,height=0,width=0的约束代码
解决方案:关掉自动生成约束代码的功能1
2
3let subView = UIView()
subview.translatesAutoresizingMaskIntoConstraints = false
.......
故障现象:
app发送https://cloud.fanmiot.cn/rest/things请求,结果返回ats报错,日志如下:1
2
3
42019-07-23 09:26:33.044872+0800 Homecare[5571:122357] Task <5547B0FE-DA52-400E-AF8E-D97453C9F2B0>.<1> finished with error - code: -1022
2019-07-23 09:26:33.046236+0800 Homecare[5571:122356] Task <5547B0FE-DA52-400E-AF8E-D97453C9F2B0>.<1> load failed with error Error Domain=NSURLErrorDomain Code=-1022 "The resource could not be loaded because the App Transport Security policy requires the use of a secure connection." UserInfo={NSLocalizedDescription=The resource could not be loaded because the App Transport Security policy requires the use of a secure connection., NSErrorFailingURLStringKey=http://undefined/rest/things, NSErrorFailingURLKey=http://undefined/rest/things, _NSURLErrorRelatedURLSessionTaskErrorKey=(
"LocalDataTask <5547B0FE-DA52-400E-AF8E-D97453C9F2B0>.<1>"
), _NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask <5547B0FE-DA52-400E-AF8E-D97453C9F2B0>.<1>, NSUnderlyingError=0x600003f18b10 {Error Domain=kCFErrorDomainCFNetwork Code=-1022 "(null)"}} [-1022]
故障原因:
https://cloud.fanmiot.cn/rest/things不可达时,服务器端自动跳转到了http://undefined/rest/things页面……
故障现象:1
2
3
4
5
6
7
8class aViewController {
override func viewDidLoad() {
super.viewDidLoad()
let vc = bTabelViewController()
view.addsubView(vc.view)
}
}
问题原因:
vc是函数内的局部变量,函数执行结束就被释放掉了;bTabelViewController的cell是根据数据动态生成的;而这些数据也随着vc的释放而消失了……
所以需要将let vc = bTabelViewController() 移到函数外
问题代码:1
2
3
4let startPoint = mapView.convert(start.coordinate, toPointTo: mapView)
let endPoint = mapView.convert(end.coordinate, toPointTo: mapView)
......
self.view.layer.addSublayer(lineLayer)
问题分析:
将经纬度转成view坐标是以mapview为参考,实际作用于view;所以当view和mapview不重合时就出现问题了,修正后代码:1
2
3
4let startPoint = mapView.convert(start.coordinate, toPointTo: view)
let endPoint = mapView.convert(end.coordinate, toPointTo: view)
......
self.view.layer.addSublayer(lineLayer)
将导航栏设置为透明1
2
3
4
5
6 //背景设置为空
self.navigationController?.navigationBar.setBackgroundImage(UIImage(), forBarMetrics: .Default)
//去除横线
self.navigationController?.navigationBar.shadowImage = UIImage()
//设置为透明
self.navigationController?.navigationBar.isTranslucent = true
导航栏的颜色随着滚动条上翻渐渐从透明变成不透明
此时注意,一定需要将istranslucent设为true,不然不管怎么改alpha值,导航栏都会有背景色。1
2
3
4
5
6
7
8
9
10
11
12
13
14func scrollViewDidScroll(_ scrollView: UIScrollView) {
let offset = scrollView.contentOffset.y
//大标题模式下的数值
if offset <= -88 {
naviAlpha = 0
} else if offset < -22 {
naviAlpha = (offset+88)/64
} else {
naviAlpha = 1
}
let image = UIImage.imageWithColor(Colors.naviBackground.withAlphaComponent(naviAlpha))
navigationController?.navigationBar.setBackgroundImage(image, for: .default)
}
锚点(参考 https://www.cnblogs.com/ybw123321/p/5394408.html)
视图的平移、翻转都是以锚点为中心进行,所以希望达到向某个点
实例可以参考:https://github.com/LynnCheng/DropdownMenu