您的位置:首页 > 移动开发 > Swift

Swift 语法小结

2015-08-03 17:52 441 查看
Swift

1.基本数据类型

a. Optional 就是枚举

AnOptional is just an enum

enum Optional<T>{

case None

case Some(T)

}

b.Array的声明

vara=Array<String>()

vara=[String]()

leta=[“A”,”B”,”C”]不可改

letb=a[3]

遍历Array可使用for in

forarray in a{

println(“\(array)”)

}

c.Dictionary

vardic=Dictionary<String,Int>()

vardic=[String:Int]()

dic[“mTitle”]=0//添加数据

vardic=[“title1”:1,”title2”:2]

访问一个dictionary的值将返回Optional

letvalue=dic[“title3”] 返回nil

使用tuple遍历Dictionary

for(key,value) in dic {

println(“\(key)=\(value)”)

}

d.结构体Range 一个起点,一个终点,称之为合理类型,Range是范型

struct Range<T>{

var startIndex:T

var endIndex:T

}

1)在Array中Range中的类型是Int型,因为Array是通过Int索引 Range<Int>

2)String中时String的索引 Range<String.Index>

3)声明

let array=[“a”,”b”,”c”,”d”]

let subArray1=array[2...3] ([“c”,”d”]) 闭区间

let subArray2=array[2..<3] ([“c”]) 左闭右开区间

遍历

for i in 27…104{

println(“i=\(i)”)

}

e.NSObject(swift中所有的类都可以继承NSObject)

Objective-C中所有类的基类,比如UIViewController

f.NSNumber 装数字的类

letn=NSNumber(double:35.5)

将会以自身的值转为int或double

letintversion=n.intValue / n.doubleVaule /n.boolValue

g.NSDate 存储日期,也可以获取当前日期和时间

Calendar,DateFormatter,DateComponents

h.NSData 比特包

传递无类型数据,原始数据

2.数据结构 类,枚举,结构

相同点:a.声明类似 b.可以有自己的属性和方法 c.都可以有自己的函数

不同点:a.Enum本身是不能存储任何值的,可以将值存储在枚举的关联信息中

b.枚举可以有计算型属性

c.结构体和类可以初始化

d.类有继承的性质,类型和转化都属于类的性质

e.枚举和结构体是 值传递,类是 引用传递

3.override 重写父类方法的关键字

final可以将一个方法标为final,表示这个方法不能被重写

4.类和实例都有自己的方法和属性

var d:Double = -10

ifd.isSignMinus {//isSignMinus是否是一个负数

d=Double.abs(d) //取绝对值

}

isSignMinus是实例d的变量或者说是d的属性

abs是Double类的方法(所有对象共享),向该方法中传入需要操作的Double类型的实例

类方法 static func abs(d:Double) -> Double

5.参数名

所有方法所有的参数都有一个内部名和外部名

内部名:在方法中拥有一个本地变量的名字,方法中冒号之前的

外部名:调用者准备使用的,调用方法是在冒号之前的

a.使用外部名

func foo(extenal internal:Int){

let local=internal

}

func bar(){

let result=foo(external: 123)

}

b.不使用外部名 _表示会被忽略,所有方法默认是采用该方式

//func foo(internal:Int)

func foo(_ internal:Int){

let local=internal

}

func bar(){

let result=foo(123)

}

c.强制使用内部名 #

func foo(#internal:Int){

let local=internal

}

func bar(){

let result=foo(internal:123)

}

d.非第一个参数推荐使用内部名和外部名,当然,你可以使用_忽略外表名,但这不是标准的做法

func foo(first:Int,externalSencond second:Double){

let local=second

}

func bar(){

let result=foo(123,externalSencond:5.5)

}

6.Property Observers(属性观察)

var someStoredProperty:Int = 42{

willSet{newValue}//属性设置前被调用

didSet{oldValue}//属性设置后被调用,可以用来对用户界面进行更新

}

override var someStoredProperty{

willSet{newValue}

didSet{oldValue}

}

使用场景:a.在自己的类中需存储属性,当其他方法设置它的值时,获得一个通知

b.当继承了某些类,你并不需要对这些类中的属性做什么修改,但当它们改变时你想知道

7.lazy 只有用到的时候才会被初始化

a.如果使用了很多资源,用lazy是不错的选择

lazy var brain=CalculatorBrain()

b.初始化的时候在后面放一个大括号,也就是通过执行这个闭包来初始化这个属性,但这个闭包直有在property被用到的时候才会执行

lazy var someProperty:Type={

return <the constructed vaule>

}()

c.可以使用一个方法来进行初始化,只有标记为lazy才可以这样用,因为在类初始化之前,类中的方法都是不可以被调用的

lazy var myProperty=self.initializeMyProperty()

8.initialization 初始化

a.无父类的类,默认有一个init()方法

b.如果一个结构体没有初始化,它将默认得到一个将所有属性作为参数的初始化方法,不需要实现

struct MyStruct{

var x: Int=42

var y: String=“moltuae”

init(x:Int,y:String)

}

c.在初始化方法里面可以设置任何属性的值,包括常量和变量

d.在类或结构体中可以调用自己的init方法 self.init(),类中可以调用父类的初始化方法 super.init()

e.在swift中提供两种构造器来初始化, Convenience Init 和 Designated Init(默认)

I.(指定构造器)Designated Init

a.必须在自己的init方法中调用父类的init方法

b.前面父类不能有Convenience

c.在调用父类的init方法前,必须初始化自己的所有属性,必须调用父类的初始化方法,然后才能给父类的属性赋值

II.(便捷构造器)Convenience Init

a.ConvenienceInit只能调用本类的Designated Init,不能调用任何父类的初始化方法

b.它能通过调用其他的Convenience Init间接调用Designated Init ,最后必须调用一个Designated Init

c.必须直接或间接调用Designated Init,然后才能访问其他的值

III.其他构造器,类必须被初始化,才能调用方法和属性

f.继承规则

a.如果类中没有实现任何的Designated Init,那么你将继承父类中的所有Designated Init,否则你将不继承任何一个父类中的Designated Init,也就是要么就不继承一个,要么就继承所有的,对于Convenience Init 也是一样的

b.如果你覆盖了你父类中的所有的Designated Init,重写了所有的这些Designated Init方法,那么你就继承来父类中所有的Convenience Init

c.如果没有实现任何一个初始化方法,你将继承所有的Designated Init和Convenience Init

g.required 初始化(与java中的抽象差不多abstract)

在init方法前面写上required,表示该方法子类必须实现这个方法

h.failable 初始化

有一些初始化允许失败并返回nil (optional)

eg:init?(arg1:Type1,..){

might return nil in heres

}

9.其他

a.UIImage 返回一个图片 optional

let image=UIImage(named:”foo”) 通过名称获取图片

通常写法

if letimage=UIImage(named:”foo”){

//image was successfully created

}else{

//couldn’t create the image

}

b.let button=UIButton.buttonWithType(UIButtonType.System)

join 返回一个由给定的分隔符合并的序列的元素。eg:join(":", ["A","B", "C"]) == "A:B:C"

那么

let separatedArrayElements:String =“,”.join(mArray)返回以逗号分割的字符串

这种写法是表示String有join()属性?

10.AnyObject 主要是用来兼容Objective-C API 和IOS

a.Swift是强类型语言,并有类型推断的特性,所以不推荐使用AnyObject来声明对象

b.AnyObject:指向一个未知对象的指针,也就是一个类的实例

c.使用场景

作为属性,eg:

var destinationViewController:AnyObject

var toolbarItems:[AnyObject]

作为方法参数,eg

func prepareForSegue(segue:UIStoryboardSegue,sender:AnyObject)

作为返回值

class fun buttonWithType(buttonType:UIButtonType) -> AnyObject

d.不能发任何消息,可通过 as 进行强转,eg:

let calcul=destinationViewController as CalculatorViewController

在不确定类型的情况下,可用 as? 返回一个Optional的值,eg:

if let calcul=destinationViewController as? CalculatorViewController{..}

使用 is 判断类型

if destinationViewController is CalculatorViewController{..}

c.AnyObject数组遍历,转换整个数组,不能使用 as? ,数组返回nil是没有意义的

for toolbarItem in toolbarItems as [UIBarButtonItem]{..}

d.lettitle=(button as UIButton).currentTitle

e.类型转换 可以对任何对象进行类型转换,转换的两个对象必须在同一条继承链上,向下转换

11.Array

Array<T>方法

a.+=[T]添加数组

b.first -> T? optional 返回Array的第一个元素

c.last -> T? optional 返回Array的最后一个元素

d.append(T) 添加元素

e.insert(T,atIndex:Int) 插入元素

f.splice(Array<T>,atIndex:Int) 将另一个Array添加到当前Array的指定位置

g.removeAtIndex(Int) 移除指定元素

h.removeRange(Range) 移除指定范围元素

m.replaceRange(Range,[T]) 替换一个范围的元素,替换元素的个数不需要等于被替换元素的个数,也就是可使Array变长

l.sort(isOrderedBefore:(T,T) -> Bool) 排序,eg:a.sort{$0<$1}

n.filter(includeElement:(T) -> Bool) -> [T] 将不需要的元素过滤掉,然后返回过滤后的数组,函数返回值Bool表示是否需要包含该元素

p.map(transform:(T) -> U) -> [U]) 映射,将原来的数组中的每一个元素映射到一个新的数组

e.g.: 将整型数组映射到字符串数组

let stringified:[String] =[1,2,3].map{“\($0)”}

g.reduce(initial:U(初始值), combine: (U,T) -> U) -> U 将整个数组减少为一个值

e.g.: 将整个数组相加 let sum:Int =[1,2,3].reduce(0){ $0+$1}

12.String.Index

a.advance(String.Index,Int)

eg: var s=“Hello”

第一个“l”出现的index

//index=start+distance=0+2

let index=advance(s.startIndex,2) //index is a String.Index to the 3rdglyph,”l”

s.splice("abc",atIndex: index) //s=“Heabcllo”从指定位置插入字符串

let mIndex=advance(s.startIndex,1)

let endIndex=advance(s.startIndex,6)

let subString=s[index..<endIndex] //subString=“abcl”

b.rangeOfString 返回一个Optional Range<String.Index>

e.g.:let num=“56.25”

if let decimalRange = num.rangeOfString(“.”){//找到小数点

//decimalRange 是Range<String.Index>

let wholeNumberPart=num[num.startIndex..<decimalRange.startIndex]//整数

}

c.removeRange 移除指定范围的字符

s.removeRange([s.startIndex..<decimalRange.startIndex])

d.repalaceRange(Range,String) 将某一范围的字符替换成指定字符

e.description -> String

endIndex -> String.Index

hasPrefix(String) -> Bool

hasSuffix(String) -> Bool

toInt() -> Int? 没有To Double()

capitalizedString -> String

lowercaseString -> String

uppercaseString -> String

f.使用指定字符合并字符串数组 join(Array) -> String

e.g:”,”.join([“1”,”2”,”3”])=“1,2,3”

