In Xcode 7 Beta 6 global function advance(startIndex, n) is no longer available. You must use Index.advancedBy(n) to get the same result. advance(startIndex, n) is very useful in substringing. Since you cannot pass an Int to the Index type in substring function.
Prior to Xcode 7 Beta 6
var str = "abc"
firstChar = str.substringToIndex(advance(str.startIndex, 1)) // a
Xcode 7 Beta6
var str = "abc"
firstChar = str.substringToIndex(str.startIndex.advancedBy(1)) // a
Showing posts with label Swift. Show all posts
Showing posts with label Swift. Show all posts
29 August, 2015
15 April, 2015
Default Behavior of UIPopoverPresentationController Changed in iOS 8.3
I have working with an adaptive app that can run on all size class. Before updating to iOS 8.3, the popover behavior is the same in iPad and iPhone 6 Plus landscape mode. However, after updating to iOS 8.3, the popover in iPhone 6 Plus has changed to FormSheet. This is because the popover now not only check the horizontal size class, but also the vertical size class. Popover will present normally in vertical regular like iPad, and present as FormSheet in vertical compact. So how can we fix it?
Below is the old method to disable the adaptivity of popover in horizontal compact. But it not enough in iOS 8.3.
In the demo of WWDC 2014 Session 214 "View Controller Advancements in iOS 8", Bruce explained a trick that let you present popover in horizontal compact environment (e.g. iPhone). Without this trick, the popover will be presented in modal. Let take a look what is the trick.
func adaptivePresentationStyleForPresentationController(controller: UIPresentationController) -> UIModalPresentationStyle {
return UIModalPresentationStyle.None
}
This function in UIAdaptivePresentationControllerDelegate can modify the UIModalPresentationSytle when the device is changed from horizontal regular to horizontal compact. By return .None, popover will no longer adaptive to horizontal compact and will presented in popover just like that in horizontal regular.
Okay, we now know that popover check now check both horizontal and vertical size class. Therefore, we need to use a new funcation. Apple introduced a new function in iOS 8.3 which let you determine the UIModalPresentationStyle by the TraitCollection.
func adaptivePresentationStyleForPresentationController(controller: UIPresentationController!, traitCollection: UITraitCollection!) -> UIModalPresentationStyle {
return UIModalPresentationStyle.None
}
This new function can be used to replace the old function. I have disabled the adaptivity of popover in whatever size class and everything works just like in iOS 8.2.
Reference: iOS 8.3 API Diffs
Below is the old method to disable the adaptivity of popover in horizontal compact. But it not enough in iOS 8.3.
In the demo of WWDC 2014 Session 214 "View Controller Advancements in iOS 8", Bruce explained a trick that let you present popover in horizontal compact environment (e.g. iPhone). Without this trick, the popover will be presented in modal. Let take a look what is the trick.
func adaptivePresentationStyleForPresentationController(controller: UIPresentationController) -> UIModalPresentationStyle {
return UIModalPresentationStyle.None
}
This function in UIAdaptivePresentationControllerDelegate can modify the UIModalPresentationSytle when the device is changed from horizontal regular to horizontal compact. By return .None, popover will no longer adaptive to horizontal compact and will presented in popover just like that in horizontal regular.
Okay, we now know that popover check now check both horizontal and vertical size class. Therefore, we need to use a new funcation. Apple introduced a new function in iOS 8.3 which let you determine the UIModalPresentationStyle by the TraitCollection.
func adaptivePresentationStyleForPresentationController(controller: UIPresentationController!, traitCollection: UITraitCollection!) -> UIModalPresentationStyle {
return UIModalPresentationStyle.None
}
This new function can be used to replace the old function. I have disabled the adaptivity of popover in whatever size class and everything works just like in iOS 8.2.
Reference: iOS 8.3 API Diffs
12 April, 2015
Problem When Appending Tuple into Array
I've got the following error message when trying to append a tuple into an array.
Missing argument for parameter #2 in call
Here is my tuple
(String, UInt64, NSDate?)
I get the tuple from another function and then append to the array
var fileRecords: [(String, UInt64, NSDate?)]?
var tuple = createArchive()
self.records!.append(tuple!) <- error here
However, if I assign the tuple to a constant first and then append that constant to array. It is work.
var tuple = createArchive()
let aTuple = tuple!
self.records!.append(aTuple) <- Okay
Missing argument for parameter #2 in call
Here is my tuple
(String, UInt64, NSDate?)
I get the tuple from another function and then append to the array
var fileRecords: [(String, UInt64, NSDate?)]?
var tuple = createArchive()
self.records!.append(tuple!) <- error here
However, if I assign the tuple to a constant first and then append that constant to array. It is work.
var tuple = createArchive()
let aTuple = tuple!
self.records!.append(aTuple) <- Okay
15 March, 2015
Element Name in Tuple only Local Significant
Tuple is a new data type in Swift. It can group multiple values of different type of data into a single tuple. It is useful when you want to return multiple values in a function.
There is an example in the Swift document from Apple, you can give elements a name when you create the tuple.
let http200Status = (statusCode: 200, description: "OK")
println("The status code is \(http200Status.statusCode)")
// prints "The status code is 200"
println("The status message is \(http200Status.description)")
// prints "The status message is OK"
The element name makes the code more readable and meaningful. However, the name can only be used within the scope. If you get a tuple that returned from a function. The element name will be removed. The element can be gotten by index number of the element.
func getHttp200Status() -> (Int, String) {
let http200Status = (statusCode: 200, description: "OK")
return http200Status
}
var status = getHttp200Status()
println("The status code is \(http200Status.statusCode)")
// '(Int, String)' does not have a member named 'statusCode'
println("The status code is \(http200Status.0)")
Elements are numbered from 0 and autocomplete will tell you what is inside the tuple.
Tuple是Swift的新資料類型. 它可以把多個不同資料類型的值組合在一個tuple內. 當你想function回傳多個值時, 這個會很有用.
這裡有一個範例在Apple的Swift文件. 當創建一個tuple時, 你可以給予每一個元素一個名字.
let http200Status = (statusCode: 200, description: "OK")
println("The status code is \(http200Status.statusCode)")
// prints "The status code is 200"
println("The status message is \(http200Status.description)")
// prints "The status message is OK"
這個名字能令你的code可讀性更高及更有意思. 不過, 這個名字只可以在scope內使用. 如果你由一個function取得一個tuple, 元素的名字會被移除. 而元素仍能以索引數字取得.
func getHttp200Status() -> (Int, String) {
let http200Status = (statusCode: 200, description: "OK")
return http200Status
}
var status = getHttp200Status()
println("The status code is \(http200Status.statusCode)")
// '(Int, String)' does not have a member named 'statusCode'
println("The status code is \(http200Status.0)")
元素索引由0開始, 自動完成會告訴你有甚麼元素在tuple裡.
There is an example in the Swift document from Apple, you can give elements a name when you create the tuple.
let http200Status = (statusCode: 200, description: "OK")
println("The status code is \(http200Status.statusCode)")
// prints "The status code is 200"
println("The status message is \(http200Status.description)")
// prints "The status message is OK"
The element name makes the code more readable and meaningful. However, the name can only be used within the scope. If you get a tuple that returned from a function. The element name will be removed. The element can be gotten by index number of the element.
func getHttp200Status() -> (Int, String) {
let http200Status = (statusCode: 200, description: "OK")
return http200Status
}
var status = getHttp200Status()
println("The status code is \(http200Status.statusCode)")
// '(Int, String)' does not have a member named 'statusCode'
println("The status code is \(http200Status.0)")
Elements are numbered from 0 and autocomplete will tell you what is inside the tuple.
Tuple是Swift的新資料類型. 它可以把多個不同資料類型的值組合在一個tuple內. 當你想function回傳多個值時, 這個會很有用.
這裡有一個範例在Apple的Swift文件. 當創建一個tuple時, 你可以給予每一個元素一個名字.
let http200Status = (statusCode: 200, description: "OK")
println("The status code is \(http200Status.statusCode)")
// prints "The status code is 200"
println("The status message is \(http200Status.description)")
// prints "The status message is OK"
這個名字能令你的code可讀性更高及更有意思. 不過, 這個名字只可以在scope內使用. 如果你由一個function取得一個tuple, 元素的名字會被移除. 而元素仍能以索引數字取得.
func getHttp200Status() -> (Int, String) {
let http200Status = (statusCode: 200, description: "OK")
return http200Status
}
var status = getHttp200Status()
println("The status code is \(http200Status.statusCode)")
// '(Int, String)' does not have a member named 'statusCode'
println("The status code is \(http200Status.0)")
元素索引由0開始, 自動完成會告訴你有甚麼元素在tuple裡.
30 August, 2014
Adding UITapGestureRecognizer to UIImageView
By default, UIImageView doesn't respond to any touch, such as UITabGestureRecognizer. However, you can enable it by either attributes inspector or code.
- Attributes Inspector
check the box "User Interaction Enabled" in the Interaction section
- Code
self.imageView.userInteractionEnabled = true
Then, add a UITabGestureRecognizer to UIImageView.
var tapGesture = UITapGestureRecognizer(target: self, action: "tapped:")
self.imageView.addGestureRecognizer(tapGesture)
func tapped(recognizer: UITapGestureRecognizer) {
println("tapped")
}
Okay, finished. Run and test it :)
UIImageView預設是不會對任何觸碰有反應, 例如UITabGestureRecognizer. 但可以透過attributes inspector或code去啟動.
- Attributes Inspector
在Interaction部份, 鈎選"User Interaction Enabled".
- Code
self.imageView.userInteractionEnabled = true
之後, 把UITabGestureRecognizer加到UIImageView中.
var tapGesture = UITapGestureRecognizer(target: self, action: "tapped:")
self.imageView.addGestureRecognizer(tapGesture)
func tapped(recognizer: UITapGestureRecognizer) {
println("tapped")
}
完成了 :)
- Attributes Inspector
check the box "User Interaction Enabled" in the Interaction section
- Code
self.imageView.userInteractionEnabled = true
Then, add a UITabGestureRecognizer to UIImageView.
var tapGesture = UITapGestureRecognizer(target: self, action: "tapped:")
self.imageView.addGestureRecognizer(tapGesture)
func tapped(recognizer: UITapGestureRecognizer) {
println("tapped")
}
Okay, finished. Run and test it :)
UIImageView預設是不會對任何觸碰有反應, 例如UITabGestureRecognizer. 但可以透過attributes inspector或code去啟動.
- Attributes Inspector
在Interaction部份, 鈎選"User Interaction Enabled".
- Code
self.imageView.userInteractionEnabled = true
之後, 把UITabGestureRecognizer加到UIImageView中.
var tapGesture = UITapGestureRecognizer(target: self, action: "tapped:")
self.imageView.addGestureRecognizer(tapGesture)
func tapped(recognizer: UITapGestureRecognizer) {
println("tapped")
}
完成了 :)
26 August, 2014
Problem with UIImage(named:) initializer
When I tried to use UIImage(named:) in an init of an object, I had got the following error.
I fixed it by adding an initializer before it. I found that in UIImage Class Reference, init(name:) is classified as "Cached Image Loading Routines", and others are classified as "Initializing Images". Does it mean init(named:) doesn't perform initialization?
當我使用 UIImage(named:) 時, 我得到以下錯誤.
我把一個 initializer 放在前面就解決這個問題. 在 UIImage Class Reference, init(named:) 是被分類為"Cached Image Loading Routines", 而其他被分類為"Initializing Images". 意思是不是 init(named:) 不會進行初始?
I fixed it by adding an initializer before it. I found that in UIImage Class Reference, init(name:) is classified as "Cached Image Loading Routines", and others are classified as "Initializing Images". Does it mean init(named:) doesn't perform initialization?
當我使用 UIImage(named:) 時, 我得到以下錯誤.
我把一個 initializer 放在前面就解決這個問題. 在 UIImage Class Reference, init(named:) 是被分類為"Cached Image Loading Routines", 而其他被分類為"Initializing Images". 意思是不是 init(named:) 不會進行初始?
19 August, 2014
Initializing Properties of Object
In Swift, you must initialize all properties of an object either in declaration or in initialization. Otherwise, Xcode will warn you that there is property haven't initialized yet.
If you want to initialize these properties in init(), you should put the super.init() at the end of init(). You will get an error if you put super.init() before all properties have been initialized.
If you want to initialize these properties in init(), you should put the super.init() at the end of init(). You will get an error if you put super.init() before all properties have been initialized.
14 July, 2014
Half-Open Range Operator changed in Xcode 6.0 Beta 3
You may see in the Swift programming guide, half-open range operator is written as 0..9 (the range is from 0 to 8, not including 9). In beta 3, it is changed to 0..<9 (much more meaningful, but personally feel it is not beautiful). A less than symbol is added.
05 July, 2014
The difference of let array and let dictionary
In Swift, let is used to declare constant and var is used to declare variable. In Objective-C, there are array and mutable array, also dictionary and mutable dictionary. Instinctively, you may think constant array is not mutable and the values inside the array is not editable. The truth is a constant array is not mutable but you may edit the values inside. However, constant dictionary is not the same as array. A constant dictionary is not mutable or editable.
I don't know why constant array is that special :(
Update:
Start from Beta 3, let array is now completely immutable, and var array is completely mutable.
Link: Swift Language Changes in Xcode 6 beta 3
I don't know why constant array is that special :(
Update:
Start from Beta 3, let array is now completely immutable, and var array is completely mutable.
Link: Swift Language Changes in Xcode 6 beta 3
22 June, 2014
Array type of parameter in function
Two ways to pass an array into a function:
1. Passing in a sequence
func sumOf(numbers: Int...) -> Int {
...
}
sumOf(42, 597, 12)
2. Passing in a Array object
func sumOf(numbers: [Int]) -> Int {
...
}
let numbers = [42, 597, 12]
sumOf(numbers)
In the 1st example, array is passed as a sequence of Int. In the 2nd example, an object of Array is required, otherwise, there will be an error. You may see that no matter you use Int... or [Int], numbers is an array inside the function.
1. Passing in a sequence
func sumOf(numbers: Int...) -> Int {
...
}
sumOf(42, 597, 12)
2. Passing in a Array object
func sumOf(numbers: [Int]) -> Int {
...
}
let numbers = [42, 597, 12]
sumOf(numbers)
In the 1st example, array is passed as a sequence of Int. In the 2nd example, an object of Array is required, otherwise, there will be an error. You may see that no matter you use Int... or [Int], numbers is an array inside the function.
Learning Swift
Here are the links to download free Swift Programming Guide from iBooks Store.
- The Swift Programming Language
- Using Swift with Cocoa and Objective-C
18 June, 2014
Swift is the future
Apple announced Swift in WWDC 2014. Although you can combine Swift and Objective-C in one app. Swift is the future of Apple developer. Swift is more safe, more efficient, more easy to write and read.
In this blog, I will focus more in Swift, including how Swift works, how Swift combine Objective-C, etc. Stay Tuned :D
In this blog, I will focus more in Swift, including how Swift works, how Swift combine Objective-C, etc. Stay Tuned :D
Subscribe to:
Posts (Atom)


