Swift系列文章由CocoaChina翻译小组翻译自苹果的官方文档: The Swift Programming Language。本篇译者:葛布林大帝( 博客)和 @numbbbbb( 博客),校对: ChildhoodAndy

通常来说,编程语言教程中的第一个程序应该在屏幕上打印“Hello,world”。在 Swift 中,可以用一行代码实现:
  1. println("hello,world")
如果你写过 C 或者 Objective-C 代码,那你应该很熟悉这种形式——在 Swift 中,这行代码就是一个完整的程序。你不需要为了输入输出或者字符串处理导入一个单独的库。全局作用域中的代码会被自动当做程序的入口点,所以你也不需要main函数。你同样不需要在每个语句结尾写上分号。
这个教程会通过一系列编程例子来让你对 Swift 有初步了解,如果你有什么不理解的地方也不用担心——任何本章介绍的内容都会在后面的章节中详细讲解。
注意:为了获得最好的体验,在 Xcode 当中使用代码预览功能。代码预览功能可以让你编辑代码并实时看到运行结果。
简单值
使用let来声明常量,使用var来声明变量。一个常量的值在编译时并不需要获取,但是你只能为它赋值一次。也就是说你可以用常量来表示这样一个值:你只需要决定一次,但是需要使用很多次。
  1. varmyVariable=42
  2. myVariable=50
  3. letmyConstant=42
常量或者变量的类型必须和你赋给它们的值一样。然而,声明时类型是可选的,声明的同时赋值的话,编译器会自动推断类型。在上面的例子中,编译器推断出myVariable是一个整数(integer)因为它的初始值是整数。
如果初始值没有提供足够的信息(或者没有初始值),那你需要在变量后面声明类型,用冒号分割。
  1. letimplicitInteger=70
  2. letimplicitDouble=70.0
  3. letexplicitDouble:Double=70
练习:创建一个常量,显式指定类型为Float并指定初始值为4。
值永远不会被隐式转换为其他类型。如果你需要把一个值转换成其他类型,请显式转换。
  1. letlabel="Thewidthis"
  2. letwidth=94
  3. letwidthLabel=label+String(width)
练习:删除最后一行中的String,错误提示是什么?
有一种更简单的把值转换成字符串的方法:把值写到括号中,并且在括号之前写一个反斜杠。例如:
  1. letapples=3
  2. letoranges=5
  3. letappleSummary="Ihave\(apples)apples."
  4. letfruitSummary="Ihave\(apples+oranges)piecesoffruit."
练习:使用\()来把一个浮点计算转换成字符串,并加上某人的名字,和他打个招呼。
使用方括号[]来创建数组和字典,并使用下标或者键(key)来访问元素。
  1. varshoppingList=["catfish","water","tulips","bluepaint"]
  2. shoppingList[1]="bottleofwater"
  3. varoccupations=[
  4. "Malcolm":"Captain",
  5. "Kaylee":"Mechanic",
  6. ]
  7. occupations["Jayne"]="PublicRelations"
要创建一个空数组或者字典,使用初始化语法。
  1. letemptyArray=String[]()
  2. letemptyDictionary=Dictionary<String,Float>()
如果类型信息可以被推断出来,你可以用[]和[:]来创建空数组和空字典——就像你声明变量或者给函数传参数的时候一样。
  1. shoppingList=[]//去逛街并买点东西
控制流
使用if和switch来进行条件操作,使用for-in、for、while和do-while来进行循环。包裹条件和循环变量括号可以省略,但是语句体的大括号是必须的。
  1. letindividualscores=[75,43,103,87,12]
  2. varteamscore=0
  3. forscoreinindividualscores{
  4. ifscore>50{
  5. teamscore+=3
  6. }else{
  7. teamscore+=1
  8. }
  9. }
  10. teamscore
在if语句中,条件必须是一个布尔表达式——像if score { ... }这样的代码是错误的。
你可以一起使用if和let来处理值缺失的情况。有些变量的值是可选的。一个可选的值可能是一个具体的值或者是nil,表示值缺失。在类型后面加一个问号来标记这个变量的值是可选的。
  1. varoptionalString:String?="Hello"
  2. optionalString==nil
  3. varoptionalName:String?="JohnAppleseed"
  4. vargreeting="Hello!"
  5. ifletname=optionalName{
  6. greeting="Hello,\(name)"
  7. }