g.以指定字符分割字符串为字符串数组 componentsSparatedByString(String) -> [String]

eg:“1,2,3”. componentsSparatedByString(“,”)=[“1”,”2”,”3”]

13.基本类型转换

let d:Double=37.5

let f:Float=37.5

let x=Int(d)

let xd=Double(x)

let cgf=CGFloat(d) 一种浮点数

let a=Array(“abc”) //a=[“a”,”b”,”c”]

let s=String([“a”,”b”,”c”]) //s=“abc”

14.Assertions断言

Optionals使得我们可以检测值是否存在。在某些情况下,如果某个值不存在或者没有提供特定的满足条件,代码不应该继续往下执行。

在这些情况下,可以使用触发断言来终止执行并提供调试。

断言是在运行时检测条件是否为true,如果为true,就继续往下执行,否则就在这里中断。

assert(() -> Bool,”message”)

e.g.:assert(validation()!=nil,”the validation function returned nil”)

15.其他方法

let count=countElements(aCollection) 集合元素的个数

let sub=dropFirst(aSliceable)

let sub=dropFirst(aSliceable)

let first=first(aCollection) 集合的第一个元素

let last= last(aCollection) 集合的最后一个元素

let prefix= prefix(aSliceable,X:Int)

let suffix=suffix(aSliceable,X:Int)

let reversed:Array=reverse(aCollection)

let backwardsString=String(reverse(s))

16.数据类型的转变

a.NString - String

NArray -Array<AnyObject>

NSDictionary -Dictionary<NSObject,AnyObject>

NSNumber - Int,Float,Double,Bool

b.数据强转

let length=(aString as NSString).length //.length是NSString中的方法,String没有

(anArray as NSArray).componentsJoinedByString(NSString)//componentsJoinedByString是NSArray中的方法

17.NSUserDefaults 小型数据库,它只会存储Property List,当App关闭时,它可以永久保存这些数据,可以自动保存

a.可以像字典一样存储以及导出Property List,其本身就是一个字典

b.方法

setObject(AnyObject, forKey:String) //AnyObject必须是Property List

objectForKey(String) -> AnyObject?

arrayForKey(String) -> Array<AnyObject>?

setDouble(Double,forkey:String)

doubleForKey(String) -> Double //如果找不到则返回0

c.声明

let defaults=NSUserDefaults.standardUserDefaults()

使用:letplist:AnyObject=defaults.objectForKey(String)

defaults.setObject(AnyObject,forKey:String)

e.synchronize() 强制保存数据到磁盘,当App不在前端或处于调试阶段时 是无法自动保存的,这时候就要使用synchronize

e.g.:if !defaults.synchronize(){..} 磁盘不能写入或磁盘已满

18.手动创建View

a.Controller中有个顶层View var view:UIView

addSubview(aView:UIView)

removeFromSuperview()

b.UIView 中有两个初始化方法

init(frame:CGRect) if the UIViewis created in code

init(coder:NSCoder) if the UIViewcomes out of a storyboard

手动创建初始化必须实现这两个方法

func setup(){..}

override init(frame:CGRect){//a designed initializer

super.init(frame:frame)

setup()

}

required init(coder aDecoder:NSCoder){//a required initializer

super.init(coder:aDecoder)

setup()

}

c.awakeFromNib() 表示刚从Storyboard中被加载出来,可以做一些初始化操作

19.坐标系统数据结构

a.坐标的单位是CGFloat,CGFloat在Swift中是结构体

b.CGPont 坐标点,结构体

eg:var point=CGPoint(x:37.0,y:55.2)

point.y -=30

point.x +=20.0

c.CGSize 矩形长和宽,结构体

e.g.:var size=CGSize(width:100.0,height:50.0)

size.width +=42.5

size.height +=75

e.CGRect 由一个CGPoint和CGSize组合的结构体

struct CGRect{

var origin:CGPoint 左上角的点坐标

var size:CGSize

}

let rect = CGRect(origin:aCGPoint,size:ACGSize)

属性和方法

var minX: CGFloat 矩形的左边界

var minY: CGFloat 矩形垂直方向上的中点

intersects(CGRect) -> Bool 两个矩形是否相交

intersect(CGRect) 创建一个更小的矩形,该矩形是两个矩形相交的部分

contains(CGPoint) -> Bool 是否在矩形中

20.控件坐标系统

a.一个点占多少个像素 var contentScaleFactor: CGFloat

b.边界属性 var bounds:CGRect

var center:CGPoint 自身视图矩形的中点,它是相对父视图的坐标系,而不是自身坐标系

var frame:CGRect 用来包含子视图的一个矩形,包含子视图的所有区域包括绘制部分,也是相对父视图的

一般来说,frame size和bounds size 完全相同,但视图View旋转的时候就不一定相同了

21.创建UIView

a.let newView = UIView(frame:myViewFrame)

let newView = UIView() //返回空视图CGRectZero,size和frame都是0

eg:

let labelRect = CGRect(x: 20,y:20,width:100,height:50)

let label=UILabel(frame: labelRect)

label.text = “Hello”

view.addSubview(label) //view是Controller中最顶层的视图

b.不要调用drawRect这个方法!!!

*drawRect是给系统调用的,当视图需要重新绘制时,系统会自动调用drawRect

setNeedsDisplay()

setNeedsDisplayInRect(regionThatNeedsToBeRedrawn: CGRect) 指定某个特定的范围来重绘

c.Core Graphics

22.UIBezierPath 绘制线条,图形

a.绘制三角形

let path=UIBezierPath()创建

path.moveToPoint(CGPoint(x:80,y:50))

path.addLineToPoint(CGPoint(x:140,y:150))

path.addLineToPoint(CGPoint(x:10,y:150))

path.closePath()

UIColor.greenColor().setFill() 内部填充颜色为绿色

UIColor.redColor().setStroke() 描边颜色为红色

path.linewidth=3.0

path.fill()

path.stroke()

b.其他

let roundRect = UIBezierPath(roundedRect: aCGRect,cornerRadius:aCGFloat) 绘制椭圆矩形

let oval = UIBezierPath(ovalInRect: aCGRect) 绘制圆或椭圆

addClip() 剪切任意的Path

funccontainsPoint(CGPoint) -> Bool 碰撞检测

usesEventOddFillRule 是否填充区域

23.UIColor

a.设置透明度

let green=UIColor.greenColor()

let transparentYellow = UIColor.yellowColor().colorWidthAlPhaComponent(0.5)设置颜色透明度 alpha取值0~1 ,0表示完全透明

b.View也可以设置透明度 (不推荐)

var opaque=fasle 设置透明度前必须先设置opaque=false

var alpha:CGFloat,

c.View可以隐藏 var hidden:Bool

24.NSAttributedString 绘制文本

a.let text = NSAttributedString(string:“hello”)

text.drawAtPoint(aCGPoint)

let textSize: CGSize = text.size 获取文本的大小

绘制可变文本:

letmutableText=NSMutableAttributedString(string:“some string”)

b.方法属性

eg:attributes:NSDicitionary

let mAttributes=[NSForegroundColorAttributeName:UIColor.greenColor(),//字体颜色
NSBackgroundColorAttributeName:UIColor.grayColor().colorWithAlphaComponent(0.1),//字体背景色
NSStrokeWidthAttributeName:CGFloat(0.5),//边线宽度
NSStrokeColorAttributeName:UIColor.redColor(),//边线颜色
NSStrikethroughStyleAttributeName:1,//删除线
NSStrikethroughColorAttributeName:UIColor.redColor(),//删除线颜色
NSUnderlineStyleAttributeName:1,//下划线
NSUnderlineColorAttributeName:UIColor.grayColor(),//下划线颜色
NSShadowAttributeName:NSShadow(),//字体阴影
NSFontAttributeName:UIFont.systemFontOfSize(25.0)]//字体
//绘制文本
let text =
NSAttributedString(string: "draw text",attributes:mAttributes)
text.drawAtPoint(CGPoint(x:10,y:250))

25.Font

a.使用推荐的字体

(static for struct,class for class type)

class func preferredFontForTextStyle(UIFontTextStyle) -> UIFont

UIFontTextStyleHeadline

UIFontTextStyleBody

UIFontTextStyleFontnate

eg:UIFont.preferredFontForTextStyle(UIFontTextStyleBody)

b.系统字体

class func systemFontOfSize(pointSize: CGFloat) -> UIFont

class funcboldSystemFontOfSize(pointSize: CGFloat) -> UIFont

eg:UIFont.systemFontOfSize(25.0)

26.显示图片

a.UIImageView

let image: UIImage? = UIImage(named: “foo”) 返回optional

let image: UIImage? = UIImage(contentsOfFile: aString)

let image: UIImage? = UIImage(data: anNSData) //raw jpg,png,tiff等

image.drawAtPoint(aCGPoint) 在左上角显示图片

image.drawInRect(aCGRect) 缩放图片让其适应这个View矩形

image.drawAsPatternInRect(aCGRect) 使图片填满整个区域

b.当View高宽改变时

View 中的属性 var contentMode: UIViewContentMode

让图片重新调整位置

mode: UIViewContentMode.Left/.Right/.Top/.Bottom/.TopRight/.TopLeft/.BottomRight/.BottomLeft/.Center

缩放:.ScaleToFill(默认)/.ScaleAspectFill/.ScaleAspectFit

重新绘制:.Redraw

27.a.在自定义控件中,class前声明@IBDesignable Xcode会自动识别这是一个IBDesignable类,可以让自定义控件的UI显示到视图板上,否则需运行的时候才能出现.

b.自定义控件的变量前配置 @IBInspectable设置自定义属性,可以在外部配置,如在storyboard

28.Extensions

给一个现存的类 结构或枚举添加新方法或属性,不需要修改源代码

a.限制

I.不能通过extension添加一个已存在的方法或属性,也就是不能替换

II.添加的属性不能有存储,只能是运算属性

b.作用:用作软件构架的核心基础

29.Protocols (协议)一种相对简便的表示API的方法,是一种数据类型 (类似于java中的接口Interface)

a.Protocols 本身是没有实现的,没有实现的数据类型,只是声明

b.使用Protocols来声明各种各样的属性和方法

c.使用条件

I.声明protocol

II.类,结构或枚举继承一个protocol必须实现它

III.必须实现protocol中所有的属性和方法

e.eg:

protocol SomeProtocol: InheritedProtocol1, InheritedProtocol2{

//必须定义一个属性是否有get方法或set方法

var someProperty:Int{get set}

fun aMethod(arg1:Double,anotherArgument:String) -> SomeType

// 任何可被改变的函数需要mutating关键字修饰

mutating func changeIt()

init(arg:Type)

}

某个类实现SomeProtocol时,也必须实现InheritedProtocol1,InheritedProtocol2,这两个也是Protocol,相当于SomeProtocol的父类。

f.protocol使用class修饰,说明该protocol只能被类实现,实例已引用被传递

e.g:protocol SomeProtocol: class,InheritedProtocol1, InheritedProtocol2{….. }

