MARK: 此篇介绍的是用纯代码自定义封装cell,xib及sb后续更新.
1.创建自定义cell文件,继承UITableViewCell
|
|
2.在控制器中
(1) 注册cell
|
|
(2) cellForRowAtIndex方法中创建自定义cell
|
|
总结:
代码自定义cell要注意cell下子控件的创建及frame约束等.这里只是提供一个思路,抛砖引玉,具体的需求具体对待.
天下事有难易乎?为之,则难者亦易矣;不为,则易者亦难矣。
|
|
|
|
|
|
总结:
代码自定义cell要注意cell下子控件的创建及frame约束等.这里只是提供一个思路,抛砖引玉,具体的需求具体对待.
Swift的子类不会自动继承父类的构造器, 若继承, 则满足如下规则:
1.如果子类没有提供任何指定构造器, 那么它将自动继承父类的所有指定构造器
2.如果子类实现了父类所有的指定构造器, 无论如何实现的, 都将自动继承父类的所有便利构造器
1.子类构造器重写了父类的指定构造器, 必须添加override修饰符
2.子类中定义的构造器只是和父类中便利构造器的形参列表, 外部形参名相同, 不算重写
1.如果一个子类没有定义任何构造器, 那么它将自动继承父类中的所有构造器
2.如果一个子类重写父类的所有指定构造器, 那么它将自动继承父类中的所有便利构造器
3.如果一个子类中任意的构造器和父类的便利构造器一模一样, 不算重写, 创建对象的时候也只会显示子类定义的构造器
|
|
|
|
|
|
1.在 Swift 中, 类的初始化器有两种, 分别是Designated Initializer(指定初始化器)和Convenience Initializer(便利初始化器)
2.如果子类没有定义任何的指定初始化器, 那么会默认继承所有来自父类的指定初始化器。
3.如果子类提供了所有父类指定初始化器的实现, 那么自动继承父类的便利初始化器
4.如果子类只实现部分父类初始化器,那么父类其他的指定初始化器和便利初始化器都不会继承。
5.子类的指定初始化器必须要调用父类合适的指定初始化器。
|
|
|
|
|
|
|
|
|
|
|
|
然后在CBWebView的Extension(新建一个类叫 WebViewExtension)中实现oc调用js的代码
|
|
|
|
|
|
隐藏状态栏
|
|
修改状态栏的颜色
|
|
|
|
|
|
|
|
摘自中文api的话:仅当一个值的类型在运行时(runtime)和as模式右边的指定类型一致或者是该类型的子类的情况下,才会匹配这个值。如果匹配成功,被匹配的值的类型被转换成as模式左边指定的模式。
首先是运行时就不多说了,重要的是 as 应用条件有2种情况:
|
|
示例代码:
|
|
少数用法:
(1) 消除二义性,,数值类型转换
|
|
(2) switch语句中进行模式匹配
如果不知道一个对象是什么类型,你可以通过switch语法检测它的类型,并且尝试在不同的情况下使用对应的类型进行相应的处理。
|
|
上例中 第二种情况,左边是右边类型的子类,如果碰到 as 左边类型是右边类型的父类则会报错!(as不可以用于父类转子类,用java话说,不支持向下转型),由此可用as!(强转) ,如果转换失败会报 runtime 运行错误。
|
|
as? 和 as! 操作符的转换规则完全一样。但 as? 如果转换不成功的时候便会返回一个 nil 对象。成功的话返回可选类型值(optional),需要我们拆包使用。
由于 as? 在转换失败的时候也不会出现错误,所以对于如果能确保100%会成功的转换则可使用 as!,否则使用 as?
|
|
|
|
在swift 3中新增加了两种访问控制权限 fileprivate和 open。下面将对这两种新增访问控制做详细介绍。
在原有的swift中的 private其实并不是真正的私有,如果一个变量定义为private,在同一个文件中的其他类依然是可以访问到的。这个场景在使用extension的时候很明显。
|
|
这样带来了两个问题:
|
|
由此,在swift 3中,新增加了一个 fileprivate来显式的表明,这个元素的访问权限为文件内私有。过去的private对应现在的fileprivate。现在的private则是真正的私有,离开了这个类或者结构体的作用域外面就无法访问。
open则是弥补public语义上的不足。
现在的pubic有两层含义:
|
|
继承是一件危险的事情。尤其对于一个framework或者module的设计者而言。在自身的module内,类或者属性对于作者而言是清晰的,能否被继承或者override都是可控的。但是对于使用它的人,作者有时会希望传达出这个类或者属性不应该被继承或者修改。这个对应的就是 final。
final的问题在于在标记之后,在任何地方都不能override。而对于lib的设计者而言,希望得到的是在module内可以被override,在被import到其他地方后其他用户使用的时候不能被override。
这就是 open产生的初衷。通过open和public标记区别一个元素在其他module中是只能被访问还是可以被override。
|
|
|
|
现在的访问权限则依次为:open,public,internal,fileprivate,private。
有的人会觉得访问权限选择的增加加大了语言的复杂度。但是如果我们思考swift语言的设计目标之一就是一门安全的语言(“Designed for Safety”)就能理解这次的改动。更加明确清晰的访问权限控制可以使程序员表达出更准确的意图,当然也迫使在编码时思考的更加深入。
用let修饰的变量会是一个不可变的常量, 也就是说不可以对它进行修改, 但如果用let修饰的常量是一个类, 那么我们可以对其所在的属性进行修改, 比如:
|
|
这里边的name就是不可变的, 如果非要去改变, Xcode会建议你把let修改成var.
PS: 如果这个时候, 再声明一个person常量去引用personInfo, 那么person的所指向的内存块是和personInfo相同的.
用var关键字声明的变量将会是一个可变的变量, 在这里, 我们并不会用var去引用一个类, 也没有必要, 继续拿上面的例子来说:
|
|
这里面的age就是属于var类型, 在初始化之后, 我们仍然可以给它进行修改.
PS: 如果这个时候, 我们用var修饰personMode变量去引用personInfo, 那么personMode和personInfo所指向的内存块并不同, personMode会将personInfo完整的拷贝一份, 然后放在另外一块内存块去管理.
在Swift当中, 我们是使用Class关键字去声明一个类, 比如:
|
|
在Swift中, 如果我们需要声明一个结构体, 我们就需要使用到struct关键字, 比如:
|
|
而我们需要声明枚举的时候, 我们就使用enum关键字, 比如:
|
|
在Swift当中的enum和Objective-C并不一样, Swift的enum不会被隐式赋值为0, 1, 里面的zhangsan就是这个枚举分支的完整值, 并且在Swift中, 我们可以给enum case声明各种类型, 比如里面的case luoliu一样.
当然, 我们也可以给枚举值默认声明一个值, 但在枚举名之前, 要声明是什么类型, 比如:
|
|
在Swift中, 如果我们要重写某个方法, 或者某个属性的话, 我们需要在重写的变量前增加一个override关键字, 比如:
|
|
上面我们介绍了override重写属性或者方法的关键字, 当然有重写, 肯定会有防止重写的关键字, 比如:
|
|
所谓的下标, 其实就可以快捷方式的设置或者获取对应的属性, 而不需要调用对应的方法去获取或者存储, 比如:
|
|
作用:写在func前面,以便于让func可以修改struct和protocol的extension中的成员的值。 如果func前面不加mutating,struct和protocol的extension中的成员的值便被保护起来,不能修改.
mutating这个关键字指的是可变, 只能用在struct和enum当中,为的就是可以方便我们在特定环境下, 需要在struct中修改对应的属性值, 比如:
|
|
用static修饰的变量或者方法, 就会变成静态变量和静态方法, 并且保证在对应的作用域当中只有一份, 同时也不需要依赖实例化, 比如:
|
|
在方法的func关键字之前加上关键字static或者class都可以用于指定类方法.
不同的是用class关键字指定的类方法可以被子类重写, 如下:
override class func work() {
print(“Teacher: University Teacher”)
}
但是用static关键字指定的类方法是不能被子类重写的, 根据报错信息: Class method overrides a ‘final’ class method.
我们可以知道被static指定的类方法包含final关键字的特性–防止被重写.
就是swift中的懒加载
被lazy关键修饰的变量, 只有在第一次被调用的时候才会去计算它初始化值的属性, 比如:
|
|
在这里需要注意两点:
1.用lazy修饰的变量必须是用var声明的, 因为属性的初始值可能在实例构造完成之后才会得到。而常量属性在构造过程完成之前必须要有初始值,因此无法声明成延迟属性。
2.如果被lazy修饰的变量没有在初始化时就被多个线程调用, 那就没有办法保证它只被初始化一次了.
在Swift 中也有对应的构造器, 来看看:
|
|
这样子coinsInPurse的值就为1000了.
还有一种用法, 就是在init后面加个”?”号, 表明该构造器可以允许失败
|
|
该关键字是用来修饰init的, 经过convenient修饰的init方法, 表明该init方式是比较次要, 辅助型的, 比如:
|
|
required也是用来修饰init方法的, 用required修饰说明该构造方法是必须实现的, 比如:
|
|
PS: 如果一个子类继承了父类required修饰的init方法, 就必须得去实现该init方法, 但子类可以觉得它之后继承于它的子类可以实现该方法.
在Swift中, 有一个类似dealloc方法, 就是deinit, 但有一些区别, dealloc方法是在引用计数为0的时候, 也就是被释放的时候才会调用, 而deinit是在实例不再引用时自动调用, 并且不用手动去管理引用计数, 比如:
|
|
在Swift中, is关键字是用来判断类型所使用的, 比如:
|
|
我们可以遍历一个[NSObject]类型的数组, 判断里面各元素的类型
在Swift 2.0之前, Swift是没有自带的错误信息处理方法, 在2.0更新之后就有了错误信息的处理方法, 让我们来看看.
在这里我们会使用到一个新的语句do-catch, 这个语句和Switch-case有些类似, 但唯独有一点不太一样的就是, 在do-catch语句中需要使用到try关键字, 而Switch-case则不需要, 好了, 下面让我们来看看.
首先我们需要定义一个ErrorType的枚举
|
|
然后我们来写一个方法, 用来获取错误类型
|
|
最后我们使用do-catch语句来获取对应的错误类型
|
|
extension的作用是在不改变原来的类型或者协议基础下增加新的属性或者方法, 比如:
|
|
protocol关键字在Swift中也是属于协议的意思, 所谓的协议就是约束对象, 比如:
|
|
public: 指的是可以访问在一个模块内的任何实体, 也可以通过导入该模块来访问, 也就是我们经常在Objective-C中经常需要导入的.h文件中的方法, 该关键字可以用来修饰变量, 方法, 类, 枚举, 结构体等等之类, 比如:
|
|
internal: 指的是可以访问同一模块源文件中得任何实体, 但不能从模块的外部去访问该源文件中得实体, 同样, internal也可以修饰变量, 方法, 类, 枚举, 结构体等等之类等, 比如:
|
|
private: 指的是限制实体时能在源文件内部使用, 外部不能访问, private也同样可以用来修饰变量, 方法, 类, 枚举, 结构体等等之类, 比如:
|
|