关于函数和闭包的介绍
image.png image.png在Swift中定义的Enum,OC中使用
Swift中定义如下,注意@objc
import Foundation
import IQKeyboardManagerSwift
@objc enum RotateState: Int {
case RotateStateDisable
case RotateStateEnable
case RotateStateCameraLive
}
class SystemInitManager: NSObject {
@objc var allowRotation: RotateState = .RotateStateDisable
//MARK: 单例
@objc static let shared = SystemInitManager()
private override init() {
super.init()
}
func config() {
ZYNetworkManager.sharedInstance()
IQKeyboardManager.sharedManager().enable = true
}
}
在OC中使用方法如下:
SystemInitManager.shared.allowRotation = RotateStateRotateStateEnable;
不能用OC的写的类去继承Swift的类
stackoverflow
init 与 viewDidLoad调用顺序
参考链接
init 与 viewDidLoad调用顺序在UITabBarController及其之类中,viewDidLoad调用在先;在其他Controller中,init调用在先;
判断是否是iPhone X方法
class func isIphoneX() -> Bool {
let app = UIApplication.shared
let statusBar = app.value(forKey: "statusBar") as AnyObject
guard let _ = NSClassFromString("UIStatusBar_Modern") else {
return false
}
if statusBar.isKind(of: NSClassFromString("UIStatusBar_Modern")!) {
return true
} else {
return false
}
}
Attention
服务器获取的JSON在Swift中会被表示成一个[String: Any]的字典
Dictionary 为 [:] 和 nil的时候
let dic1: [String: String] = [:]
let dic2: [String: String]? = nil
ZYPrint(markStr: "dic1.count", message: dic1.count)
ZYPrint(markStr: "dic2.count", message: dic2?.count)
if dic1.isEmpty {
print("dic1.isEmpty")
}
if (dic2?.isEmpty)! {
print("dic2.isEmpty")
}
输出如下
****************************************
dic1.count:
0
****************************************
dic2.count:
nil
dic1.isEmpty
最后还会crash
UserDefaults
Objective-C中需要调用 synchronize 方法进行同步, 但是在Swift中已经废弃了该方法, 所以不需要手动去调用.
-synchronize is deprecated and will be marked with the NS_DEPRECATED macro in a future release.
给系统类添加属性
参考Alamofire
extension URLSession {
private struct AssociatedKeys {
static var managerKey = "URLSession.ServerTrustPolicyManager"
}
var serverTrustPolicyManager: ServerTrustPolicyManager? {
get {
return objc_getAssociatedObject(self, &AssociatedKeys.managerKey) as? ServerTrustPolicyManager
}
set (manager) {
objc_setAssociatedObject(self, &AssociatedKeys.managerKey, manager, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
}
}
判断是否是iPhone X
注意这里判断是否属于某个类型的方法
func isIphoneX() -> Bool {
let app = UIApplication.shared
let statusBar = app.value(forKey: "statusBar") as! UIView
guard let statusClass = NSClassFromString("UIStatusBar_Modern") else {
return false
}
if statusBar.isKind(of: statusClass) {
return true
} else {
return false
}
}
as & as! & as?
http://blog.csdn.net/h454036111/article/details/49151933
一,as
摘自中文api的话:仅当一个值的类型在运行时(runtime)和as模式右边的指定类型一致 - 或者是该类型的子类 - 的情况下,才会匹配这个值。如果匹配成功,被匹配的值的类型被转换成as
模式左边指定的模式。
首先是运行时 就不多说了 ,重要的是 as 应用条件有2种情况:
1,和 "as" 右边类型一致
2,是右边类型的子类(这种情况在java里叫向上转型)
事例代码如下:
二,as!
上例中 第二种情况 2,是右边类型的子类 如果 碰到as 左边类型是右边类型的父类则会报错!(as不可以用于父类转子类,用java话说,不支持向下转型),由此可用as!(强转)
编译器也会提示你用as!, as!强转如果类型不符合会报错。
三,as?
as? 相当于optional类型,如果转换失败返回nil。
上代码!
定义属性有些可以不用加?
看看这里返回的方式
class PageContentView: UIView {
// MARK:- 定义属性
fileprivate var childVcs : [UIViewController]
fileprivate weak var parentViewController : UIViewController?
fileprivate var startOffsetX : CGFloat = 0
fileprivate var isForbidScrollDelegate : Bool = false
// weak只能修饰可选类型
weak var delegate : PageContentViewDelegate?
// MARK:- 懒加载属性,
fileprivate lazy var collectionView : UICollectionView = {[weak self] in //闭包里面self 加weak
// 1.创建layout
let layout = UICollectionViewFlowLayout()
layout.itemSize = (self?.bounds.size)! // 可选链返回的一定是可选类型,所以这里要解包,一定有值,所以强制解包!
layout.minimumLineSpacing = 0
layout.minimumInteritemSpacing = 0
layout.scrollDirection = .horizontal
// 2.创建UICollectionView
let collectionView = UICollectionView(frame: CGRect.zero, collectionViewLayout: layout)
collectionView.showsHorizontalScrollIndicator = false
collectionView.isPagingEnabled = true
collectionView.bounces = false
collectionView.dataSource = self
collectionView.delegate = self
collectionView.scrollsToTop = false
collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: ContentCellID)
return collectionView
}()
// MARK:- 自定义构造函数
init(frame: CGRect, childVcs : [UIViewController], parentViewController : UIViewController?) {
self.childVcs = childVcs
self.parentViewController = parentViewController
super.init(frame: frame)
// 设置UI
setupUI()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
关于for循环
for _ in 0..<4 {
}
for view in cell.contentView.subviews {
}
for (index, value ) in array {
}
这三个替代以前的
for (int i = 0, i < array.count, i++) {
}
cell 注册相关
以后还是注册一下比较好,养成习惯
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
/*代码创建,并且没有注册cell的情况下,用dequeueReusableCell(withIdentifier identifier: String) -> UITableViewCell?
如果已经注册了,或者用的xib,就使用dequeueReusableCell(withIdentifier identifier: String, for indexPath: IndexPath) -> UITableViewCell
*/
//??空合运算符,a ?? b,对可选类型a进行判断,为nil默认值为b,不为空就解封
let cell = tableView.dequeueReusableCell(withIdentifier: reuseIdentifier) ?? UITableViewCell(style: .subtitle, reuseIdentifier: reuseIdentifier)
let text = datas[indexPath.row]
cell.textLabel?.text = text
cell.textLabel?.textColor = .white
cell.textLabel?.font = UIFont(name: fontNames[fontNumber], size: 24)
cell.backgroundColor = .black
return cell
}
宏定义
swift中是不能使用宏定义语法的,但是因为命名空间的缘故,我们可以给我们的项目添加一个空的Const.swift文件,在其中,我们将原本oc中不需要接受参数的宏,定义成let常量,将需要接受参数的宏定义成函数即可,由于我们的整个项目共享命名空间,我们就可以在项目内的任何地方直接使用Const.swift中定义的这些公共的常量和函数
http://www.jianshu.com/p/5f5f7c4e1dc0
static & class
1,结构体struct和枚举enum的静态属性,静态方法使用static关键字
2,类class的类型属性,类型方法使用class关键字
http://www.hangge.com/blog/cache/detail_520.html
网友评论