g.protocol可以要求实现的类,结构或枚举去实现特定的初始化方法

h.实现

class SomeClass:SuperclassOfSomeClass,SomeProtocol,AnotherProtocol{

required init(..) //初始化必须使用required修饰

}

enum SomeEnum:SomeProtocol,AnotherProtocol{…..}

struct SomeEnum:SomeProtocol,AnotherProtocol{…..}

一旦声明了Protocol就必须实现,否则无法通过编译

还可以使用Extension来扩展属性或方法

extension Something:SomeProtocol{..}

n.使用

protocol Moveable{

mutating fun moveTo(p: CGPoint)

}

class Car:Moveable{

func moveTo(p:CGPoint){…}

func changeOil()

}

struct Shape: Moveable{

mutating fun moveTo(p:CGPoint{…}

fun draw()

}

let prius:Car= Car()

let square: Shape = Shape()

var thingToMove:Moveable=prius

thingToMove.moveTo(..)

thingToMove=square

let thingsToMove:[Moveable]=[prius,square]

func slide(slider:Movearble){

let positionToSlideTo=..

slider.moveTO(positionToSlideTo)

}

slide(prius)

slide(square)

//使用<>,表示x这个参数必须同时实现Slippery和Moveable协议

funcslipAndSlide(x:protocol<Slippery,Moveable>)

eg:

protocol SomeProtocol{
func aMethod(username:String) ->
String
var doubleValue:Double{get
set}
}

class DrawView:
SomeProtocol{
func aMethod(username:
String) -> String {
return “You are \(username)”
}
var length:Double =
0
var doubleValue:Double {
set{
length = newValue}
get{
return length}
}
}

30.Delegation (代理) Protocol中的一种

a.Delegation是Protocol重要的用途

b.用法

1) 创建一个代理协议Delegation Protocol,它包含了许多方法的Protocol,可能包含属性,它描述了这个View要别人做的事情,也就是View代理给其他人的职责

2) 在View中创建一个delegation属性,称作代理或有时叫做数据源,Delegation Protocol就是属性被声明的类型

3) 使用View中的这个delegation属性去处理所有的代理,只要是任何遵循这个Protocol的对象都可以对这个delegation属性设置

4) Controller必须声明实现这个代理协议

5) Controller会将自身作为代理对象Delegation,它会设置这个视图的代理属性为其自身

6) Controller必须实现这个协议Protocol,实现协议规定的required实现的所有方法

eg: 相当于java接口实例对象,如

protocolSomeProtecol{

func method()

}

class A{

var delegate: SomeProtecol

func doSome(){

delegate.method()

}

var testB:B = B()

func init(){

delegate=testB

}

}

class B : SomeProtecol {

impl...

}

31.weak 指针的内存管理,相互引用时,无法释放内存,变量声明为weak,那么这个对象无论指向什么对象,这个被指向的对象都不应该保留在内存中

32.Gestures

一般识别View手势的对象是Controller

l UITabGestureRecognizer 拍击,任意次数的拍击

l UIPinchGestureRecognizer 向里或向外捏,用于缩放

l UIPanGestureRecognizer 摇动或拖拽,拖动

l UISwipeGestureRecognizer 擦碰,以任意方向

l UIRotationGestureRecognizer 旋转,手指朝向反方向移动

l UILongPressGestureRecognizer 长按

a.使用步骤

I. 为视图添加手势识别器addGestureRecognizer

II.当创建手势识别器的时候,必须指定一个对象,如果视图识别了这个手势,就报告给这个对象

b.UIPanGestureRecognizer

@IBOutlet weak var pannableView:UIView{

didSet{

//参数:target 当手势被识别时向target对象发送消息,一般这个是个Controller

// action 表示事件处理的方法名称,当事件触发后会调用这个方法,pan:冒号表示该方法后面有一个参数,如果没有冒号,则得不到这个参数

let recognizer=UIPanGestureRecognizer(target:self,action:”pan:”)

pannableView.addGestureRecognizer(recognizer)

}

}

UIPanGestureRecognizer方法

//手势被识别或重置,开始手指移动了多远距离,可以通过setTranslation重置这个起点

fun translationInView(view:UIView) -> CGPoint

//获取滑动的速度

func velocityInView(view:UIView) -> CGPint

funksetTranslation(translation:CGPoint,inView:UIView)

eg:

@IBOutlet
weak var btnMove:
UIButton!{
didSet{
let recognizer =
UIPanGestureRecognizer(target: self, action:
"handlePanGesture:")
btnMove.addGestureRecognizer(recognizer)
}
}
var netTranslation:CGPoint =
CGPoint(x:0,y:0)
func handlePanGesture(sender:
UIPanGestureRecognizer){
var translation:
CGPoint = sender.translationInView(btnMove)
btnMove.transform =
CGAffineTransformMakeTranslation(netTranslation.x+translation.x,
netTranslation.y+translation.y)
if sender.state ==
UIGestureRecognizerState.Ended{
netTranslation.x+=translation.x
netTranslation.y+=translation.y
}

}

c.UIGestureRecognizer 状态

//拖动手势的状态

var state:UIGestureRecognizerState { get }

.Possible状态,表示是一个拖动手势

.Recognized状态 表示一个非连续的手势,或一个swipe

.Began状态 表示拖动手势,即手势连续

.Changed状态 表示手势的移动,识别器会不断通知事件处理对象

.End状态 表示手势离开屏幕

.Canceled/.Failed状态 表示取消手势,如电话打进来时会中断手势

eg:

func pan(gesture:UIPanGestureRecognizer){

switch gesture.state{

//fall through在switch中说明当前case的函数实现,即为下一个case的函数实现,也就是直接跳到下一个case了

//本例中Changed和End执行了相同的代码

case .Changed:fall through

case .End:

lettranslation=gesture.translationInView(pannableView)

getsture.setTranslation(CGPointZero,inView:pannableView)

default:break

}

}

e.UIPinchGestureRecognizer 缩放,传递的是scale

var scale:CGFloat 缩放手势开始的时候,scale=1

varvelocity:CGFloat { get } 用户缩放的速度,只能获取

eg:

@IBOutlet
weak var mDrawView:
DrawView!{
didSet{
let pinchRecognizer=
UIPinchGestureRecognizer(target:
self, action: "handlePinchGesture:")
mDrawView.addGestureRecognizer(pinchRecognizer)
}
}
var lastScaleFactor:CGFloat =
1;
funchandlePinchGesture(sender:UIPinchGestureRecognizer){
let scale=sender.scale
if scale >
1{//放大
mDrawView.transform =
CGAffineTransformMakeScale(lastScaleFactor+scale-1,lastScaleFactor+scale-1)
}else{//缩小
mDrawView.transform =
CGAffineTransformMakeScale(lastScaleFactor*scale,lastScaleFactor*scale)
}
if sender.state ==
UIGestureRecognizerState.Ended {
if scale >
1 {
lastScaleFactor =
lastScaleFactor+scale-1
}else{
lastScaleFactor =
lastScaleFactor * scale
}
}

}

f.UIRotatonGestureRecognizer

var rotation:CGFloat 旋转弧度

varvelocity:CGFloat { get } 速度,只能获取

eg:

@IBOutlet
weak var mDrawView:
DrawView!{
didSet{
let rotationRecognizer =
UIRotationGestureRecognizer(target:
self, action: "handlerRotationGesture:")
mDrawView.addGestureRecognizer(rotationRecognizer)
}
}
var lastRotation:
CGFloat = 1;//旋转
funchandlerRotationGesture(sender:
UIRotationGestureRecognizer){
var rotation:
CGFloat = sender.rotation
mDrawView.transform =
CGAffineTransformMakeRotation(lastRotation+rotation)
if sender.state ==
UIGestureRecognizerState.Ended{
lastRotation += rotation
}
}

g.UISwipeGestureRecognizer

创建一个swipe手势时,必须设置点击所需的次数或滑动的方向

var derection:UISwipeGestureRecoginzerDirection 滑动的方向

varnumberOfTouchesRequired:Int 点击所需的次数

eg:

@IBOutlet
weak var mDrawView:
DrawView! {
didSet{
let swipeRecognizer =
UISwipeGestureRecognizer(target:self, action:"handleSwipeGesture:")
swipeRecognizer.direction =
UISwipeGestureRecognizerDirection.Left
mDrawView.addGestureRecognizer(swipeRecognizer)
}
}

func handleSwipeGesture(sender:
UISwipeGestureRecognizer){
var direction = sender.direction//滑动方向
switch (direction){
case
UISwipeGestureRecognizerDirection.Left:
println("Left")
case
UISwipeGestureRecognizerDirection.Right:
println("Right")
case
UISwipeGestureRecognizerDirection.Up:
println("Up")
case
UISwipeGestureRecognizerDirection.Down:
println("Down")
default:
break
}
}

h.UITapGestureRecognizer

设置点击和触摸的次数,双击(两次点击),可以通知第一次和第二次点击

var numberOfTapsRequired:Int 点击的次数

varnumberOfTouchesRequired:Int 触摸的次数

eg:

@IBOutlet
weak var mDrawView:
DrawView!{
didSet{
let tapRegognizer =
UITapGestureRecognizer(target:
self, action: "handleTapGesture:")
mDrawView.addGestureRecognizer(tapRegognizer)
}
}
var lastScaleFactor:CGFloat =
1;//放大缩小
var scale:CGFloat =
1.1
//双击屏幕时调用此方法
func handleTapGesture(sender:
UITapGestureRecognizer){
if
scale > 1{//放大
mDrawView.transform =
CGAffineTransformMakeScale(lastScaleFactor+scale-1,lastScaleFactor+scale-1)
}else{//缩小
mDrawView.transform =
CGAffineTransformMakeScale(lastScaleFactor*scale,lastScaleFactor*scale)
}
if sender.state ==
UIGestureRecognizerState.Ended {
if
scale > 1 {
lastScaleFactor =
lastScaleFactor+scale-1
scale =
0.8
}else{
lastScaleFactor =
lastScaleFactor *
scale
scale =
1.2
}
}
}

33.UISplitViewController 并列排放的控件

a.2重MVC,并排放,左边称为Master,右边称为Detail

b.只能放在拥有regular size的设备中

c.Master决定了Detail的内容是什么

d.创建

1)拖出Split View Controller并删除所有系统带出的其他的MVC

2)按住Control键拖动,去链接Master和Detail

e.Split View不能在iPhone上并排显示

f.转化为UINavigationController,Editor->Embed in->NavigationController

g.处于compact时,Split是不能平铺的

h.tableviewCell的标识符对应

j.为Master添加Segua选中tableViewCell按住Control拖动到Detail面板

k.必须先删除数据源再移除Table中的项

mData.removeAtIndex(indexPath.row)
tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)

34.Size Classes屏幕适配

a.regular width ,regular height(iPaid)

b.compact width ,compact height (iPhone)

35.UINavigationController 就是一个MVC,它的View由其他MVC组成,可以包含任意数量的MVC

a.它把其他都MVC放在屏幕上,与其他类型的Controller不同的是,它共享这个屏幕。类似Card叠加放置。