练习:把optionalName改成nil,greeting会是什么?添加一个else语句,当optionalName是nil时给greeting赋一个不同的值。
如果变量的可选值是nil,条件会判断为false,大括号中的代码会被跳过。如果不是nil,会将值赋给let后面的常量,这样代码块中就可以使用这个值了。
switch支持任意类型的数据以及各种比较操作——不仅仅是整数以及测试相等。
  1. letvegetable="redpepper"
  2. switchvegetable{
  3. case"celery":
  4. letvegetableComment="Addsomeraisinsandmakeantsonalog."
  5. case"cucumber","watercress":
  6. letvegetableComment="Thatwouldmakeagoodteasandwich."
  7. caseletxwherex.hasSuffix("pepper"):
  8. letvegetableComment="Isitaspicy\(x)?"
  9. default:
  10. letvegetableComment="Everythingtastesgoodinsoup."
  11. }
练习删除default语句,看看会有什么错误?
运行switch中匹配到的子句之后,程序会退出switch语句,并不会继续向下运行,所以不需要在每个子句结尾写break。
你可以使用for-in来遍历字典,需要两个变量来表示每个键值对。
  1. letinterestingNumbers=[
  2. "Prime":[2,3,5,7,11,13],
  3. "Fibonacci":[1,1,2,8],
  4. "Square":[1,4,9,16,25],
  5. ]
  6. varlargest=0
  7. for(kind,numbers)ininterestingNumbers{
  8. fornumberinnumbers{
  9. ifnumber>largest{
  10. largest=number
  11. }
  12. }
  13. }
  14. largest
练习:添加另一个变量来记录哪种类型的数字是最大的。
使用while来重复运行一段代码直到不满足条件。循环条件可以在开头也可以在结尾。
  1. varn=2
  2. whilen<100{
  3. n=n*2
  4. }
  5. n
  6. varm=2
  7. do{
  8. m=m*2
  9. }whilem<100
  10. m
你可以在循环中使用..来表示范围,也可以使用传统的写法,两者是等价的:
  1. varfirstForLoop=0
  2. foriin0..3{
  3. firstForLoop+=i
  4. }
  5. firstForLoop
  6. varsecondForLoop=0
  7. forvari=0;i<3;++i{
  8. secondForLoop+=1
  9. }
  10. secondForLoop
使用..创建的范围不包含上界,如果想包含的话需要使用...。
函数和闭包
使用func来声明一个函数,使用名字和参数来调用函数。使用->来指定函数返回值。
  1. funcgreet(name:String,day:String)->String{
  2. return"Hello\(name),todayis\(day)."
  3. }
  4. greet("Bob","Tuesday")
练习:删除day参数,添加一个参数来表示今天吃了什么午饭。
使用一个元组来返回多个值。
  1. funcgetGasPrices()->(Double,Double,Double){
  2. return(3.59,3.69,3.79)
  3. }
  4. getGasPrices()
函数的参数数量是可变的,用一个数组来获取它们:
  1. funcsumOf(numbers:Int...)->Int{
  2. varsum=0
  3. fornumberinnumbers{
  4. sum+=number
  5. }
  6. returnsum
  7. }
  8. sumOf()
  9. sumOf(42,597,12)
练习:写一个计算参数平均值的函数。
函数可以嵌套。被嵌套的函数可以访问外侧函数的变量,你可以使用嵌套函数来重构一个太长或者太复杂的函数。
  1. funcreturnFifteen()->Int{
  2. vary=10
  3. funcadd(){
  4. y+=5
  5. }
  6. add()
  7. returny
  8. }
  9. returnFifteen()
函数是一等公民,这意味着函数可以作为另一个函数的返回值。
  1. funcmakeIncrementer()->(Int->Int){
  2. funcaddOne(number:Int)->Int{
  3. return1+number
  4. }
  5. returnaddOne
  6. }
  7. varincrement=makeIncrementer()
  8. increment(7)
