所有小技巧都是基于Swift3
1.如何判断运行的设备类型,比如是iPad还是iPhone
//判断设备类型,iPad或者iPhone
if UIDevice.current.userInterfaceIdiom == .pad {
print("设备是iPad")
}else if UIDevice.current.userInterfaceIdiom == .phone {
print("设备是iPhone")
}
2.如何使用Timer
//创建timer,创建好5S后,会执行指定的方法,并且附带了userinfo信息,该信息可以不带
var timer: Timer? = Timer.scheduledTimer(timeInterval: 5, target: self, selector: #selector(show(timer:)), userInfo: ["custom":"msg"], repeats: false)
func show(timer: Timer) {
print(Date())
//打印出附带信息
print(timer.userInfo)
}
//销毁timer
if let time = timer {
//销毁timer需要调用invalidate,并且,可以把timer置为nil
time.invalidate()
timer = nil
}
3.如何快速给方法、属性等添加文档
首先,写出方法或属性
func chreatString(name: String) -> String {
return "你好,\(name)"
}
然后在方法上一行使用:command + option + / 快捷键,会出现如下所示:
/// <#Description#>
///
/// - parameter name: <#name description#>
///
/// - returns: <#return value description#>
func chreatString(name: String) -> String {
return "你好,\(name)"
}
依次填入对应的值
/// 生成一句话
///
/// - parameter name: 名字
///
/// - returns: 返回生成的话
func chreatString(name: String) -> String {
return "你好,\(name)"
}
然后点击该方法,就能在属性观察器中查看到文档了
4.将数组内元素组装成各种需求的字符串
let array: [Character] = ["1","2","3"]
//将一个字符数组依次组装成字符串,没有间隔
print(String(array))//123
let array2 = ["12","34","56"]
//将一个字符串数组依次组装成字符串,没有间隔
print(String(array2.flatMap { String.CharacterView($0) } ))
//或者
print(array2.joined())//123456
//将一个字符串数组依次组装成字符串,有指定间隔字符
print(array2.joined(separator: "-"))//12-34-56
//将一个字符串数组依次拆开,并且指定间隔字符
let string = array2.flatMap { String.CharacterView($0) }.map { String($0) }
print(string.joined(separator: ","))//1,2,3,4,5,6
//将一个float数组,组装成一个字符串,指定间隔字符
let floatArray = [1, 2, 3, 4]
let stringArray = floatArray.flatMap { String($0) }
print(stringArray.joined(separator: "-"))//1-2-3-4
///////////////////////////////////////////////
//如果只是想简单的知道数组的内容,那么,使用description即可
let arr = [1, 2, 3]
print(arr.description)//[1, 2, 3]
//特别的,如果是自定义的类,也想能够这样子打印出来,只需要重写description属性,即可实现
let array = [Test(name: "a", age: 11), Test(name: "b", age: 22), Test(name: "c", age: 33)]
print(array.description)
//没有重写description属性,打印如下:[<_TtCC1s14ViewController4Test: 0x600000254730>, <_TtCC1s14ViewController4Test: 0x6000002546d0>, <_TtCC1s14ViewController4Test: 0x600000254700>]
//重写后,打印如下:[a--11, b--22, c--33]
class Test: NSObject{
let name: String
let age: Int
init(name: String, age: Int) {
self.name = name
self.age = age
}
override var description: String {
return "\(name)--\(age)"
}
}
5.使用try?和try!处理异常
//会抛出异常的方法
func someThrowingFunction() throws -> Int {}
//可以使用try?来调用,如果没有抛出异常,则返回x=Int?类型的值,抛出异常,则x=nil
let x = try? someThrowingFunction()
//try?和下方的代码是等价的
let y: Int?
do {
y = try someThrowingFunction()
} catch {
y = nil
}
//try!则是,如果抛出异常,程序会终止,不抛出,则返回解包后的值。try!用于100%确定不会抛出异常时使用
6.如何判断一个变量是否是某个类型
class Test {}
let test = Test()
print(type(of: test))//Test
print(Test.self)//Test
type(of: test) == Test.self//true
//判断Array
let arr = [1, 3]
type(of: arr) == Array<Int>.self//true
7.class和static的区别
class和static都表示类属性或者类方法。区别在于
class A {
class func func1() -> String {
return "1"
}
static func func2() -> String {
return "2"
}
}
class B: A {
//正常使用,不会报错
override class func func1() -> String {
return "a"
}
//会报错,那是因为不能够重写static修饰的类方法
override static func func2() -> String {
return "b"
}
//可以看出,static相当于就是class final,不能够被重写
}
8.解决给UIImageView添加手势事件,无法触发的问题
let image = UIImageView(frame: CGRect(x: 20, y: 100, width: view.frame.width-40, height: 100))
//必须要设置isuserinteractionenable为true时,才能触发手势事件
image.isUserInteractionEnabled = true
view.addSubview(image)
let tap = UITapGestureRecognizer(target: self, action: #selector(tap(gr:)))
image.addGestureRecognizer(tap)
func tap(gr: UITapGestureRecognizer) {
print("点击了")
}
9.如何使用NSLocalizedString加载内容
//首先,扩展一个方法
extension String {
func localized(withComment:String) -> String {
return NSLocalizedString(self, tableName: nil, bundle: Bundle.main, value: "", comment: withComment)
}
}
//在 .strings文件中添加
/* with !!! */
"Hi" = "Привет!!!";
//使用
myLabel.text = "Hi".localized(withComment: "with !!!")
10.data与string互相转换
//data->string
let dataStr = String(data: data, encoding: .utf8)
//string->data
let data = "DataString".data(using: .utf8)
11.如何判断app是否是首次打开
//如何记录用户是否是第一次打开app
let userDefaults = UserDefaults.standard
if userDefaults.bool(forKey: "hasRunBefore") == false {
//可以在这里清空以前保存的钥匙串的内容,或者做别的操作,比如加载首次打开的欢迎界面等
//接下来更新userdefaults
userDefaults.set(true, forKey: "hasRunBefore")
userDefaults.synchronize()
}
12.保留指定位数的小数,进行四舍五入
extension Double {
//保留指定位小数,四舍五入
func roundTo(places: Int) -> Double {
let divisor = pow(10.0, Double(places))
return (self * divisor).rounded() / divisor
}
}
let x = 0.123456.roundTo(places: 5)//0.12346
13.GCD实现子线程执行任务
//后台执行操作
DispatchQueue.global(qos: .background).async {
print("子线程执行")
DispatchQueue.main.async {
print("子线程执行")
}
}
//可以扩展一个方法,增加延时和执行完成后的回调处理
extension DispatchQueue {
static func background(delay: Double = 0.0, background: (()->Void)? = nil, completion: (() -> Void)? = nil) {
DispatchQueue.global(qos: .background).async {
background?()
if let completion = completion {
DispatchQueue.main.asyncAfter(deadline: .now() + delay, execute: {
completion()
})
}
}
}
}
//使用
DispatchQueue.background(delay: 3.0, background: {
//后台要执行的操作
}, completion: {
//后台执行完成后,延时3秒执行回调
})
DispatchQueue.background(background: {
//后台要执行的操作
}, completion:{
//后台执行完成后,就执行回调
})
DispatchQueue.background(delay: 3.0, completion:{
//不需要后台执行任何操作,延时3秒执行回调
})
14.oc中的isKindOfClass方法,在swift中如何使用
//在OC中,这样使用
if ([touch.view isKindOfClass: UIPickerView.class]) {
}
//swift中,使用is
let x: Any = "x"
if x is String {
print("true")
}
15.如何实现nsrange与range之间的互相转换
extension String {
func nsRange(from range: Range<String.Index>) -> NSRange {
let from = range.lowerBound.samePosition(in: utf16)
let to = range.upperBound.samePosition(in: utf16)
return NSRange(location: utf16.distance(from: utf16.startIndex, to: from),
length: utf16.distance(from: from, to: to))
}
}
extension String {
func range(from nsRange: NSRange) -> Range<String.Index>? {
guard
let from16 = utf16.index(utf16.startIndex, offsetBy: nsRange.location, limitedBy: utf16.endIndex),
let to16 = utf16.index(utf16.startIndex, offsetBy: nsRange.location + nsRange.length, limitedBy: utf16.endIndex),
let from = from16.samePosition(in: self),
let to = to16.samePosition(in: self)
else { return nil }
return from ..< to
}
}
//使用
let str = "a👿b🇩🇪c"
let r1 = str.range(of: "🇩🇪")!
// range -> NSRange:
let n1 = str.nsRange(from: r1)
print((str as NSString).substring(with: n1)) // 🇩🇪
// NSRange -> range:
let r2 = str.range(from: n1)!
print(str.substring(with: r2)) // 🇩🇪
16.如何生成UUID
let uuid1 = UUID().uuidString
17.如何实现base64string与string之间的互相转换
let plainString = "你好"
//string -> base64string
let plainData = plainString.data(using: .utf8)
let base64string = plainData?.base64EncodedString()
print(base64string!)//5L2g5aW9
//base64string -> string
if let decodedData = Data(base64Encoded: base64string!) {
let decodedString = String(data: decodedData, encoding: .utf8)
print(decodedString!)//你好
}
18.如何将十六进制字符串#ffffff或ffffff字符串转换成相应的uicolor实例
//将#ffffff或ffffff字符串转换成响应的uicolor实例
func hexStringToUIColor (hex:String) -> UIColor {
var cString:String = hex.trimmingCharacters(in: .whitespacesAndNewlines).uppercased()
if (cString.hasPrefix("#")) {
cString.remove(at: cString.startIndex)
}
if ((cString.characters.count) != 6) {
return UIColor.gray
}
var rgbValue:UInt32 = 0
Scanner(string: cString).scanHexInt32(&rgbValue)
return UIColor(
red: CGFloat((rgbValue & 0xFF0000) >> 16) / 255.0,
green: CGFloat((rgbValue & 0x00FF00) >> 8) / 255.0,
blue: CGFloat(rgbValue & 0x0000FF) / 255.0,
alpha: CGFloat(1.0)
)
}