b.在多重MVC之间共享一个小的屏幕空间,它会将这些MVC堆起来

36.获取子MVCs

a.通过viewConrollers这个属性去获取Card子项,它们是由UIViewController组成的数组

var viewControllers:[UIViewController] {get set}

Tab bar: 有序的数组

Split view: 只有两个元素,Master是下标为[0]的,Detail是下标为[1]的,设值Push/Pop

Navigation controller: root view[0],剩下的就按顺序排列在栈中

b.如何获取ViewController

var tabBarContoller:UITabBarController?{get}

var splitViewController:UISplitViewController?{get}

var navigationController:UInavigationController?{get}

eg:获取一个splitView的Detail

if(letdetailVC:UIViewController==splitViewController?.viewControllers[1]){…}

37.Segues 从一个viewController转换到另一个viewController,类似于Android的监听器 按Control拖动

a.系统定义了四种Segues,也可以自定义Segues

Show Segue 展示正在交互的MVC

Show Detail Segue在SplitView中就是显示Detail,其他情况和Show Segue的效果一样

Modal Segue 完全布满整个屏幕,不推荐

Popover segue 一个小窗口,并不完全布满整个屏幕,点击窗口外的其它地方该窗口会消失,类似于Android的PopWindow

b.触发Segues可调用方法performSegueWidthIdentifier

func performSegueWidthIdentifier(idenifier:String,sender:AnyObject)

前提条件是:定义了identifier

c.prepareForeSegue

func perpareForSegue(segue:UIStoryboardSegue,sender:AnyObject?){//sender触发这个Segue的控件

if let identifier = segue.identifier{

switch identifier{

case “Show Graph”://某个Segue的identifier

if let vc =segue.destinationViewController as? MyController{

vc.property1=…

vc.callMethodToSetItUp(…)

}

default:break;

}

}

}

d.当你准备创建新的MVC时,它的outlet还没被设定时,这会让你的程序崩溃,也可能产生一些意想不到的行为

38.更改ViewController的命名步骤

a.更改类名

b.双击更改文件名

c.Main.storyboard中选择Custom Class的Class为更名后的ViewController

39.storyboard

a.设置是否固定字体大小 Autoshrink

Minimum Font Size自动根据屏幕缩放字体,但有最小字体的限制

Fixed Font Size固定控件大小

b.storyboard中插入View/Navigation View/Scroll View/Split View,选中控件

c.Label换行

选中Label ->Line Breaks

TruncateTail删减尾部,尾部点点

Word Wrap自动换行

d.UILabel适用于三行内的静态文本

d.设置启动View

40.Popover 弹窗窗口

a.并不是一个UIViewController

b.PopoverPrepare

eg:func prepareForSegue(segue:UIStoryboardSegue,send:AnyObject?){

iflet identifier=segue.identifier{

switch identifier{

case “popover segue”:

if let vc=Segue.destinationViewController as? MyController{

if let ppc=vc.popoverPresentationController{

ppc.permittedArrowDirections=

UIPopoverArrowDirection.Any

ppc.delegate=self

}

}

}

}

}

c.Presentation Controller 不能使用segue

1)当Popover弹窗时的相关适配,如显示位置,弹窗大小

默认会以modal方式全屏显示,可以设置为none,表示不需要适配

funcadaptivePresentationStyleForPresentationController(UIPresentationController)->UIModalPresentationStyle

{ returnUIModalPresentationStyle.None }

2)自定义窗口

func presentationController(UIPresentationController,viewControllerForAdaptivePresentationStyle:UIModalPresentationStyle)->UIViewController?

{ //returna UIViewController to use }

3)需实现代理协议 UIViewControllerTransitioningDelegate

eg:

class ViewController:
UIViewController, UIViewControllerTransitioningDelegate {
@IBAction
funcshowDidTouch(sender: UIBarButtonItem) {//按钮点击的Action
//create a controller,绑定 PresentViewController
let controller:UINavigationController! =
self.storyboard?.instantiateViewControllerWithIdentifier("ShowNavigationController")
as? UINavigationController
//"ShowNavigationController" storyboard中定义的controller标识
controller.modalPresentationStyle = .Custom
controller.transitioningDelegate =
self
self.presentViewController(controller, animated:
true, completion: {})
}
//UIViewControllerTransitioningDelegate
实现方法
funcpresentationControllerForPresentedViewController(presented:
UIViewController, presentingViewControllerpresenting:
UIViewController!, sourceViewControllersource:
UIViewController) ->
UIPresentationController? {
return
CustomPresentationController(presentedViewController:presented,presentingViewController:presenting)
}
}

CustomPresentationController是自定义的一个controller,它继承于UIPresentationController

d.设置窗口大小,结合segue使用

var preferredContentSize:CGSize

41.View Controller 生命周期

生命周期
调用场景
相关处理
说明
其他
awakeFromNib

当.nib文件被加载时,即通过nib文件创建view时

不要滥用该方法

viewDidLoad()

从dashborad中准备就绪,Outline设置完毕后调用。

只调用一次

初始化视图,更新UI

一旦Model发生了改变,可以property observer中更新UI;但是,当新建一个View Controller,同样需要更新UI,那是因为property observer并不会在outlet设置之前去真正更新UI,因为你正在preparedForSegue的过程中。

很多时候当View Controller被调用viewDidLoad时UI界面并没有被真正更新,因为outline还没设置好。

注意:不要在该方法中做与几何位置相关当操作,因为此时视图的边界位置还没有确定

viewWillAppear(

animated: Bool)

View Controller 马上要显示在屏幕上。

可调用多次

处理一些与几何位置相关到事情

视图边界已设置好

该方法有个参数animated,代表是否页面显示时需要有动画效果,一般在一个Navigation Controller里需要使用到这个参数

viewDidAppear(

animated: Bool)

View Controller已显示在屏幕上

viewWillDisappear(

animated: Bool)

View Controlle将要消失在屏幕上

清除一些占用资源的对象,比如图片

横竖屏切换的时候SplitView的Master经常会调用这个方法

注意:不要处理任何耗时的操作,容易卡死线程

viewDidDisappear(

animated: Bool)

View Controlle消失在屏幕上

viewWillTransitionToSize

屏幕旋转

func viewWillTransitionToSize(

size: CGSize,

withTransitionCoordinator: UIViewControllerTransitionCoordinator

)

可以使用animate alongside动画

屏幕并不是一个事件,可以去取消特定的Autorotation,默认是取消的,竖屏模式

didReceiveMemoryWarning

电量低

清理大内存对象

比如一个指向图片的弱指针,此时将会被释放

viewWillLayoutSubviews

当视图层次或顶层视图当边界发生改变

当几何位置发生变化时,边界同样发生了变化,大部分的重新布局都是系统自动完成的,如果已经设置好Auto Layout属性的话。

但是,如果你需要在这个过程中处理一些自己的东西的话,就必须重写系统的两个方法

viewWillLayoutSubviews

viewDidLayoutSubviews

几何位置

启动(viewWillAppear后)或横竖屏(viewWillTransitionToSize后)时调用

viewDidLayoutSubviews

几何位置

总结:

初始化,awakeFromNib,segue preparation被初始化,outline设置,viewDidLoad,……..

42.自动化布局AutoLayout

l 使用蓝色当虚线达到想要的效果

l 使用Ctrl+拖动来创建view与view之间的关系

l storyboard右下角 Pin 和Arrange窗口

l 使用Reset to Suggested Contraints调整自适应边距

l Document Outline 解决错误或冲突(点击storyboard左下角展开,红色或黄色的提示)

l Size Inspector (选中view的详情约束,storyboard右上角)

l 点击一个约束并选择它,然后设置属性检查

其他:

a. MasteringAutolayout 需要经验

b. 自动化布局也可使用代码实现

各种设备比较:

设备
竖屏
横屏
说明
iPhone 6 plus

width:Compact

height:Regular

width:Regular

height:Compact

iPhone

width:Compact

height:Regular

width:Compact

height:Compact

除iPhone 6 plus以外的设备

iPad

Regular

Regular

特别的:Split view 中的master是Compact width,Regular height

*竖屏 Any Width+Regular Height

storyboard自动化布局:

操作
详细
备注
图例
右边界对齐

选中控件,按Ctrl向右拖动到右边界线,选择Trailling Space to Container Margin。

选择时,可按Shift可多选

上边界对齐

选中控件,按Ctrl向上拖动到上边界线,选择Top Space to Top Layout Guide。

选择时,可按Shift可多选

左边界对齐

选中控件,按Ctrl向左拖动到左边界线,选择Leading Space to Container Margin

选择时,可按Shift可多选

下边界对齐

选中控件,按Ctrl向下拖动到下边界线,选择Bottom Space to Bottom Layout Guide。

选择时,可按Shift可多选

两个控件间的相对间距

选中控件,按Ctrl向垂直方向拖动到相对控件内部,选择verticl spaceing。

选中控件,按Ctrl向水平方向拖动到相对控件内部,选择Horizentol spaceing。

设置成功后,两控件间会形成一条蓝色的I形线条

选择时,可按Shift可多选

两个控件间基线对齐

选中控件,按Ctrl拖动到相对控件内部,选择Baseline

选择时,可按Shift可多选

两个控件等宽/等高

选中控件,按Ctrl拖动到相对控件内部,选择Equal Widths/Equal Heights

选择时,可按Shift可多选

消除约束固定值,使用相对值

点击某个约束,打开编辑页面,在Contant值出选择Use Standard Value

约束使用固定值,对自动化布局不利,设置Standard Value后约束会显示Equals:default

消除UI调整不适应的黄色警告

选中viewController,点击右下角的第三个图标,选择All Views in View Controller下的Update Frames,系统会将控件调整到最适应的位置

阻止内容压缩优先级

Content Compression Resistance Priority中设置的优先级系数越低,越优先不被压缩

主要处理图片伸缩的问题,当遇到不同分辨率图片适配当压缩问题时,应将图片控件系数调低

内容压缩优先级

Content Hugging Priority中设置的优先级系数越低,越先被压缩

相对某控件Y方向中间的上方(图中的Name)

添加约束Y居中(CenterY)对齐后,点击约束详情,Second Item 选择Bottom

相对某控件Y方向中间的下方(图中的Company)

添加约束Y居中(CenterY)对齐后,点击约束详情,Second Item 选择Top

43.预览视图

操作:在双屏的模式下,打开View Controller,点击最左边的蓝色圈Automatic,选择Preview,即可预览,可预览横竖屏视图

a.打开双屏的模式

b.点击最左边的蓝色圈Automatic,选择Preview

c.预览效果

44.icon size

1x:低分辨率设备 2x:高分辨率设备 3x:极高分辨率设备,如iPhone 6 plus

45.杂七杂八

l 约束 NSLayoutContranit

l 等比放缩图片