函数也可以当做参数传入另一个函数。
  1. funchasAnyMatches(list:Int[],condition:Int->Bool)->Bool{
  2. foriteminlist{
  3. ifcondition(item){
  4. returntrue
  5. }
  6. }
  7. returnfalse
  8. }
  9. funclessthanTen(number:Int)->Bool{
  10. returnnumber<10
  11. }
  12. varnumbers=[20,19,12]
  13. hasAnyMatches(numbers,lessthanTen)
函数实际上是一种特殊的闭包,你可以使用{}来创建一个匿名闭包。使用in来分割参数并返回类型。
  1. numbers.map({
  2. (number:Int)->Intin
  3. letresult=3*number
  4. returnresult
  5. })
练习:重写闭包,对所有奇数返回0。
有很多种创建闭包的方法。如果一个闭包的类型已知,比如作为一个回调函数,你可以忽略参数的类型和返回值。单个语句闭包会把它语句的值当做结果返回。
你可以通过参数位置而不是参数名字来引用参数——这个方法在非常短的闭包中非常有用。当一个闭包作为最后一个参数传给一个函数的时候,它可以直接跟在括号后面。
  1. sort([1,12,2]){$0>$1}
对象和类
使用class和类名来创建一个类。类中属性的声明和常量、变量声明一样,唯一的区别就是它们的上下文是类。同样,方法和函数声明也一样。
  1. classShape{
  2. varnumberOfSides=0
  3. funcsimpleDescription()->String{
  4. return"Ashapewith\(numberOfSides)sides."
  5. }
  6. }
练习:使用let添加一个常量属性,再添加一个接收一个参数的方法。
要创建一个类的实例,在类名后面加上括号。使用点语法来访问实例的属性和方法。
  1. varshape=Shape()
  2. shape.numberOfSides=7
  3. varshapeDescription=shape.simpleDescription()
这个版本的Shape类缺少了一些重要的东西:一个构造函数来初始化类实例。使用init来创建一个构造器。
  1. classNamedShape{
  2. varnumberOfSides:Int=0
  3. varname:String
  4. init(name:String){
  5. self.name=name
  6. }
  7. funcsimpleDescription()->String{
  8. return"Ashapewith\(numberOfSides)sides."
  9. }
  10. }
注意:self被用来区别实例变量。当你创建实例的时候,像传入函数参数一样给类传入构造器的参数。每个属性都需要赋值——无论是通过声明(就像numberOfSides)还是通过构造器(就像name)。
如果你需要在删除对象之前进行一些清理工作,使用deinit创建一个析构函数。
子类的定义方法是在它们的类名后面加上父类的名字,用冒号分割。创建类的时候并不需要一个标准的根类,所以你可以忽略父类。
子类如果要重写父类的方法的话,需要用override标记——如果没有添加override就重写父类方法的话编译器会报错。编译器同样会检测override标记的方法是否确实在父类中。
  1. classSquare:NamedShape{
  2. varsideLength:Double
  3. init(sideLength:Double,name:String){
  4. self.sideLength=sideLength
  5. super.init(name:name)
  6. numberOfSides=4
  7. }
  8. funcarea()->Double{
  9. returnsideLength*sideLength
  10. }
  11. overridefuncsimpleDescription()->String{
  12. return"Asquarewithsidesoflength\(sideLength)."
  13. }
  14. }
  15. lettest=Square(sideLength:5.2,name:"mytestsquare")
  16. test.area()
  17. test.simpleDescription()
练习:创建NamedShape的另一个子类Circle,构造器接收两个参数,一个是半径一个是名称,实现area和describe方法。
属性可以有 getter 和 setter 。
  1. classEquilateralTriangle:NamedShape{
  2. varsideLength:Double=0.0
  3. init(sideLength:Double,name:String){
  4. self.sideLength=sideLength
  5. super.init(name:name)
  6. numberOfSides=3
  7. }
  8. varperimeter:Double{
  9. get{
  10. return3.0*sideLength
  11. }
  12. set{
  13. sideLength=newValue/3.0
  14. }
  15. }
  16. overridefuncsimpleDescription()->String{
  17. return"Anequilateraltriaglewithsidesoflength\(sideLength)."
  18. }
  19. }
  20. vartriangle=EquilateralTriangle(sideLength:3.1,name:"atriangle")
  21. triangle.perimeter
  22. triangle.perimeter=9.9
  23. triangle.sideLength
