本篇是Swift內部培訓整理的PPT材料,主要內容來源于蘋果Swift編程語言官方教程,參考了網上的一些視頻課程內容。在教程介紹完之后,本人附帶實現了一個項目開發中的常用場景的Demo:基于導航欄和Tab欄的應用。
1.Swift概述
我們先來看一篇文章:《蘋果新貴 Swift之前世今生》
Swift是用于設計iOS及Mac OS X應用的一門新語言。
1.1.Swift特點
1.2.Swift代碼的文件擴展名
*.swift
2.第一個Swift程序
2.1.使用Xcode PRoject編寫
2.2.使用Playground編寫
我們可以基于 Playground 做這些事情:
3.常量與變量
let關鍵詞聲明常量,var關鍵詞聲明變量。
let maximumNumberOfLoginAttempts = 10 // 常量只有在初始化的時候可以賦值var currentLoginAttempt = 0
4.運算符和表達式
4.1.運算符
4.2.表達式
1.不指定數據類型
var a1 = 10var a2 = 20var a = a1 > a2 ? "a1":"a2"
2.指定數據類型
var a1:Int = 10var a2:Int = 20var a = a1 > a2 ? "a1":"a2"
3.可以有分號結尾
var a1:Int = 10; var a2:Int = 20var a = a1 > a2 ? "a1":"a2"
4.3.注釋
///* */
5.數據類型
5.1.整型
Swift提供8、16、32、64位形式的有符號及無符號整數,這些整數類型遵循C語言的命名規約。與Swift中的所有類型一樣,這些整數類型的名稱以大寫字母開頭。
Swift還提供了一個整數類型Int;
Swift還提供了無符號整數類型UInt。
5.2.浮點型
5.3.數字型
表示數字如下:
let decimalInteger = 17 // 表示是10進制let binaryInteger = 0b10001 // 二進制17let octalInteger = 0o21 // 8進制17let hexadecimalInteger = 0x11 // 16進制17
5.4.布爾類型
true和false
let orangesAreOrange = truelet turnipsAreDelicious = false
6.數據類型轉換
6.1.整型轉換
不同類型的整數常量或變量所能存儲的值域不同,需要顯示地轉換
let twoThousand:UInt16 = 2000let one:UInt8 = 1//let twoThousandAndOne = twoThousand + one // 錯誤let twoThousandAndOne = twoThousand + UInt16(one) // 正確
6.2.整型與浮點數轉換
整數與浮點數類型之間的轉換,需要顯示地轉換:
let three = 3let pointOneFourOneFiveNine = 0.14159let pi = Double(three) + pointOneFourOneFiveNine
7.字符串類型
7.1.字符串初始化
1.初始化
let someString = "Some string literal value"let wiseWords = "/"Imagination is more important than knowledge/" - Einstein"let dollarSign = "/x24" // $,Unicode scalar U+0024
2.空值
var emptyString = "" // 空串初始化var anotherEmptyString = String() // 通過初始化函數初始化
3.空值判斷
if emptyString.isEmpty{ println("Nothing to see here")}if emptyString == ""{ println("Nothing to see here")}
7.2.字符串修改
var 聲明的可以修改,let不能修改。
var variableString = "Horse"variableString += " and carriage"
7.3.字符串插入
斜杠+括號+變量
let multiplier = 3let message = "/(multiplier) times 2.5 is /(Double(multiplier) * 2.5)"
7.4.字符串長度
使用countElements函數。OC中使用length屬性。
let unusualMenagerie = "Koala , Snail, Penguin"println("unusualMenagerie has /(countElements(unusualMenagerie)) characters")
7.5.比較字符串相等
let quotation = "We're a lot alike,you and I."let sameQuotation = "We're a lot alike,you and I."if quotation == sameQuotation{ println("These two strings are considered equal")}
8.元組(tuple)類型
元組將多個值組合為單個值。元組內的值可以是任意類型,各元素不必是相同的類型,元組在作為函數返回值時尤其有用。
1.定義方法1
let http404Error = (404,"Not Found")println("The status code is /(http404Error.0)");println("The status message is /(http404Error.1)");
2.定義方法2
let http200Error = (statusCode:404,discription:"Not Found")println("The status code is /(http200Error.statusCode)");println("The status message is /(http200Error.discription)");
9.可選(Optional)類型
9.1.使用可選類型
我們在如下情況下使用可選類型:
let possibleNumber = "123"let convertedNumber:Int?=possibleNumber.toInt()
“Int?”是可選類型
if convertedNumber{ println("/(possibleNumber) has an Integer value of /(convertedNumber!)")}else{ println("/(possibleNumber) could not be convented to an integer")}
convertedNumber是從可選類型中取值
9.2.使用nil
我們可以為可選類型的變量設置nil值,表示沒有任何值。
var serverResponseCode:Int?=404serverResponseCode = nil
如果不是可選類型,那么是不能設置為nil的
10.數組
10.1.數組初始化
基本語法:
[value1,value2,value3]var shoppingList:String[] = [“Eggs","Milk"]
對比一下OC中的方式:
NSArray *array = @[@"aa",@"bb"];
10.2.數組追加元素
使用append函數追加或通過+操作符:
var shoppingList:String[] = ["Eggs","Milk"]shoppingList.append("Flour")shoppingList += ["Cheese","Butter"]
10.3.數組插入元素
使用insert方法:
var shoppingList:String[] = ["Eggs","Milk"]shoppingList.insert("Butter", atIndex: 0)shoppingList += ["Cheese","Chocolate Spread"]
比較一下OC中:
[array insertObject:@"dd" atIndex:1];
10.4.數組刪除元素
使用removeAtIndex方法
var shoppingList:String[] = ["Eggs","Milk","Butter"]let deleteItem = shoppingList.removeAtIndex(2)println(deleteItem)println(shoppingList)
10.5.數組長度
使用count屬性(和OC中一樣):
var shoppingList:String[] = ["Eggs","Milk","Butter"]println("The shopping list contains /(shoppingList.count) items.")
10.6.數組遍歷
1.遍歷方法1
var shoppingList:String[] = ["Eggs","Milk","Butter"]for item in shoppingList{ println(item)}
2.遍歷方法2
有循環變量:
for(index,value) in enumerate(shoppingList){ println("Item /(index + 1):/(value)")}
11.字典
11.1.字典初始化
基本語法:
[key1:value1,key2:value2,key3:value3]var airports:Dictionary<String,String> = ["TYO":"Tokyo","DUB":"Dublin"]
11.2.字典追加元素
var airports:Dictionary<String,String> = ["TYO":"Tokyo","DUB":"Dublin"]airports["LHR"] = "Lonton"println("The dictionary of airports contains /(airports.count)")
11.3.字典刪除元素
通過removeValueForKey(key)方法刪除
var airports:Dictionary<String,String> = ["TYO":"Tokyo","DUB":"Dublin"]if let removedValue = airports.removeValueForKey("DUB"){ println("The removed airport's name is /(removedValue)")}else{ println("The airports dictionary does not contains a value for DUB")}
11.4.字典長度
使用count屬性
println("The count of airport's is /(airports.count)")
11.5.字典遍歷
1.遍歷字典
var airports:Dictionary<String,String> = ["TYO":"Tokyo","DUB":"Dublin"]for (airportCode,airportName) in airports{ println("/(airportCode):/(airportName)")}
2.遍歷鍵和值
for airportCode in airports.keys{ println("Airport code:/(airportCode)")}for airportName in airports.values{ println("Airport name/(airportName)")}
3.獲得鍵和值的數組
let airportCodes = Array(airports.keys)let airportNames = Array(airports.values)
12.控制語句
12.1.分支語句
1.條件語句if-else
if boolean-expression{statement1;}[else if boolean-expression{statement2;}][else{statement3;}]
2.多分支語句switch
switch some value to consider{case value1,value2,value3:respond to value1default:otherwise}
每個case不需要顯示地添加break,每個case至少有一條語句。可以比較任何類型。
12.2.循環語句
1.while語句
while condition{statements}
示例:
var i = 100var r = 0var s = 0var t = 0while i < 1000 { r = i / 100 ; s = (i - r * 100) / 10; t = i - r * 100 - s * 10; if(i == r * r * r + s * s * s + t * t * t){ println("i=/(i)"); } i++}
2.do-while語句
do{statements}while condition
示例:
var i = 100var r = 0var s = 0var t = 0do{ r = i / 100 ; s = (i - r * 100) / 10; t = i - r * 100 - s * 10; if(i == r * r * r + s * s * s + t * t * t){ println("i=/(i)"); } i++}while i < 1000
3.for語句
for initialization;condition;increment{statements}
示例:
var i = 8var r = 0var s = 0for var j = 0;j <= i;j++ { r = j * j; s = j * j * j; println("/(j)的平方:/(r) /(j)的立方:/(s)");}
4.for in語句
一般用于遍歷集合
1.遍歷范圍
for index in 1...5{ println("/(index) times 5 is /(index * 5)");}
2.忽略循環變量
let base = 3let power = 10var answer = 1for _ in 1...power{ answer *= base;}println("/(base) to the power of /(power) is /(answer)")
3.遍歷數組
let names = ["Anna","Alex","Jack"]for name in names{ println("Hello,/(name)")}
4.遍歷字典
let numberofLegs = ["spider":8,"ant":6,"car":4];for(animalName,legCount) in numberofLegs{ println("/(animalName) have /(legCount) legs")}
5.遍歷字符串
for character in "Hello"{ println(character)}
12.3.跳轉語句
let integerDescribe = 5var description = "The number /(integerDescribe) is"switch integerDescribe{case 2,3,5: description += " a prise number,and also" fallthroughdefault: description += " an integer.";}
4.return
13.函數
13.1.函數定義
使用func定義一個函數。調用函數使用它的名字加上小括號中的參數列表。使用->分隔參數的名字和返回值類型。
函數聲明:
func greet(name:String,day:String) -> String{ return "Hello /(name),today is /(day)"}
函數調用:
greet("Bob", "Tuesday")
13.2.無返回值函數
func sayGoodBye(personName:String){ println("Goodbye,/(personName)");}sayGoodBye("Tony");
13.3.多返回值函數
使用元組類型返回多個值
func count(string:String) -> (vowels:Int,consonants:Int,others:Int){ var vowel = 0,consonant = 0,other = 0; for character in string{ switch String(character).lowercaseString{ case "a","e","i","o","u": ++vowel; case "b","c","d","f","g","h","j","k","l","m","n","p","q","r","s","t","v","w","x","y","z": ++consonant; default: ++other; } } return (vowel,consonant,other);}let total = count("Some thing is change!");println("/(total.vowels)元音,/(total.consonants)輔音")
13.4.嵌入函數
func chooseStepFunction(backwards:Bool) -> (Int) -> Int{ func stepForward(input:Int) -> Int{ return input + 1 } func stepBackward(input:Int) -> Int{ return input - 1 } return backwards ? stepBackward : stepForward}var currentValue = -4// moveNearerToZero是一個函數指針let moveNearerToZero = chooseStepFunction(currentValue > 0)while currentValue != 0{ println("/(currentValue)......") currentValue = moveNearerToZero(currentValue)}
14.閉包(Closure)
語法:
{(parameters) -> return type instatements}
示例:數組排序
采用函數實現:
let names = ["Chris","Alex","Ewa","Barry","Daniella"]func backwards(s1:String,s2:String) -> Bool{ return s1 > s2}// sort排序函數,backwards通過排序規則的函數var reversed = sort(names,backwards)println(reversed)
采用閉包實現:
var reversed = sort(names,{(s1:String,s2:String) -> Bool in return s1 > s2})println(reversed)
15.類與結構體
類和結構體有很多共性:
類比結構體多出的功能:
15.1.類和結構體的定義
定義類和結構體:
class SomeClass{// class definition goes here}struct SomeStructure{// structure definition goes here}
示例:
struct Resolution{var width = 0var height = 0}class VideoMode{var resolution = Resolution()var interfaced = falsevar frameRate = 0.0var name:String?}
15.2.類和結構體的實例化
struct Resolution{var width = 0var height = 0}class VideoMode{var resolution = Resolution()var interfaced = falsevar frameRate = 0.0var name:String?}let someResolution = Resolution()// let someResolution = Resolution(width:10,height:20)let someVideoMode = VideoMode()
16.屬性
16.1.屬性的存儲
屬性的主要作用是存儲數據,可以分為常量屬性和變量屬性;
struct FixedLengthRange{ var firstValue:Int let length:Int}var rangeOfThreeItems = FixedLengthRange(firstValue:0,length:3)rangeOfThreeItems.firstValue = 6// 注意:length是常量屬性,值是不可以修改的
16.2.延時存儲屬性
延時存儲屬性是初始化時候不分配值,直到第一次使用它。屬性@lazy聲明。
為什么要用延時存儲屬性?當一個屬性是一個龐大類時,并且這個屬性很少用到,那么就可以考慮使用延時存儲屬性,這樣可以避免大量數據加載到內存中。
class DataImporter{ var fileName = "data.txt"}class DataManager{ @lazy var importer = DataImporter() var data = ""} let manager = DataManager();manager.data += "Some Data"manager.data += "Some more data"println(manager.importer.fileName)
去掉@lazy關鍵字在playground里面試試,看看有什么不一樣?
16.3.計算屬性
有的時候一些屬性是通過其他的屬性計算得出的,通過get和set訪問器對其訪問。
// 定義Pointstruct Point{ var x = 0.0,y = 0.0}// 定義Sizestruct Size{ var width = 0.0,height = 0.0}// 定義Rectstruct Rect{ var origin = Point() var size = Size() var center:Point{ get{ let centerX = origin.x + (size.width / 2) let centerY = origin.y + (size.height / 2) return Point(x:centerX,y:centerY) } set(newCenter){ origin.x = newCenter.x - (size.width / 2) origin.y = newCenter.y - (size.height / 2) } }}var square = Rect(origin:Point(x:0.0,y:0.0),size:Size(width:10.0,height:20.0))let initialSquareCenter = square.centersquare.center = Point(x:15.0,y:15.0)println("square origin is now at (/(square.origin.x),/(square.origin.y))")
16.4.屬性觀察者
為了監聽屬性的變化,swift通過了屬性觀察者。
class StepCounter{ var totalSteps:Int = 0{ willSet(newTotalSteps){ println("About to set totalSteps to /(newTotalSteps)") } didSet{ if totalSteps >= oldValue{ println("Added /(totalSteps - oldValue) steps") } } }}let stepCounter = StepCounter()stepCounter.totalSteps = 200stepCounter.totalSteps = 360
16.5.靜態屬性
靜態屬性在結構體中使用static定義,類中使用class定義。
struct SomeStructure{ static var storedTypeProperty = "Some Value"}class SomeClass{ class var computedTypeProperty:Int{ return 3 }}
17.方法
Swift中的方法是與特定類型(類和結構體)相關的函數
17.1.方法
class Counter{ var count = 0 func increment(){ count++ } func incremmentBy(amount:Int){ count += amount } func reset(){ count = 0 }}let counter = Counter()counter.increment()counter.incremmentBy(5)counter.reset()
17.2.使用self
self代表當前對象。
struct Point{ var x = 0.0,y = 0.0 func isToTheRightOfX(x:Double) -> Bool{ return self.x > x }}let somePoint = Point(x:4.0,y:5.0)if somePoint.isToTheRightOfX(1.0){ println("This point is to the right of the line where x == 1.0")}
18.下標
18.1.定義下標
還記得字典嗎?
var numberOfLegs = ["bird":2,"cat":4,"ant":6]let birdLeg = numberOfLegs["bird"]
["bird"]就是下標
下標可以在類和結構體中定義
18.2.只讀下標
struct TimesTable{ let multiplier:Int subscript(index:Int) -> Int{ return multiplier * index }}let threeTimesTable = TimesTable(multiplier:3)println("six times three is /(threeTimesTable[6])")
19.繼承
Swift中的類能夠繼承其他類的屬性、方法等。
19.1.定義基類
class Vehicle{ var numberOfWheels:Int var maxPassengers:Int func description() -> String{ return "/(numberOfWheels) wheels;up to /(maxPassengers)" } init(){ numberOfWheels = 0 maxPassengers = 1 }}let someVehicle = Vehicle()
19.2.定義子類
class Bicycle:Vehicle{ init() { super.init() numberOfWheels = 2 }}let bicycle = Bicycle()println("Bicycle:/(bicycle.description())")
19.3.重寫(Overriding)
子類能夠重寫父類的方法、屬性、下標。
19.3.1方法重寫
class Vehicle{ var numberOfWheels:Int var maxPassengers:Int func description() -> String{ return "/(numberOfWheels) wheels;up to /(maxPassengers)" } init(){ numberOfWheels = 0 maxPassengers = 1 }}class Car:Vehicle{ var speed:Double = 0.0 init() { super.init() numberOfWheels = 4 maxPassengers = 5 } override func description() -> String{ return super.description() + ";" + "traveling at /(speed)" }}let car = Car()println("Car:/(car.description())")
19.3.2屬性重寫
class Vehicle{ var numberOfWheels:Int var maxPassengers:Int func description() -> String{ return "/(numberOfWheels) wheels;up to /(maxPassengers)" } init(){ numberOfWheels = 0 maxPassengers = 1 }}class Car:Vehicle{ var speed:Double = 0.0 init() { super.init() numberOfWheels = 4 maxPassengers = 5 } override func description() -> String{ return super.description() + ";" + "traveling at /(speed)" }}class SpeedLimitedCar:Car{ override var speed:Double{ get{ return super.speed } set{ super.speed = min(newValue,40.0) } }}let limitedCar = SpeedLimitedCar()limitedCar.speed = 60.0println("SpeedLimitedCar:/(limitedCar.description())")
20.構造器(Initializer)
為了初始化結構體和類等類型的實例屬性。
20.1.默認構造器
struct Fahrenheit{ var temperature:Double init(){ temperature = 32.0 }}var f = Fahrenheit() // 調用默認構造器init(),沒有參數和返回值println("The default temperature is /(f.temperature)")
20.2.自定義構造器
定義類兩個構造器:init(fromFahrenheit:) 和 init(fromKelvin:)
struct Celsius{ var temperatureInCelsius:Double init(fromFahrenheit fahrenheit:Double){ temperatureInCelsius = (fahrenheit - 32.0) / 1.8 } init(fromKelvin kelvin:Double){ temperatureInCelsius = kelvin - 273.15 }// init(fahrenheit:Double){// temperatureInCelsius = (fahrenheit - 32.0) / 1.8// }// // init(kelvin:Double){// temperatureInCelsius = kelvin - 273.15// }}let boilingPointOfWater = Celsius(fromFahrenheit:212.0)let freezingPointOfWater = Celsius(fromKelvin:273.15)//let boilingPointOfWater = Celsius(fahrenheit:212.0)//let freezingPointOfWater = Celsius(kelvin:273.15)
21.析構器(Deinitializer)
析構器與構造器相反,在對象釋放時候調用。
使用關鍵字deinit,語法如下:
deinit{}
實例:
class Player{ var coinsInPurse:Int init(coins:Int){ println("call init") coinsInPurse = coins } func winCoins(coins:Int){ coinsInPurse += 10 } deinit{ coinsInPurse = 0 }}var playerOne:Player? = Player(coins:100)println("PlayerOne has coins /(playerOne!.coinsInPurse)")playerOne = nil;
22.擴展(Extension)
在現有類和結構體的基礎上,擴展新的功能。
語法:
extension SomeType{}extension SomeType:SomeProtocol,AnotherProtocol{}
OC中的擴展:
@interface UIImage (UIImageScale)
22.1.計算屬性
extension Double{ var km:Double{return self * 1000.0} var m:Double{return self} var cm:Double{return self / 100.0} var mm:Double{return self / 1000.0}}let oneInch = 25.4.mmprintln("OneInch is /(oneInch) meters")
22.2.使用構造器
struct Size{ var width = 0.0,height = 0.0}struct Point{ var x = 0.0,y = 0.0}struct Rect{ var origin = Point() var size = Size()}extension Rect{ init(center:Point,size:Size){ let originX = center.x - (size.width / 2) let originY = center.y - (size.height / 2) self.init(origin:Point(x:originX,y:originY),size:size) }}let centerRect = Rect(center:Point(x:4.0,y:4.0),size:Size(width:3.0,height:3.0))
22.3.方法擴展
extension Int{ func message() -> String{ var message = ""; switch self{ case 0: message = "成功" case -1: message = "用戶登錄失敗" default: message = "未知錯誤" } return message; }}3.message();0.message();(-1).message();
23.協議(Protocol)
協議是為方法、屬性等定義一套規范,沒有具體的實現。協議能夠被類、結構體等具體實現。
protocol SomeProtocol{}struct SomeStructure:SomeProtocol{}class SomeClass:SomeProtocol{}
23.1.屬性
// 1.set和get訪問器protocol SomeProtocol{ var mustBeSettable:Int{get set} var doesNotNeedToBeSettable:Int{get}}// 2.靜態屬性protocol AnotherProtocol{ class var someTypeProperty:Int{get set}}// 3.只讀protocol FullyNamed{ var fullName:String{get}}
示例:
protocol FullyNamed{ var fullName:String{get}}struct Person : FullyNamed{ var fullName:String}let john = Person(fullName:"John Appleseed")class Starship : FullyNamed{ var prefix:String? var name:String init(name:String,prefix:String? = nil){ self.name = name self.prefix = prefix } var fullName:String{ return (prefix ? prefix! + " " : "") + name }}var ncc1701 = Starship(name:"Enterprise",prefix:"USS")println("/(ncc1701.fullName)")
23.2.方法
// 1.定義方法protocol RandomNumberGenerator{ func random() -> Double}// 2.定義靜態方法protocol SomeProtocol{ class func someTypeMethod()}
示例:
class LinearCongruentialGenerator:RandomNumberGenerator{ var lastRandom = 42.0 let m = 139968.0 let a = 3877.0 let c = 29573.0 func random() -> Double{ lastRandom = ((lastRandom * a + c) % m) return lastRandom / m }}let generator = LinearCongruentialGenerator()println("Here's a random number:/(generator.random())")
23.3.把協議作為類型使用
protocol RandomNumberGenerator{ func random() -> Double}class LinearCongruentialGenerator:RandomNumberGenerator{ var lastRandom = 42.0 let m = 139968.0 let a = 3877.0 let c = 29573.0 func random() -> Double{ lastRandom = ((lastRandom * a + c) % m) return lastRandom / m }}class Dice{ let sides:Int let generator:RandomNumberGenerator init(sides:Int,generator:RandomNumberGenerator){ self.sides = sides self.generator = generator } func roll() -> Int{ return Int(generator.random() * Double(sides)) + 1 }}var d6 = Dice(sides:6,generator:LinearCongruentialGenerator())for _ in 1...5{ println("Random dice roll is /(d6.roll())")}
24.Swift的應用
在這一部分,我實現了一個小Demo:導航欄和Tab欄結合使用。具體代碼說明如下:
24.1.項目結構說明
主要文件說明:
24.2.運行效果截圖
iPhone 5S截圖:
iPhone 4S截圖:
24.3.主要代碼
AppDelegate里面:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary?) -> Bool { self.window = UIWindow(frame: UIScreen.mainScreen().bounds) var tabbarViewCtrl = TabBarViewController(nibName:nil,bundle:nil);// var navigationViewController = UINavigationController(rootViewController:tabbarViewCtrl); var navigationViewController = CustomNavigationController(rootViewController: tabbarViewCtrl); self.window!.rootViewController = navigationViewController; self.window!.makeKeyAndVisible() return true }
TabBarViewController:
init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) { super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) self.title = "任務"; } override func viewDidLoad() { super.viewDidLoad() configureTabBar(); } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } /******************************************************************************* * 方法名稱:configureTabBar * 功能描述:配置TabBar控件 * 輸入參數: * 輸出參數: ******************************************************************************/ func configureTabBar() { self.view.backgroundColor = UIColor.whiteColor(); self.tabBar.hidden = true; // 隱藏自帶的Tab var width = self.view.frame.size.width; var height = self.view.frame.size.height; self.myTabbar = UIView(frame:CGRectMake(0, height - 48 - 64, width, 112)); let currentVersion = UIDevice.currentDevice().systemVersion; if (currentVersion.isIos7()) { self.myTabbar!.frame = CGRectMake(0, height - 48, width, 112); } self.myTabbar!.backgroundColor = UIColor(patternImage:UIImage(named:"tab_bg_ico.png")); self.view.addSubview(self.myTabbar); self.view.bringSubviewToFront(self.myTabbar); // 任務 var btnTask = UIButton.buttonWithType(UIButtonType.Custom) as UIButton; // 后面必須要加上as UIButton btnTask.frame = CGRectMake(0, 0, 80, 48); btnTask.tag = 100; btnTask.selected = true; btnTask.setImage(UIImage(named:"tabtask_sel_ico.png"),forState:UIControlState.Normal); btnTask.addTarget(self,action: "tabBarButtonClicked:",forControlEvents:UIControlEvents.TouchUpInside); self.myTabbar!.addSubview(btnTask); // 單據 var btnBill = UIButton.buttonWithType(UIButtonType.Custom) as UIButton; btnBill.frame = CGRectMake(80, 0, 80, 48); btnBill.tag = 101; btnBill.setImage(UIImage(named:"tabbill_nor_ico.png"),forState:UIControlState.Normal); btnBill.addTarget(self,action: "tabBarButtonClicked:",forControlEvents:UIControlEvents.TouchUpInside); self.myTabbar!.addSubview(btnBill); // 查詢 var btnQuery = UIButton.buttonWithType(UIButtonType.Custom) as UIButton; btnQuery.frame = CGRectMake(160, 0, 80, 48); btnQuery.tag = 102; btnQuery.setImage(UIImage(named:"tabquery_nor_ico.png"),forState:UIControlState.Normal); btnQuery.addTarget(self,action: "tabBarButtonClicked:",forControlEvents:UIControlEvents.TouchUpInside); self.myTabbar!.addSubview(btnQuery); // 設置 var btnSetting = UIButton.buttonWithType(UIButtonType.Custom) as UIButton; btnSetting.frame = CGRectMake(240, 0, 80, 48); btnSetting.tag = 103; btnSetting.setImage(UIImage(named:"tabset_nor_ico.png"),forState:UIControlState.Normal); btnSetting.addTarget(self,action:"tabBarButtonClicked:",forControlEvents:UIControlEvents.TouchUpInside); self.myTabbar!.addSubview(btnSetting); var taskViewCtrl = MyTaskViewController(nibName:"MyTaskViewController",bundle:nil); var billViewCtrl = MyBillViewController(); var queryViewCtrl = QueryViewController(nibName:"QueryViewController",bundle:nil); var settingViewCtrl = SettingViewController(nibName:"SettingViewController",bundle:nil); self.viewControllers = [taskViewCtrl,billViewCtrl,queryViewCtrl,settingViewCtrl]; } /******************************************************************************* * 方法名稱:configureTabBar * 功能描述:配置TabBar控件 * 輸入參數: sender:事件源 * 輸出參數: ******************************************************************************/ func tabBarButtonClicked(sender:UIButton) { var index = sender.tag; var btnTask = self.view.viewWithTag(100) as UIButton var btnBill = self.view.viewWithTag(101) as UIButton var btnQuery = self.view.viewWithTag(102) as UIButton var btnSetting = self.view.viewWithTag(103) as UIButton switch index{ case 100: // 任務 self.title = "任務"; btnTask.selected = true; btnBill.selected = false; btnQuery.selected = false; btnSetting.selected = false; btnTask.setImage(UIImage(named:"tabtask_sel_ico.png"),forState:UIControlState.Normal); btnBill.setImage(UIImage(named:"tabbill_nor_ico.png"),forState:UIControlState.Normal); btnQuery.setImage(UIImage(named:"tabquery_nor_ico.png"),forState:UIControlState.Normal); btnSetting.setImage(UIImage(named:"tabset_nor_ico.png"),forState:UIControlState.Normal); case 101: // 單據 self.title = "單據"; btnTask.selected = false; btnBill.selected = true; btnQuery.selected = false; btnSetting.selected = false; btnTask.setImage(UIImage(named:"tabtask_nor_ico.png"),forState:UIControlState.Normal); btnBill.setImage(UIImage(named:"tabbill_sel_ico.png"),forState:UIControlState.Normal); btnQuery.setImage(UIImage(named:"tabquery_nor_ico.png"),forState:UIControlState.Normal); btnSetting.setImage(UIImage(named:"tabset_nor_ico.png"),forState:UIControlState.Normal); case 102: // 查詢 self.title = "查詢"; btnTask.selected = false; btnBill.selected = false; btnQuery.selected = true; btnSetting.selected = false; btnTask.setImage(UIImage(named:"tabtask_nor_ico.png"),forState:UIControlState.Normal); btnBill.setImage(UIImage(named:"tabbill_nor_ico.png"),forState:UIControlState.Normal); btnQuery.setImage(UIImage(named:"tabquery_sel_ico.png"),forState:UIControlState.Normal); btnSetting.setImage(UIImage(named:"tabset_nor_ico.png"),forState:UIControlState.Normal); case 103: // 設置 self.title = "設置"; btnTask.selected = false; btnBill.selected = false; btnQuery.selected = false; btnSetting.selected = true; btnTask.setImage(UIImage(named:"tabtask_nor_ico.png"),forState:UIControlState.Normal); btnBill.setImage(UIImage(named:"tabbill_nor_ico.png"),forState:UIControlState.Normal); btnQuery.setImage(UIImage(named:"tabquery_nor_ico.png"),forState:UIControlState.Normal); btnSetting.setImage(UIImage(named:"tabset_sel_ico.png"),forState:UIControlState.Normal); default: println("No Selected Items"); } self.selectedIndex = index - 100; }
CustomNavigationController:
class CustomNavigationController: UINavigationController{ init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) { super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) // Custom initialization } init(rootViewController: UIViewController!) { return super.init(rootViewController: rootViewController); } override func viewDidLoad() { super.viewDidLoad() let currentVersion = UIDevice.currentDevice().systemVersion; if (currentVersion.isIos7()) { self.navigationBar.setBackgroundImage(UIImage(named:"navbg_ico.png").stretchableImageWithLeftCapWidth(20,topCapHeight: 30),forBarMetrics:UIBarMetrics.Default); } else { self.navigationBar.setBackgroundImage(UIImage(named:"navbg_ico.png"),forBarMetrics:UIBarMetrics.DefaultPrompt); } } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } override func pushViewController(viewController: UIViewController!, animated: Bool) { super.pushViewController(viewController,animated:animated); } override func popViewControllerAnimated(animated: Bool) -> UIViewController! { return super.popViewControllerAnimated(animated); }}
MyTaskViewController
override func viewDidLoad() { super.viewDidLoad() self.tableView.registerClass(UITableViewCell.self,forCellReuseIdentifier: "Cell"); } override func viewWillAppear(animated: Bool) { var width = self.view.frame.size.width var height = self.view.frame.size.height self.tableView.frame = CGRectMake(0, 0, width, height - 48); } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } // ========================================================================= // Table view data source func numberOfSectionsInTableView(tableView: UITableView!) -> Int { return 1; } func tableView(tableView: UITableView!, numberOfRowsInSection section: Int) -> Int { return 50; } func tableView(tableView: UITableView!, heightForRowAtIndexPath indexPath: NSIndexPath!) -> CGFloat { return 56; } func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! { let cell = tableView .dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell; var lblBillCode = UILabel(frame:CGRectMake(10,4,140,22)); lblBillCode.text = "JTBX1404020601"; lblBillCode.font = UIFont(name: "Arial",size: 16); cell.addSubview(lblBillCode); var lblContent = UILabel(frame:CGRectMake(160,4,150,22)); lblContent.text = "市內交通費用報銷單"; lblContent.textAlignment = NSTextAlignment.Right; lblContent.font = UIFont(name: "Arial",size: 16); cell.addSubview(lblContent); var lblTime = UILabel(frame:CGRectMake(160,30,150,22)); lblTime.text = "2014-05-23 22:10:10"; lblTime.font = UIFont(name: "Arial",size: 14); lblTime.textColor = UIColor.grayColor(); lblTime.textAlignment = NSTextAlignment.Right; cell.addSubview(lblTime); return cell; } // ========================================================================= // Table view data delegate func tableView(tableView: UITableView!, didSelectRowAtIndexPath indexPath: NSIndexPath!){ println("row = %d",indexPath.row) }
NSStringExt:
extension String { /******************************************************************************* * 方法名稱:isIos7 * 功能描述:配置TabBar控件 * 輸入參數: * 輸出參數:true:IOS7及以上系統;false:IOS7以下系統。 ******************************************************************************/ func isIos7() -> Bool? { return self >= "7.0" } func stringHeightWith(fontSize:CGFloat,width:CGFloat)->CGFloat { var font = UIFont.systemFontOfSize(fontSize) var size = CGSizeMake(width,CGFLOAT_MAX) var paragraphStyle = NSMutableParagraphStyle() paragraphStyle.lineBreakMode = .ByWordWrapping; var attributes = [NSFontAttributeName:font, NSParagraphStyleAttributeName:paragraphStyle.copy()] var text = self as NSString var rect = text.boundingRectWithSize(size, options:.UsesLineFragmentOrigin, attributes: attributes, context:nil) return rect.size.height }}
源碼下載
新聞熱點
疑難解答