//添加约束 NSLayoutConstraint约束类型 imageView是图片控件
var aspectRatioContstraint:
NSLayoutConstraint?{
willSet{
if
let existingConstraint = aspectRatioContstraint{//设置前移除约束
view.removeConstraint(existingConstraint)
}
}
didSet{
if
let newConstraint = aspectRatioContstraint{
view.addConstraint(newConstraint)
}
}
}

设置约束

imageView.image = newValue
if
let constrainedView = imageView{
if
let newImage = newValue{//判断newValue不为nil
aspectRatioContstraint =
NSLayoutConstraint(
item: imageView,//item
需要添加约束的控件
attribute: .Width,//被约束的属性
relatedBy: .Equal,//Constants和multipliers的关系
.Equal:width=heigth*等高比
toItem: constrainedView,//相对其他控件,这里是imageview自己的宽高比,所以相对于自己
attribute:.Height,//相对的属性
multiplier: newImage.aspectRatio,//相乘的系数:等高比
constant: 0)//增加的常量
}else{
aspectRatioContstraint =
nil
}
}

l storyboard消除SubView关系

比如当storyboard在ScrollView满屏后再拖入其他控件,storyboard会自动将该控件添加为ScrollView的子控件,这种情况不一定是想要的。如何消除这种SubView关系:

a. 点击storyboard左下角的Document Outline,直接将子控件拖出ScrollView,将控件顺序拖到ScrollView的下方,控件就在ScrollView的上层了

b. 添加约束

选择控件,按Ctrl键拖动到View,即可添加约束

46.Scroll View(滚动条)

1)滚动区域设置 必须设置,否则不会显示

scrollView.contentSize= CGSize(width: 3000, height: 2000)

2)添加子View

login.frame = CGRect(x: 2700, y:50, width:120, height: 180)

scrollView.addSubview(log0)

图片:

letimage=UIImage(named:”xx.jpg”)

letiv=UIImageView(image:image)//iv.frmage.

=image.size

scrollView.addScrollview(iv)

scrollView.contentSize=imageView.bounds.size

3)获取当前滑动的坐标区域

letupperLeftOfVisible: CGPoint = scrollView.contentOffset

4)通过代码滑动到制定区域

funcscrollRectToVisible(CGRect, animated: Bool)// animated:true滑动过去,false 直接跳过去。

如果contentSize修改了,scrollView会闪一下。

5) Zooming

a.放缩的比例

srollView.minmumZoonScale=0.5 //默认大小的一半

scrollView.maxmumZoomScale=2.0//两倍大小

b.代理delegate

当ScrollView在Zooming时,它只zoom in

func viewForZoomingInScrollView(sender: UIScrollView)-> UIView

手势离开屏幕的时候调用的delegate

func scrollViewDidEndZooming(UIScrollView,withView:UIView,atScale: CGFloat)

c.其他

var zoomScale: CGFloat

func setZoomScale(CGFloat, animated: Bool) 设置缩放比例

func zoomToRect(CGRect, animated: Bool)

eg:

6)Closures 闭包方法

样例一:

class Grapher{

var yForX: ((x:Double) -> Double?)?//闭包

}

let grapher = Grapher()

let graphingBrain = CalculatorBrain()

graphingBrain.program = theProgramToGraph

grapher.yForX = { (x:Double) -> Doublein //闭包的实现

graphingBrain.variableValues[“M”] = x

return graphingBrain.evaluate()

}

调用eg: grapher.yForX!(x:1.0)

样例二:

class Foo{

var action: () -> Void = {}

func show(value: Int){ println(“\(value)”)}

func setupMyAction(){

var x: Int = 0

action={//闭包

x=x+1

self.show(x)//闭包内部有个指针指向self

}

}

func doMyAction10Times(){for i in 1..10{action()}}

}

闭包内相互指向,会造成两者永远存在内存中,它们永远不会被释放,造成捕获异常泄漏,解决:不捕获self指针[unowned self] in

action={ [unowned self] in

x=x+1

self.show(x)//闭包内部有个指针指向self

}

yForx = {[unowned
self](x:Double)->
Double in
self.showSomething()
return
1
}

47. Multithreading(多线程)

iOS有多重队列,一个函数队列,基础的闭包,每个队列都有一个自己的线程去运行这些队列

a.执行队列,执行一个函数或一个闭包

letqueue: dispatch_queue_t=….

dispatch_async(queue){……..} 两个参数,一个队列一个闭包,闭包不需要参数也不返回值

b.主队列,是一个串行队列

主队列一次从队列里只拉出一个函数执行,所有的UI活动都必须发生在主队列

主队列不能做任何可能阻塞的任务,比如URL的NSData下载

MVC的代码都在主队列中执行

letmainQ: dispatch_queue_t=dispatch_get_main_queue()//获取主队列

letmainQ: NSOperationQueue=NSOperationQueue.mainQueue()//OC获取主队列

eg:

dispatch_async(notTheMainQueue){//notTheMainQueue中处理阻塞UI的任务

dispatch_async(dispatch_get_main_queue()){//主线程中处理不阻塞UI的任务

}

}

c.其他并行队列

QOS_CLASS_USER_INTERACTIVE优先级最高

QOS_CLASS_USER_INITIATED 优先级高

QOS_CLASS_UTILITY 优先级一般

QOS_CALSS_BACKGROUND 后台任务,优先级低

letqos = Int(x.value)

letqueue=dispatch_get_global_queue(qos,0)

d.建立自己的串行队列

letserial=dispatch_queue_create(“name”,DISPATCH_QUEUE_SERIAL)

e.Example

Example1:

letdelayInSeconds=25.0

letdelay=Int64(delayInseconds*Double(NSEC_PER_MSEC))

letdispatchTime=dispatch_time(DISPATCH_TIME_NOW,delay)

dispatch_after(dispatchTime,dispatch_get_main_queue()){

}

Example2: NSURLSession API

let session = NSURLSession(NSURLSessionConfiguration.defaultSessionConfiguration())

if let url=NSURL(string: http://url”){
let request=NSURLRequest(URL:url)

lettask=session.downloadTaskWithRequest(request){//异步下载一个文件

(localURL,response,error) in collection

}

task.resume()

}

48.进度条 Activity Indicator View

49.文本框 UITextField

1) 显示键盘becomeFirstResponder()

2) 隐藏键盘 resignFirstResponder()

3) 一个重要的代理delegate UITextFieldDelegate

functextFieldShouldReturn(sender: UITextField)

在用户点击键盘上的return键后触发(也可能是search或go,取决于键盘类型),此时需调用resignFirstResponder隐藏键盘

4) UITextField 是一种UIControl,可以设置target/action,但通常我们使用

delegate,因为系统会自动调用resignFirstResponder

5) 编辑已结束,即使没有按return按钮

func textFieldDidEndEditing(sender:UITextField)

6) 键盘弹出时UITextField需移动到键盘之上

方式:把UITextField放在静态到TableView中或UITextField在顶部

7)其他属性

varclearsOnBeginEditing: Bool

varadjustFontSizeToFitWidth: Bool

varplaceholder: String//提示语

varbackground/disabledBackground: UIImage

vardefaultTextAttributes: Dictionary

varinputAccessoryView: UIView//可以在键盘上面添加其他控件

8) UITextView是一个非常强大的编辑对象,多行,多种字体等等

UITextInputTraits协议监听键盘输入

UITextField属性,包括键盘类型,是否自动大写,是否密码形式输入:

varUITextAutocapitalicationType auctocapitalizationType//words,sentences等

varUITextAutocorrectionType autocorrectionType//yes or no

varUIReturnKeyType returnkeyType//Go, search, Google, Done 等

varBOOL secureTextEntry//设置密码形式输入

varUIKeyboardType keyboardType//ASCII,URL,PhonePad等

9)NSNotification 键盘总是在视图之上

当TextFiled在底部,需要调整输入框的位置时,要用到NSNotification

UIKeyboard{will,Did}{Show,Hide}Notifications

注册一个事件 UIKeyboardDidShowNotification

NSNotificationCenter.defaultCenter().addObeserver(self,

selector:”theKeyboardappeared:”,

name:UIKeyboardDidShowNotification

object:view.window)

键盘弹出的时候将会调用自定义方法

functheKeyboardAppeared(notification:NSNotification)

eg:

classUITextFieldViewController:
UIViewController,UITextFieldDelegate,UITextInputTraits {

@IBOutlet
weak var textField:
UITextField!{
didSet{
textField.autocapitalizationType =
UITextAutocapitalizationType.Words
textField.autocorrectionType =
UITextAutocorrectionType.Yes
textField.returnKeyType =
UIReturnKeyType.Done
textField.secureTextEntry =
false
textField.keyboardType =
UIKeyboardType.URL
textField.becomeFirstResponder()
textField.delegate =
self
let view:UIView =
UIView(frame: CGRect(x:
10, y: 20, width:
20, height: 20))
view.backgroundColor =
UIColor.blueColor()
textField.inputAccessoryView = view
}

}
override
func viewDidLoad() {
super.viewDidLoad()
NSNotificationCenter.defaultCenter().addObserver(self, selector:
"theKeyboardappeared:", name:
UIKeyboardWillShowNotification, object: textField.window)
// Do any additional setup after loading the view.
}
functheKeyboardappeared(sender:NSNotification){
//软键盘遮挡处理
}
//点击了return/search/go,表示输入完成
functextFieldShouldReturn(textField:
UITextField) -> Bool {
textField.resignFirstResponder()//收起键盘
return
true
}
//编辑已结束,即使没有按return按钮
functextFieldDidEndEditing(textField:
UITextField) {
textField.resignFirstResponder()//收起键盘
}

}
50. UITableView 展示大量数据

1)本质是一个一维表格,也可以当成列表,它是UIScrollView的子类,在拥有大量数据的时候非常有效率

2)可以把多个TableView嵌套到NavigationController中,建立二位表格,因为无法建立真正的二维表格

3)Table显示方式

plain Style:长列表,用于动态数据

Group Style: 可以把一列的信息管理起来,用于固定数据

4)Table的组成

Header(头部):UIView

Section(组项): ,多个项归类,每个 section 都有一个 header和Foot

Footer(底部): UIView

复杂的Header和Footer可以使用TableViewCell

UITableViewDataSource’s tableView(UITableView, cellForRowAtIndexPath:NSIndexPath)

5)列表样式

Subtitle:UITableViewCellStyle.Subtitle ,子标题

Basic: UITableViewCellStyle.default ,常见不分类列表

Right Detail: UITableViewCellStyle.value1,左边是归纳,右边是详情

Left Detail: UITableViewCellStyle.value2,右边是归纳,左边是详情

6)UITableViewController

缺点:MVC 的全部 view 都必须得是 tableview

优点:storyboard中建立UITableViewController时它会自动将data sourch数据源和delegate连接到TableView上,普通的ViewController需要自己连接。

7)设置cell的类型

static:可以放置任何控件,table会将它们分组,可以给它们设置outlets,静态的

dynamic:一系列相同的控件集合,plain

custom:

8)Detail Disclusure

添加segue时应选择Accessory Action中的show

9)实现data source协议

a.table中section的数量

b.制定section中有几行