在perimeter的 setter 中,新值的名字是newValue。你可以在set之后显示的设置一个名字。
注意EquilateralTriangle类的构造器执行了三步:
1. 设置子类声明的属性值
2. 调用父类的构造器
3. 改变父类定义的属性值。其他的工作比如调用方法、getters和setters也可以在这个阶段完成。
如果你不需要计算属性但是需要在设置一个新值之前运行一些代码,使用willSet和didSet。
比如,下面的类确保三角形的边长总是和正方形的边长相同。
  1. classTriangleAndSquare{
  2. vartriangle:EquilateralTriangle{
  3. willSet{
  4. square.sideLength=newValue.sideLength
  5. }
  6. }
  7. varsquare:Square{
  8. willSet{
  9. triangle.sideLength=newValue.sideLength
  10. }
  11. }
  12. init(size:Double,name:String){
  13. square=Square(sideLength:size,name:name)
  14. triangle=EquilateralTriangle(sideLength:size,name:name)
  15. }
  16. }
  17. vartriangleAndSquare=TriangleAndSquare(size:10,name:"anothertestshape")
  18. triangleAndSquare.square.sideLength
  19. triangleAndSquare.triangle.sideLength
  20. triangleAndSquare.square=Square(sideLength:50,name:"largersquare")
  21. triangleAndSquare.triangle.sideLength
类中的方法和一般的函数有一个重要的区别,函数的参数名只在函数内部使用,但是方法的参数名需要在调用的时候显式说明(除了第一个参数)。默认情况下,方法的参数名和它在方法内部的名字一样,不过你也可以定义第二个名字,这个名字被用在方法内部。
  1. classCounter{
  2. varcount:Int=0
  3. funcincrementBy(amount:Int,numberOfTimestimes:Int){
  4. count+=amount*times
  5. }
  6. }
  7. varcounter=Counter()
  8. counter.incrementBy(2,numberOfTimes:7)
处理变量的可选值时,你可以在操作(比如方法、属性和子脚本)之前加?。如果?之前的值是nil,?后面的东西都会被忽略,并且整个表达式返回nil。否则,?之后的东西都会被运行。在这两种情况下,整个表达式的值也是一个可选值。
  1. letoptionalSquare:Square?=Square(sideLength:2.5,name:"optionalsquare")
  2. letsideLength=optionalSquare?.sideLength
枚举和结构体
使用enum来创建一个枚举。就像类和其他所有命名类型一样,枚举可以包含方法。
  1. enumRank:Int{
  2. caseAce=1
  3. caseTwo,Three,Four,Five,Six,Seven,Eight,Nine,Ten
  4. caseJack,Queen,King
  5. funcsimpleDescription()->String{
  6. switchself{
  7. case.Ace:
  8. return"ace"
  9. case.Jack:
  10. return"jack"
  11. case.Queen:
  12. return"queen"
  13. case.King:
  14. return"king"
  15. default:
  16. returnString(self.toRaw())
  17. }
  18. }
  19. }
  20. letace=Rank.Ace
  21. letaceRawValue=ace.toRaw()
练习:写一个函数,通过比较它们的原始值来比较两个Rank值。
在上面的例子中,枚举原始值的类型是Int,所以你只需要设置第一个原始值。剩下的原始值会按照顺序赋值。你也可以使用字符串或者浮点数作为枚举的原始值。
使用toRaw和fromraw函数来在原始值和枚举值之间进行转换。
  1. ifletconvertedRank=Rank.fromraw(3){
  2. letthreeDescription=convertedRank.simpleDescription()
  3. }
枚举的成员值是实际值,并不是原始值的另一种表达方法。实际上,如果原始值没有意义,你不需要设置。
  1. enumSuit{
  2. caseSpades,Hearts,Diamonds,Clubs
  3. funcsimpleDescription()->String{
  4. switchself{
  5. case.Spades:
  6. return"spades"
  7. case.Hearts:
  8. return"hearts"
  9. case.Diamonds:
  10. return"diamonds"
  11. case.Clubs:
  12. return"clubs"
  13. }
  14. }
  15. }
  16. lethearts=Suit.Hearts
  17. letheartsDescription=hearts.simpleDescription()