c.给它一个UITableViewCell 或它的子类来显示这一行

10)通过它们可以向Table载入数据

a.普通Cell

functableView(tv:UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) ->UITableViewCell{

let data=myInternalDataStructure[indexPath.section][indexPath.row]

let cell=…//创建一个UITableViewCell并加载数据

returncell

}

b.SubTitle Cell

func tableView(tv:UITableView,cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{

let data=myInternalDataStructure[indexPath.section][indexPath.row]

//自定义UITabeleViewCell

let dequeued:AnyObject=tv.dequeueReusableCellWithIdentifier(“MyCell”,forIndexPath:indexPath)//由于历史的原因,它并没有返回一个UITableCell,而是AnyObject,需要我们强转

letcell=dequeued as UITableViewCell

cell.textLabel?.text=”Title”//较大的文字

cell.detailTextLabel?.text=”Subtitle”//较小的文字

//也可载入图片,有imageView属性

returncell

}

c.自定义Custom Cell

func tableView(tv:UITableView,cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{

let data=myInternalDataStructure[indexPath.section][indexPath.row]

let dequeued: AnyObject=tv.dequeueReusableCellWithIdentifier(“MyCustomCell”,forIndexPath:indexPath)//由于历史的原因,它并没有返回一个UITableCell,而是AnyObject,需要我们强转

letcell=dequeued as MyTableViewCell

cell.publicAPIofMyTableViewCell=data.theDataTheCellNeedsToDisplayItsCustomLabelsEtc



returncell

}

11)UITableViewDataSource

funcnumberOfSectionsInTableView(sender:UITableView) -> Int //必须实现该方法,必须设置每个section有多少行

func tableView(sender:UITableView,numberOfRowsInSection:Int) -> Int

cellForRowAtIndexPath也是必须实现的方法,如果是静态的table就不需要实现,因为在storyboard中已经设置好了

获取标题

func tableView(UITableView, titleFor{Header, Footer}InSection: Int)-> String

也可以实现UITableView的delegate去获取标题

12)TableView Segues

//sender 是UIButton/UITableViewCell

func prepareForSegue(segue:UIStoryboardSegue, sender: AnyObject){

iflet identifier= segue.identifier{

switch identifier{

case “XyzSegue”:

case “AbcSegue”:

let cell=sender as MyTableViewCell//强转

if let indexPath =tableView.indexPathForCell(cell){

letseguedToMVC=segue.destinationViewController as MyVC

seguedToMVC.publicAPI=data[indexPath.section][indexPath.row]

}

default: break

}

}

}

13)UITableViewDelegate

delegate可以监听table内部发生的情况,例如:

当Table中一行被点击时,可以设置segue到其他视图,也可以在didSelectRowAtIndexPath代理方法中获取到,它会提供section和Row

其他方法:will/did willBegin/didEnd

14)UITableView Target/Action 更新Table UI

func tableView(sender: UITableView, didSelectRowAtIndexPathindexPath:NSIndexPath){

}

//点击 detail disclosure响应

functableView(UITableView, accessoryButtonTappedForRowWithIndexPath: NSIndexPath)

15)刷新数据

func reloadData(),它会发送numberOfSectionsInTableView和numberOfRowsInTableView,并且对每一个可见的cell调用cellFortowAtIndexPath,重新载入所有的数据

也可以调用

funcreloadRowsAtIndexPaths(indexPaths: [NSIndexPath], widthRowAnimation:UITableViewRowAnimation)

传递给它一个IndexPath数组,它只会重新载入这些cell

更新数据时行高可能会改变,应代码设置Table的高度为UITableViewAutomaticDimension自适应,如果设置了AutomaticDimension也需要设置estimatedRowHeight,因为table view是scroll view ,estimatedRowHeight可以获取size的大小

通过delegate获取行高

func tableView(UITableView, {estimated} heightForRowAtIndexPath: NSIndexPath) -> CGFloat

16)创建TableView

在storyboard中拖入一个UITableViewController后,将它放入Navigation Controller中,选中该controller,点击Edit->Embed In(放入)->Navigation Controller

因为可能需要点击某条tweet然后展示更多信息

63.Unwind Segues 不会创建视图

1)优点:

a.能直接或间接地回到之前地位置,解开连接

b.如果你有一个MVC并且是通过modal的方式展示的

2)modal

Modal segue:取代整个屏幕

popover就是一种modal,每当popover弹出的时候,除了这个popover其他都无法操作

3)当你在任何MVC中添加了IBAction方法,如果它的参数是UIStoryboardSegue,当使用Ctrl+拖动到退出按钮时,需选择goBack: Segue/Action

64.Alerts和Action Sheets 两种用户请求弹出框

1)区别:

Alerts:直接弹出在屏幕的中央,都是modal的形式,类似于Android的Dialoag

Action Sheets:从屏幕底部滑出,popover,集结了一堆选项的表单,如选择图片/拍照,类似于Android的popupWindow

2)创建Action Sheets 在iPhone(底部弹出层)和iPad(popover)显示效果不同

varalert=UIAlertController(

title:”Redeploy Cassini”,

message:”Issue commands to Cassini’sguidance system.”

preferredStyle:UIAlertContrllerStyle.ActionSheet

)

添加事件监听

alert.addAction(UIAlertAction(

title:”Orbit Staturn”, //标题

style:UIAlertActionStyle.Default, //样式, Default蓝色的字体,.Destructive红色文字

//handler:(action:UIAlertAction) -> Void//闭包,action就是这个UIAlertAction本身

{

(action: UIAlertAction) ->Void in

…..

}

))

显示ViewController

//设置显示的方式为popover

alert.modalPresentationStyle=.Popover

let ppc=alert.popoverPresentationController

ppc?.barButtonItem=redeployBarButtongItem

presentViewController(alert, animated:true,completion:nil)

3)创建Alert 在iPhone和iPad显示效果一样

var alert=UIAlertController(

title:”Login Required”,

message:”Please enter your Cassini guidancesystem.”

preferredStyle: UIAlertContrllerStyle.Alert

)

添加底部按钮

alert.addAction(UIAlertAction(

title:”Cancel”

style:.Cancel)

{(action:UIAlertAction) ->Void in

….

}

)

添加登录事件

alert.addAction(UIAlertAction(

title:”Login”,

style:.Default)

{(action: UIAlertAction) -> Void in

let tf=self.alert.textFields?.first as?UITextField //获取密码

if tf!=nill{self.loginWithPassword(tf.text) }//登录

}

)

//添加输入框

alert.addTextFieldWithConfigurationHandler{(textField) in

textField.placeholer=”Guidance System Password”

}

65.NSTimer 定时器

1)永远在主队列中使用定时器

2)启动定时器

NSTimer .scheduledTimeWithTimeInterval(

_seconds: 2.0,//启动的间隔时间

target:self, //向谁发消息AnyObject

selector:”fire”, //需要定时器执行的方法Selector(String)

userInfor:nil, //参数存储传递AnyObject?

repeats: true//是否只执行一次,true表示每两秒执行一次

)

func fire(timer: NSTimer){

lettheTimersUserInfo = timer.userInfo

}

3)停止计时器

func fire(timer: NSTimer){

if imDoneWithThisTimer{

timer.invalidate()//销毁

}

}

还可以使用tolerance可以优化系统性能(推荐)

myOneMinuteTimer.tolerance=10//每十秒执行一次

tolerance只设置一个秒为单位的时间

使用tolerance使得应用处于一个低耗能状态,否则它就会一直保持唤醒状态,以确保定时器的触发

66.动画Animation

分类

1) 使用view属性的执行动画

a) frame:视图随意移动

class func animateWithDuration(

duration: NSTimeInterval,//动画执行的时间

delay:NSTimeInterval,//等待的时间

options:UIViewanimationOptions,//动画

animations:()-> Void,//block,无参数也无返回值,修改视图属性

completion:((finished: Bool) -> Void)?)//动画执行完毕

eg:2秒后开始执行,开始3秒的淡出视图,完成后将它从父视图中移除

if myView.alpha=1.0{

UIView.animateWithDuration(3.0,

Delay:2.0,

Options:UIViewAnimationOptions.CurveEaseInEaseOut,//动画

Animations:{myView.alpha=0.0},// 修改透明度

completion:{if $0{myView.removeFromSuperView()}})

println(“myView.alpha=\(myView.alpha)”)

}

b) transform:旋转放缩视图

UI View.transitionWithView(

view:UIView,

duration: NSTimeInterval,//动画执行时间

options:UIViewAnimationOptions,//动画

animations:() -> Void,

completion:((finished: Bool) -> Void)?)

eg:

UIView.transitionWithView(view:myPlayingCardView,

duration:0.75,

options:UIViewAnimationOptions.TransitionFlipFromLeft

animations:{cardIsFaceUp=!cardIsFaceUp}

completions:nil )

c) alpha:透明度

UIViewAnimationOptions:

BegainFromCurrentState

AllowUserInteraction

LayoutSubviews

Repeat

Autoreverse

OverrideInheritedDuration

OverrideInheritedCurve

AllowAnimatedContent

CurveEaseInEaseOut

CurverLinear

2) viewController的跳转动画

3) CoreAnimation是在UI View Core Animation动画,底层的一种,非常强大的动画引擎,可操纵大量属性的执行动画

4) DynamicAnimation动态动画,基于物理引擎的动画,它会赋予视图重力和碰撞

67. Dynamic Animation

1)步骤:

a.创建UIDynamicAnimator

varanimator=UIDynamicAnimator(referenceView:UIView)

referenceView必须指定最顶层的UIView

b.添加UIDynamicBehaviors 动态行为,比如重力或碰撞之类的

eg: let gravity=UIGravityBehavitor()

animator.addBehavior(gravity)

eg:collider=UICollisionBehavior()

animator.addBehaviot(collider)

c.添加UIDynamicItems

let item1:UIDynamicItem=…

let item2:UIDYnamicItem=…

grivate.addItem(item1)

collider.addItem(item1)

gravity.addItem(item2)

item1将会受其他重力和碰撞所影响

item2只受重力影响

2)UIDynamicItem protocol协议

protocol UIDynamicItem{

var bounds:CGRect{get}//只读,动画器无法改变一个东西的大小

var center:CGPoint{get set}//对象的位置

var transform:CGAffineTransform{get set}//用于旋转

}

改变一个视图中心或使视图变形

func updateItemUsingCurrentState(item:UIDynamicItem)

3)UIGravityBehavior

varangle: CGFloat//设置一个角度

varmagnitude:CGFloat//比例1:1000,每1000像素点每二次方秒

任意对象在这个方向上就会有一个加速度

4)UIAttachmentBehavior其他行为动画效果

int(item:UIDynamicItem,attachedToAnchor:CGPoint)

init(item:UIDynamicItem,attachedToItem:UIDynamicItem)

init(item:UIDynamicItem,offsetFromCenter:CGPoint,

attachedToItem/Anchor…)

varlength:CGFloat

varanchorPoint:CGPoint

5)UICollisionBehavior碰撞效果

能控制对象间的碰撞,还可以控制对象和一个边界间的碰撞

varcollisionMode:UICollisitionBehaviorMode

设置路径UIBezierPath曲线,它会使用这个UIBezierPath当作它的外部边界

设置边界时必须设置identifier标志符

funcaddBoundaryWithIdentifier(identifier:NSCopying,forPath:UIBezierPath)

也可以设置translatesReferenceBoundsIntoBoundary为true,那么动画对象的所有外边框就会变成一个边界

vartranslatesReferenceBoundsIntoBoundary:Bool

func removeBoundaryWithIdentifier(identifier:NSCopying)

设置代理

varcollisionDelegate:UICollisionBehaviorDelegate

当碰触到一个边界时,将会得到这个代理消息

func collisionBehavior(behavior:UICollistionBehavior,

began/endedContactForItem:UIDynamicItem,

withBoundaryIdentifier:NSCopying)//需转为字符串或其他类型

6)IUSnapBehavior 移动到某个地方,发生类碰撞然后震荡

init(item:UIDynamicItem, snapToPoint:CGPoint)

vardamping:CGFloat 震荡的幅度

7)UIPushBehavior 将某个东西推向特定的角度或是一个力度

push会影响所有被添加到这个动画里的东西

push和重力的区别:push行为可以是一个一次性的效果,也可以是一个持续性或连续性的效果,不会加速,它是恒速

varmode:UIPushBehaviorMode

varpushDirection:CGVector

varangle:CGFloat

varmagnitude:CGFloat

8)UIDynamicItemBehavior 动态对象行为,所有行为的父类,本身是UIDynamicBehavior的子类

varallowsRotation:Bool

varfriction: CGFloat

varelasticity: CGFloat //设置弹性,弹跳的幅度
=1完全失重弹跳不停止

funclinearVelocityForItem(UIDynamicItem) -> CGPoint 线速度

func addLinearVelocity(CGPoint, forItem:UIDynamicItem) 在特定方向添加速度

func angularVelocityForItem(UIDynamicItem) -> CGFloat 角速度

9)UIDynamicBehavior 所有行为的父类

func addChildBehavior(UIDynamicBehavior)//添加子行为

可以拥有复合行为

所有的行为一次只能在一个动画中

10)UIDynamicAnimator

vardynamicAnimator: UIDynamicAnimator{get}

funcwillMoveToAnimator(UIDynamicAnimator)

var delegate:UIDynamicAnimatorDelegate

func dynamicAnimatorDidPause(UIDynamicAnimator)动画暂停

func dynamicAnimatorWillResume(UIDynamicAnimator)动画恢复

l 不要在一个视图放入一个行为中,当一个视图不在动画的参考视图的视图体系中,程序就会崩溃

l 不要使用一个大小为(0,0)的对象动画

eg:避免内存循环

if letpushBehavior=UIPushBehavior(items:[..], mode:.Instantaneous){

pushBehavior.magnitude=..

pushBehavior.angle=..

//调用自身,造成内存循环不释放

pushBehavior.action={ [unowned pushBehavior] in //改进

//改进后,表示pushBehavior在闭包中是不会被强引用的,所以不需要捕获

pushBehavior.dynamicAnimator!.removeBehavior(pushBehavior)

}

animator.addBehavior(pushBehavior)

}

68.Application 生命周期

1)生命周期

a. Not running

b. Inactive

l Not running à Inactive状态切换

AppDelegate会受到通知:

Funcapplication(UIapplication, didFinishLaunchingWithOptions:

[NSObject:AnyObject])

observe:每次应用启动

UIApplicationDidFinishLauncheingNotification

l Active à InActivity

AppDelegate会受到通知:

Func applicationWillResignActive(UIApplication)

observe:每次应用启动

UIApplicationWillResignActiveNotification

l Backgroundà InActivity

AppDelegate会受到通知:

Func applicationWillEnterForeground (UIApplication)

observe:每次应用启动

UIApplicationWillEnterForegroundNotification

c. Active

l InActivity à Active应用暂停Pause

AppDelegate会受到通知:

Func applicationDidBecomeActivite(UIApplication)

observe:

UIApplicationDidBecomeActiviteNotification

d. Background

l InActivityàBackground应用

AppDelegate会受到通知:

FuncapplicationDidEnterBackground(UIApplication)

开启线程,启动后台任务之类的

observe:

UIApplicationDidEnterBackgroundNotification

e. Suspended

机制:在手机锁定后,应用访问的数据需要加密

2) UIApplication

a.获取共享对象let myApp = UIApplication.sharedApplication()

b. 打开URL

func openURL(NSURL)

func canOpenURL(NSURL) -> Bool

c. 本地通知

func(un)registerForRemoteNotifications()

func scheduleLocalNotification(UILocalNotification)

funcregisterUserNotificationSettings(UIUserNotificationSettings)

d. 设置获取间隔,启动后台工作Background Fetch

funcsetMinimumBackgroundFetchInterval(NSTimeInterval) 默认值是Never

如果不设置,那么应用不会被唤醒

一般需设置为UIApplicationBackgroudFetchIntervalMinimum,尽多可能多的唤醒应用程序后台

e. 运行后台任务,后台时主线程会被暂停

func backgroundTaskWithExpirationHandler(handler:() -> Void) -> UIBackgroundTaskIdentifier

完成时需调用 endBackgroundTask(UIBackgroundTaskIdentifier)

默认情况下,如果在期限内,后台任务没有完成,那么iOS将终止应用程序,这时候还可以使用

begainBackgroundTaskWithExpirationHandler再向系统申请点时间

f. 网络进度条显示/隐藏设置

varnetworkActivityIndicatorVisible: Bool

g. 其他属性

varbackgroundTimeRemaining: NSTimeInterval{get}

varpreferredContentSizeCategory: String{get} 字体的大小

varapplicationState: UIApplicationState{get} 应用程序状态,foreground/background/active

3) info.plist 字典,包括很多应用程序的设置

69.NSNotification通知

1)NSNotificationCenter 接收消息

func addObserverForName(String, //接收消息标志名

object:AnyObject?, 发送广播者,=nil的话表示接收所有这类型的的广播

queue:NSOperationQueue?)//队列

{ (notification: NSNotification) -> Void in //队列闭包

可能是当前队列,也可能是主队列

let info: [NSObject:AnyObject]? = nofification.userInfo

userInfo是一个OC里面的字典,key: NSObject, values: AnyObject

}

NSOperationQueue类似一个在分发工作中顶端的面向对象的API

eg:

let center =NSNotificationCenter.defaultCenter()

//UIContentSizeCategoryDidChangeNotification系统自体更改的通知标识

center.addObserverForName(UIContentSizeCategoryDidChangeNotification,

object: UIApplication.sharedApplication(),

queue: NSOperationQueue.mainQueue())

{ notifaction in

letc = notification.userInfo?[UIContentSizeCategoryNewValueKey]

}

70.Core Motion

CMMotionManager

1)检测硬件设备是否可用

var {accelerometer,gyro,magnetometer,deviceMotion}Available:Bool accelerometer加速器

2)开启硬件

func start{Accelerometer, Gyro,magnetometer, DeviceMotion}updates()

3)硬件是否活跃

var{accelerometer,gyro,magnetometer,deviceMotion}Active: Bool

4)停止硬件

funcstop{Accelerometer,Gyro,Magnetometer,DeviceMotion}upates()

5)设备移动获取加速数据

var accelerometerData: CMAccelerometerData

var acceleration: CMAcceleration

struct CMAcceleration{

varx: Double //g(9.8 m/s/s)

vary: Double

varz:Double

}

g:重力加速度

陀螺仪

var gyroData: CMGyroData

var rotationRate:CMRotationRate 转速

struct CMRotationRate{

varx: Double //radius/s

var y: Double //radius/s

var z: Double //radius/s

}

磁力计

var magnetometerData: CMMagnetometerData

var magneticField: CMMagneticField

struct CMMagneticField{

var x: Double

var y: Double

var z: Double

}

6)CMDeviceMotion

var gravity: CMAcceleration 重力

var userAcceleration: CMAcceleration 用户加速度

var rotationRate: CMRotationRate

var attitude: CMAttitude

class CMAttitude: NSObject{

var roll: Double 滚动

var pitch: Double 投掷

var yaw: Double 偏航方向

}

var magneticField:CMCalibratedMagneticField

struct CMCalibratedMagneticField{

varfield: CMMagneticField

varaccuracy: CM

}

7)注册一个block

a.注册一个block接收Accelerometer数据

funcstartAccelerometerUpdatesToQueue(queue: NSOperationQueue!,withHandler:CMAccelerometerHandler)

typealiasCMAccelerationHandler=(CMAccelerometerData!, NSError!) -> Void

队列NSOperationQueue()或NSOperation.mainQueue或当前队列

b.注册一个block接收Gyro数据

func startGyroUpdatesToQueue(queue:NSOperationQueue!, withHandler:CMGyroHandler)

typealias CMGyroHandler=(CMAGyroData!,NSError!) -> Void

c.注册一个block接收DeviceMotion数据

func startDeviceMotionUpdatesToQueue(queue:NSOperationQueue!, withHandler: CMDeviceMotionHandler)

typealias CMDeviceMotionHandler=(CMDeviceMotion!,NSError!) -> Void

8)设置rate 单位是秒

var accelerometerUpdateInterval:NSTimeInterval

var gyroUpdateInterval: NSTimeInterval

var magnetometerUpdateInterval:NSTimeInterval

var deviceMotionUpdateInterval:NSTimeInterval

71.Core Location

1) 代表基本位置的对象CLLocation(CL:Core Location)

a.属性:coordinate坐标, altitude高度, horizontalAccuracy/verticalAccuracy水平或垂直精度,

timestamp时间戳, speed速度, course 方向

b.经纬度

varcoordinate: CLLocationCoordinate2D//平面坐标,不包括高度

struct CLLocationCooordinate2D{

CLLocationDegrees latitude //Double

CLLocationDegrees longitude //Double

}

c.精确度

衡量水平和垂直空间的,精确度并不是一个百分比的数值或类似,是一组预定义好的信息

varhorizontalAccuracy: CLLocationAccuracy

varverticalAccuracy: CLLocationAccuracy

精度越高越耗电,与基站通讯耗电非常低,手机会一直和基站通讯,wifi也比较耗电

kCLLocaitonAccuracyBestForNavigation 最高精度 GPS

kCLLocaitonAccuracyBest 高精度 GPS

kCLLocaitonAccuracyNearestTenMeters 10米附近的精度 GPS+wifi混合

kCLLocaitonAccuracyHundredMeters 百米附近的精度 wifi

kCLLocaitonAccuracyKilometer 一公里的精度 基站

kCLLocaitonAccuracyThreeKilometers 三公里的精度 基站

d.速度:瞬时速度

varspeed: CLLocationSpeed

e.方向: 更倾向于运动轨迹的方向

varcourse: CLLocationDirection

f.时间戳:重要属性,当获取位置可能不是一个实时的操作,可以查看时间戳检查位置信息获取的时间