练习:给Suit添加一个color方法,对spades和clubs返回“black”,对hearts和diamonds返回“red”。
注意:有两种方式可以引用Hearts成员:给hearts常量赋值时,枚举成员Suit.Hearts需要用全名来引用,因为常量没有显式指定类型。在switch里,枚举成员使用缩写.Hearts来引用,因为self的值已经知道是一个suit。已知变量类型的情况下你可以使用缩写。
使用struct来创建一个结构体。结构体和类有很多相同的地方,比如方法和构造器。它们结构体之间最大的一个区别就是 结构体是传值,类是传引用。
  1. structCard{
  2. varrank:Rank
  3. varsuit:Suit
  4. funcsimpleDescription()->String{
  5. return"The\(rank.simpleDescription())of\
  6. (suit.simpleDescription())"
  7. }
  8. }
  9. letthreeOfSpades=Card(rank:.Three,suit:.Spades)
  10. letthreeOfSpadesDescription=threeOfSpades.simpleDescription()
练习:给Card添加一个方法,创建一副完整的扑克牌并把每张牌的rank和suit对应起来。
一个枚举成员的实例可以有实例值。相同枚举成员的实例可以有不同的值。创建实例的时候传入值即可。实例值和原始值是不同的:枚举成员的原始值对于所有实例都是相同的,而且你是在定义枚举的时候设置原始值。
例如,考虑从服务器获取日出和日落的时间。服务器会返回正常结果或者错误信息。
  1. enumServerResponse{
  2. caseResult(String,String)
  3. caseError(String)
  4. }
  5. letsuccess=ServerResponse.Result("6:00am","8:09pm")
  6. letfailure=ServerResponse.Error("Outofcheese.")
  7. switchsuccess{
  8. caselet.Result(sunrise,sunset):
  9. letserverResponse="Sunriseisat\(sunrise)andsunsetisat\(sunset)."
  10. caselet.Error(error):
  11. letserverResponse="Failure...\(error)"
  12. }
练习:给ServerResponse和switch添加第三种情况。
注意:如何从ServerResponse中提取日升和日落时间。
接口和扩展
使用protocol来声明一个接口。
  1. protocolExampleProtocol{
  2. varsimpleDescription:String{get}
  3. mutatingfuncadjust()
  4. }
类、枚举和结构体都可以实现接口。
  1. classSimpleClass:ExampleProtocol{
  2. varsimpleDescription:String="Averysimpleclass."
  3. varanotherProperty:Int=69105
  4. funcadjust(){
  5. simpleDescription+="Now100%adjusted."
  6. }
  7. }
  8. vara=SimpleClass()
  9. a.adjust()
  10. letaDescription=a.simpleDescription
  11. structSimpleStructure:ExampleProtocol{
  12. varsimpleDescription:String="Asimplestructure"
  13. mutatingfuncadjust(){
  14. simpleDescription+="(adjusted)"
  15. }
  16. }
  17. varb=SimpleStructure()
  18. b.adjust()
  19. letbDescription=b.simpleDescription
练习:写一个实现这个接口的枚举。
注意:声明SimpleStructure时候mutating关键字用来标记一个会修改结构体的方法。SimpleClass的声明不需要标记任何方法因为类中的方法经常会修改类。
使用extension来为现有的类型添加功能,比如添加一个计算属性的方法。你可以使用扩展来给任意类型添加协议,甚至是你从外部库或者框架中导入的类型。
  1. extensionInt:ExampleProtocol{
  2. varsimpleDescription:String{
  3. return"Thenumber\(self)"
  4. }
  5. mutatingfuncadjust(){
  6. self+=42
  7. }
  8. }
  9. 7.simpleDescription
练习:给Double类型写一个扩展,添加absoluteValue功能。
你可以像使用其他命名类型一样使用接口名——例如,创建一个有不同类型但是都实现一个接口的对象集合。当你处理类型是接口的值时,接口外定义的方法不可用。
  1. letprotocolValue:ExampleProtocol=a
  2. protocolValue.simpleDescription
  3. //protocolValue.anotherProperty//Uncommenttoseetheerror
即使protocolValue变量运行时的类型是simpleClass,编译器会把它的类型当做ExampleProtocol。这表示你不能调用类在它实现的接口之外实现的方法或者属性。
泛型
在尖括号里写一个名字来创建一个泛型函数或者类型。
  1. funcrepeat<ItemType>(item:ItemType,times:Int)->ItemType[]{
  2. varresult=ItemType[]()
  3. foriin0..times{
  4. result+=item
  5. }
  6. returnresult
  7. }
  8. repeat("knock",4)
你也可以创建泛型类、枚举和结构体。
  1. //ReimplementtheSwiftstandardlibrary'soptionaltype
  2. enumOptionalValue<T>{
  3. caseNone
  4. caseSome(T)
  5. }
  6. varpossibleInteger:OptionalValue<Int>=.None
  7. possibleInteger=.some(100)
在类型名后面使用where来指定一个需求列表——例如,要限定实现一个协议的类型,需要限定两个类型要相同,或者限定一个类必须有一个特定的父类。
  1. funcanyCommonElements<T,UwhereT:Sequence,U:Sequence,T.GeneratorType.Element:Equatable,T.GeneratorType.Element==U.GeneratorType.Element>(lhs:T,rhs:U)->Bool{
  2. forlhsIteminlhs{
  3. forrhsIteminrhs{
  4. iflhsItem==rhsItem{
  5. returntrue
  6. }
  7. }
  8. }
  9. returnfalse
  10. }
  11. anyCommonElements([1,3],[3])
练习:修改anyCommonElements函数来创建一个函数,返回一个数组,内容是两个序列的共有元素。
简单起见,你可以忽略where,只在冒号后面写接口或者类名。<T: Equatable>和<T where T: Equatable>是等价的。

Swift 2的更多相关文章

  1. HTML5 WebSocket实现点对点聊天的示例代码

    这篇文章主要介绍了HTML5 WebSocket实现点对点聊天的示例代码的相关资料,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  2. ios – 在Swift的UIView中找到UILabel

    我正在尝试在我的UIViewControllers的超级视图中找到我的UILabels.这是我的代码:这是在Objective-C中推荐的方式,但是在Swift中我只得到UIViews和CALayer.我肯定在提供给这个方法的视图中有UILabel.我错过了什么?我的UIViewController中的调用:解决方法使用函数式编程概念可以更轻松地实现这一目标.

  3. ios – 声明NSDictionary并在Swift中添加键值对?

    我一直在尝试使用类类型键和值来声明一个NSDictionary,如下所示:这里,“Category”和“SubCategory”是全局类.我知道我不能将类类型用于关键字段.但是,无论如何,我应该做到这一点.有没有办法做到这一点?如何声明专门的NSDictionary或类似的东西来做到这一点?

  4. ios – 在Swift中将输入字段字符串转换为Int

    所以我非常擅长制作APP广告Swift,我试图在文本字段中做一些非常简单的输入,取值,然后将它们用作Int进行某些计算.但是’vardistance’有些东西不正确它是导致错误的最后一行代码.它说致命错误:无法解开Optional.None解决方法在你的例子中,距离是一个Int?否则称为可选的Int..toInt()返回Int?因为从String到Int的转换可能失败.请参阅以下示例:

  5. ios – Swift相当于`[NSDictionary initWithObjects:forKeys:]`

    Swift的原生字典是否与[NSDictionaryinitWithObjects:forKeys:]相当?假设我有两个带键和值的数组,并希望将它们放在字典中.在Objective-C中,我这样做:当然我可以通过两个数组迭代一个计数器,使用vardict:[String:Int]并逐步添加东西.但这似乎不是一个好的解决方案.使用zip和enumerate可能是同时迭代两者的更好方法.然而,这种方法

  6. 如何在iOS中检测文本(字符串)语言?

    例如,给定以下字符串:我想检测每个声明的字符串中使用的语言.让我们假设已实现函数的签名是:如果没有检测到语言,则返回可选字符串.因此,适当的结果将是:有一个简单的方法来实现它吗?

  7. xamarin – 崩溃在AccountStore.Create().保存(e.Account,“);

    在Xamarin.Forms示例TodoAwsAuth中https://developer.xamarin.com/guides/xamarin-forms/web-services/authentication/oauth/成功登录后,在aOnAuthenticationCompleted事件中,应用程序在尝试保存到Xamarin.Auth时崩溃错误说不能对钥匙串说期待着寻求帮助.解决方法看看你

  8. ios – 将视频分享到Facebook

    我正在编写一个简单的测试应用程序,用于将视频从iOS上传到Facebook.由于FacebookSDK的所有文档都在Objective-C中,因此我发现很难在线找到有关如何使用Swift执行此操作的示例/教程.到目前为止我有这个在我的UI上放置一个共享按钮,但它看起来已禁用,从我读到的这是因为没有内容设置,但我看不出这是怎么可能的.我的getVideoURL()函数返回一个NSURL,它肯定包含视

  9. xcode – 错误“线程1:断点2.1”

    我正在研究RESTAPI管理器.这是一个错误,我无法解决它.我得到的错误在下面突出显示.当我打电话给这个班级获取资源时:我评论的线打印:Thread1:breakpoint2.1我需要修复错误的建议.任何建议都非常感谢解决方法您可能在不注意的情况下意外设置了断点.单击并拖动代表断路器外部断点的蓝色刻度线以将其擦除.

  10. ios – 更改导航栏标题swift中的字符间距

    类型的值有人可以帮我这个或建议一种不同的方式来改变swift中导航栏标题中的字符间距吗?解决方法您无法直接设置属性字符串.你可以通过替换titleView来做一个技巧

随机推荐

  1. Swift UITextField,UITextView,UISegmentedControl,UISwitch

    下面我们通过一个demo来简单的实现下这些控件的功能.首先,我们拖将这几个控件拖到storyboard,并关联上相应的属性和动作.如图:关联上属性和动作后,看看实现的代码:

  2. swift UISlider,UIStepper

    我们用两个label来显示slider和stepper的值.再用张图片来显示改变stepper值的效果.首先,这三个控件需要全局变量声明如下然后,我们对所有的控件做个简单的布局:最后,当slider的值改变时,我们用一个label来显示值的变化,同样,用另一个label来显示stepper值的变化,并改变图片的大小:实现效果如下:

  3. preferredFontForTextStyle字体设置之更改

    即:

  4. Swift没有异常处理,遇到功能性错误怎么办?

    本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请发送邮件至dio@foxmail.com举报,一经查实,本站将立刻删除。

  5. 字典实战和UIKit初探

    ios中数组和字典的应用Applicationschedule类别子项类别名称优先级数据包contactsentertainment接触UIKit学习用Swift调用CocoaTouchimportUIKitletcolors=[]varbackView=UIView(frame:CGRectMake(0.0,0.0,320.0,CGFloat(colors.count*50)))backView

  6. swift语言IOS8开发战记21 Core Data2

    上一话中我们简单地介绍了一些coredata的基本知识,这一话我们通过编程来实现coredata的使用。还记得我们在coredata中定义的那个Model么,上面这段代码会加载这个Model。定义完方法之后,我们对coredata的准备都已经完成了。最后强调一点,coredata并不是数据库,它只是一个框架,协助我们进行数据库操作,它并不关心我们把数据存到哪里。

  7. swift语言IOS8开发战记22 Core Data3

    上一话我们定义了与coredata有关的变量和方法,做足了准备工作,这一话我们来试试能不能成功。首先打开上一话中生成的Info类,在其中引用头文件的地方添加一个@objc,不然后面会报错,我也不知道为什么。

  8. swift实战小程序1天气预报

    在有一定swift基础的情况下,让我们来做一些小程序练练手,今天来试试做一个简单地天气预报。然后在btnpressed方法中依旧增加loadWeather方法.在loadWeather方法中加上信息的显示语句:运行一下看看效果,如图:虽然显示出来了,但是我们的text是可编辑状态的,在storyboard中勾选Editable,再次运行:大功告成,而且现在每次单击按钮,就会重新请求天气情况,大家也来试试吧。

  9. 【iOS学习01】swift ? and !  的学习

    如果不初始化就会报错。

  10. swift语言IOS8开发战记23 Core Data4

    接着我们需要把我们的Rest类变成一个被coredata管理的类,点开Rest类,作如下修改:关键字@NSManaged的作用是与实体中对应的属性通信,BinaryData对应的类型是NSData,CoreData没有布尔属性,只能用0和1来区分。进行如下操作,输入类名:建立好之后因为我们之前写的代码有些地方并不适用于coredata,所以编译器会报错,现在来一一解决。

返回
顶部