vartimestamp: NSDate

2)获取CLLocation

CLLocationManager

a.检查是否有相应的硬件,不是所有手机都有点位硬件

b.创建一个实例并且设置代理delegate

c.按需求配置位置信息

d.开始发送代理信息

它会通过一个稳定的流向你发信息

3)监控手机的地理位置方式

a.基于一个特定的精确度,提供持续的更新

b.地理位置有显著改变的时候通知,可以设置区域

4)CLLocaionManager的类方法

授权状态:Authorized, Denied, Restricted

classfunc authorizationStatus() -> CLAuthorizationStatus

class func locationServicesEnabled() ->Bool 位置服务是否开启

class func significantLocationChangeMonitoringAvailable() -> Bool 显著位置变更监控方式是否可用

class func isMonitoringAvailableForClass(AnyClass!) -> Bool

class func isRangingAvailable() -> Bool

5)获取授权

func requestWhenInUseAthorization() 仅在app是当前活动的app时启动

func rquestAlwaysAuthorization() 申请在任何时候都获取位置,即使app在后台

使授权申请生效需在info.plist文件里加入一个键,在这两个键二选一,只要有键就可以不需要有值。

NSLocationWhenInUseageDescription

NSLocationAlwaysUseageDescription

在CLLocationManager里设置desiredAccuracy

vat desiredAccuracy: CLLocationAccuracy 精确度

var distanceFilter: CLLocationDistance 指定距离更新过滤器

func startUpdatingLocation() 开始更新位置信息

func stopUpdatingLocation() 停止更新位置信息

6)代理信息方法

CLLocationManager:发送消息方

func locationManager(CLLocationManager,didUpdateLocations: [CLLocation])

手机处于休眠状态时,GPS也可以纪录位置信息

7)向delegate回调错误信息

func locationManager(CLLocationManager,didFailWithError: NSError)

错误信息

kCLErrorLocationUnknown

kCLErrorDenied

kCLErrorHeadingFailure

8)显著变更

funcstartMonitoringSignificantLocationChanges()

func stopMonitoringSignificantLocationChanges()

app启动时会调用didFinishLaunchingWithOptions方法

func application(UIApplication,didFinishLaunchingWithOptions: [NSObject, AnyObject])

这个字典有一个key: UIApplicationLaunchOptionsLocationKey, 这个说明app启动时由于一个显著位置变更导致的,你需要去查看当前位置然后作出响应。

var location: CLLocation

9)区域

靠近或离开区域时,会调用它的代理方法

func locationManager(CLLocationManager,didEnterRegion: CLRegion)

func locationManager(CLLocationManager,didExitRegion: CLRegion)

func locationManager(CLLocationManager,monitoringDidFailForRegion: CLRegion, withError: NSError)

a. CLCircularRegion圆圈区域

func startMonitoringForRegion(CLRegion)

func stopMonitoringForRegion(CLRegion)

let cr=CLCirularRegion(center:CLLocationCoordinate2D, 圆点

radius: CLLocationDistance, 半径

identifier:String) 标识是必要的

app没有启动或在后台时也能监控区域,需要特定点时间唤醒app,app被唤醒时会提醒已进入预设区域

b. CLBeaconRegion 灯塔区域

你是否靠近另一台iOS设备,需要用到Core Bluetooth框架技术,需要定义identifier并注册该identifier

系统可以检测到与灯塔间的距离

funcstartRangingBeaconsInRegion(CLBeaconRegion)调用该方法后,将会受到didRangeBeacons 这个代理方法发送的信息

10)app在后台时也可以区域监控

可以在CLLocationManager的monitoredRegions属性里找到

var monitoredRegions: NSSet 无序数组

var maximumRegionMonitoringDistance:CLLocationDistance{get}

72.地图 Map

1)MKMapView: UIView的子类

coordinate,title,subtitle

MKAnnotationView的子类展示,地图上的标识图形,默认是个大头针

MKPinAnnotationView 点击弹出框

a.初始化

importMapKit

letmapView = MKMapView()

varannotations: [MKAnnotation]{get} 是一个AnyObject的只读数组,但是不能把非MKAnnotation的对象放入这个数组中

协议protocol

protocol MKAnnotation: NSObject

var coordinate: CLLocationCoordinate2D{get} 坐标

var title: String!{get} 标题,必须设置

var subtitle: String!{get} 子标题

2)MKAnnotation

只读属性

var annotations: [MKAnnotation] {get}

必须添加/移除annotation

func addAnnotation(MKAnnotation)

func addAnnotations([MKAnnotation])

func removeAnnotation(MKAnnotation)

func removeAnnotations([MKAnnotation])

3)MKAnnotationView

a.MKAnnotationView如何加载以及和annotation数组联系起来

viewForAnnotation会提供一个annotation并需要为它创建视图

func mapView(sender: MKMapView,viewForAnnotation: MKannotation) -> MKAnnotationView{

//把一个复用的视图从队列中取出

varview = sender.dequeueReusableAnnotationViewWithIdentifier(IDENT)

ifview==nil{

// reuseIdentifier复用标识符

view = MKPinAnnotationView(annotation: annotation, reuseIdentifier:IDENT)

view.canShowCallout=true/false是不是允许弹出标识视图

}

aView.annotation=annotation

return view

}

b.其他属性

var annotation: MKAnnotation

var image: UIImage 设置地图标识图片,默认是个大头针

左右辅助视图

var leftCalloutAccessoryView: UIView

var rightCalloutAccessoryView: UIView

var enabled: Bool 激活或隐藏

var centerOffset: CGPoint 中心偏移量

var draggable: Bool 大头针是否可拖拽,坐标coordinate属性{get set}

c.特性:如果标识视图的辅助视图是一个UIControl,通常是一个UIButton,当它被点击时,地图视图当代理方法calloutAccessoryControlTapped就会被调用(弹出框的点击事件)

eg:view.rightCalloutAccessoryView=UIButton.buttonWithType(UIButtonTypeDetailDisclusure)

func mapView(MKMapView, annotationView:MKAnnotationView, calloutAccessoryControlTapped: UIControl)

d.点击地图标志图会调用didSelectAnnotationView

mapView(viewForAnnotation:)

letview.leftCalloutAccessoryView=UIImageView()

func mapView(MKMapView,didSelectAnnotationView aView:MKAnnotationView)

{

检查左辅助视图是否是一个图片视图

iflet imageView = aView.leftCalloutAccessoryView as? UIImageView{

imageView.image=..设置图片,然后开启一个线程开始下载

}

}

3)配置地图类型

卫星视图Statellite,混合视图Hybrid,标准的街道视图Standard

var mapType: MKMapType

var showsUserLoaction: Bool true:定位到当前位置

var isUserLocationVisible: Bool 可以设置当前位置是否显示

var userLocation: MKUserLocation 用户位置信息

限制用户操作

var zoomEnabled: Bool 放缩

var scrollEnabled: Bool 滚动

var pitchEnable: Bool 所有手势//3D

var rotateEnable:Bool 旋转

4)MKMapCamera

var camera:MKMapCamera

调整视角的坐标

letcamera=MKMapCamera(lookingAtCenterCoordinate: CLLocationCoordinate2D,

fromEyeCoordinate:CLLocationCoordinate2D,

eyeAltitude:CLLocationDistance)

5)MKCoordinateRegion控制显示地图的部分

var region:MKCoordinateRegion

structMKCoordinateRegion{

var center: CLLocationCoordinate2D

var span: MKCoordinateSpan

}

structMKCoordinateSpan{围绕这个点的经纬度

var latitudeDelta: CLLocationDegrees

var longitudeDelta: CLLocationDegrees

}

func setRegion(MKCoordinateRegion,animated: Bool)

varcenterCoordinate: CLLocationCoordinate2D 设置区域中心的坐标

funcsetCenterCoordinate(CLLocationCoordinate2D, animated: Bool)

funcshowAnnotations([MKAnnotation, animated: Bool])

6)其他方法和函数

MKMapRectContainsPoint,MKMapPointForCoordinate

转换不同的坐标空间 地球坐标,地图坐标

funcmapPointForPoint(CGPoint) -> MKMapPoint

funcmapRectForRect(CGRect) -> MKMapRect

funcpointForMapPoint(MKMapPoint) -> CGPoint

funcrectForMapRect(MKMapRect) -> CGRect

代理方法 didChangeRegionAnimated,它会告诉你现在显示在地图里的区域变化

funcmapView(MKMapView, didChangeRegionAnimated: Bool)

有时候需要调用地图视图的动画链,比如切换地点时,可以先缩小到整个区域,再放大到具体的地点,这样比直接跳过去更好

7)MKLocalSearch地图搜素

varrequest=MKLocalSearchRequest()

request.naturalLanguageQuery=@”Ike’s” 搜素地名

request.region=..

letsearch=MKLocalSearch(request: request)

search.startWithCompletionHandler{(MKLocalSearchResponse,NSError) -> Void in

主线程使用网络查询,返回一个MKPlacemark

}

MKMapItem

funcopenInMapsWithLaunchOptions([NSObject: AnyObject]) -> Bool

8)路线规划

MKRoute MKPolyline

9)Overlays 覆盖层

MKOverlay是MKAnnotation的子类

funcaddOverlay(MKOverlay, level: MKOverlayLevel)

funcremoveOverlay(MKOverlay)

varboundingMapRect: MKMapRect 包含整个覆盖层的矩形

func intersectsMapRect(MKMapRect)-> Bool 矩形是否有交叉

给覆盖层定义自定义视图

funcmapView(MKMapView, rendererForOverlay: MKOverlay) -> MKOverlayRenderer

MKOverlayRenderer在地图上绘制覆盖层

系统渲染

MKCircleRenderer 渲染圆形

MKPolylineRenderer画路线

MKPolygonRederer 渲染多边形

MKTileOverlayRenderer 平铺图片

73.Modal Segue

1)主要是用来处理屏幕上的内容 弹出层

以modal的形态显示选择present modally

funcperformSegue(UIStoryboardSegue, withIdentifier: String) 直接调用segue

展示ViewController

funcpresentViewController(UIViewController, animated: Bool, completion: () ->Void)

modalPresentationStyle:.FullScreen(全屏,默认值), .OverFullScreen(全屏,但并不阻止下面但屏幕互动), .Popover(弹出窗口), .FormSheet

2)如何通过modally segued返回到MVC

funcprepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!){

if segue.identifier == “GOTOMyModalVC” {

let vc = segue.destinationViewControlleras MyModalVC

}

}

大部分modal segue完成工作后就会移除自己

unwind可以移除自己

也可以手动调用dismissViewControllerAnimated

funcdismissViewControllerAnimated(Bool, completion: () -> Void)

3)如何将一个modal view controller展示到屏幕上

varmodalTransitionStyle: UIModalTransitionStyle 出现或离开的动画样式

.CoverVertical 从底部滑出,默认效果

.FlipHorizontal 翻转的效果

.CrossDissolve 淡出

.PartialCurl 从底部的一个角落翻起
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: