SwiftRecord
2019-08-06 本文已影响0人
喵喵粉
- keyWindow
var kKeyWindow: UIWindow? {
// if #available(iOS 13.0, *) {
// var window: UIWindow?
// if let cs = UIApplication.shared.connectedScenes as? Set<UIWindowScene> {
// for windowScene in cs {
// if windowScene.activationState == .foregroundActive {
// window = windowScene.windows.last
// }
// return window
// }
// }
// }
if #available(iOS 13.0, *) {
let keyWindow = UIApplication.shared.connectedScenes
.filter({$0.activationState == .foregroundActive})
.map({$0 as? UIWindowScene})
.compactMap({$0})
.first?.windows
.filter({$0.isKeyWindow}).first
return keyWindow
}
return UIApplication.shared.keyWindow
}
var left = 50.0
if let kw = kKeyWindow {
if #available(iOS 11.0, *) {
left = kw.safeAreaInsets.left
DebugLog(kw.safeAreaInsets)
}
}
var kIsPhoneX: Bool {
if #available(iOS 11.0, *) {
return kKeyWindow?.safeAreaInsets.bottom ?? 0.0 > 0.0
} else {
return false
}
if #available(iOS 11.0, *) {
if let window1 = UIApplication.shared.delegate?.window, let window = window1 {
let zero: CGFloat = 0.0
return window.safeAreaInsets.bottom > zero
} else {
let isMore = UIApplication.shared.keyWindow?.safeAreaInsets.bottom ?? 0.0 > 0.0
return isMore
}
}
return false
}
- 使用keypath
- enum
///大头针颜色
typedef NS_ENUM(NSInteger, MAPinAnnotationColor) {
MAPinAnnotationColorRed = 0, ///< 红色大头针
MAPinAnnotationColorGreen, ///< 绿色大头针
MAPinAnnotationColorPurple ///< 紫色大头针
};
MAPinAnnotationColor(rawValue: index%3)!
- 新建黑名单
fileprivate let filePath: String = {
///每个账号对应一个文件
let doc = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).last!
let folder = "/blackList/"
let fileName = "\(kUserInfo.userId)-blackList"
let path = doc+folder+fileName
//创建blackList文件夹
let fileMgr = FileManager.default
if fileMgr.fileExists(atPath: doc+folder) == false {
do {
try fileMgr.createDirectory(atPath: doc+folder, withIntermediateDirectories: true, attributes: nil)
DebugLog("创建路径\( doc+folder)")
} catch {
DebugLog("创建路径\( doc+folder)捕捉到异常")
}
}
DebugLog(path)
return path
}()
- 清除通知栏内所有通知消息:
要点在于要先把BadgeNumber 设成跟当前不同的值,然后再设成0
UIApplication.shared.applicationIconBadgeNumber = 1
UIApplication.shared.applicationIconBadgeNumber = 0
- 给键盘加按钮
override func awakeFromNib() {
super.awakeFromNib()
addToolbar()
}
fileprivate func addToolbar() {
let toolbar = UIToolbar(frame: CGRect(x: 0, y: 0, width: kScreenW, height: 40.0))
toolbar.isTranslucent = true
toolbar.barStyle = .default
let button = UIButton(frame: CGRect(x: 0, y: 0, width: 80, height: 35))
button.setTitle("完成", for: .normal)
button.setTitleColor(.extTheme, for: .normal)
button.addTarget(self, action: #selector(shouKeyboard), for: .touchUpInside)
let spaceBBI = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
//let doneBBI = UIBarButtonItem(title: "完成", style: .done, target: self, action: #selector(shouKeyboard))
let doneBBI = UIBarButtonItem(customView: button)
toolbar.items = [spaceBBI, doneBBI]
tfName.inputAccessoryView = toolbar
}
@objc fileprivate func shouKeyboard() {
tfName.resignFirstResponder()
}
- switch判断可选类型
var age: Int? = 10
switch age {
case let v?: //这里v进行解包
print(v)
case nil:
print("nil")
}
等价下面的写法
if let v = age {
print(v)
} else {
print("nil")
}
2.case 后面匹配方法
extension String {
static func ~= (pattern: (String) -> Bool, value: String) -> Bool {
return pattern(value)
}
}
func hasSuffixed(_ suffix: String) -> ((String) -> Bool) { return { $0.hasSuffix(suffix) }}
func hasPrefixed(_ prefix: String) -> ((String) -> Bool) {
// return { $0.hasPrefix(prefix) }
//等同上句
return {
(str: String) -> Bool in
str.hasPrefix(prefix)
}
}
var fn = hasPrefixed("123")
print(fn("1253456"))
var str = "123456"
switch str {
case hasPrefixed("123"), hasSuffixed("456"):
print("has prefix 123 或者 hasSuffixed 456")
default:
break
}
extension Int {
static func ~= (pattern: (Int) -> Bool, value: Int) -> Bool {
return pattern(value)
}
}
func isEven(_ i: Int) -> Bool { return i%2 == 0 }
func isOdd(_ i: Int) -> Bool { return i%2 != 0 }
let aaaa = 11
switch aaaa {
case isEven:
print("aaaa \(aaaa) 是偶数")
case isOdd:
print("aaaa \(aaaa) 是奇数")
default:break
}
打印: aaaa 11 是奇数
- 柯里化
// MARK: 柯里化 -
func add(_ v1: Int, _ v2: Int, _ v3: Int) -> Int { return v1 + v2 + v3 }
func addF(_ v: Int) -> (Int) -> Int {
return {$0+v}
}
func minus(_ v1: Int, _ v2: Int, _ v3: Int) -> Int { return v1 - v2 - v3 }
func minusF(_ v3: Int) -> ((Int) -> ((Int) -> Int)) {
return { v2 in
return { v1 in
return v1-v2-v3
}
}
}
prefix func ~<A, B, C, D>(_ fn: @escaping (A, B, C) -> D) -> (C) -> (B) -> (A) -> (D) {
return { c in return { b in return { a in return fn(a, b, c)} } }
}
print((~add)(2)(3)(4), (~minus)(2)(3)(4))
let rsttt = minusF(12)(34)(11)
print(rsttt)
- 为String添加扩展
struct MJ<Base> {
var base: Base
init(_ base: Base) {
self.base = base
}
}
//协议
protocol MJCompatible { }
extension MJCompatible {
var mj: MJ<Self> {
set {}
get { return MJ(self) }
}
static var mj: MJ<Self>.Type {
set {}
get { return MJ<Self>.self }
}
}
/*
extension String {
var mj: MJ<String> { return MJ(self) }
static var mj: MJ<String>.Type { return MJ<String>.self }
}
class Persons { }
extension Persons {
var mj: MJ<Persons> { return MJ(self) }
}
*/
extension String: MJCompatible {}
extension NSString: MJCompatible {}
class Persons { }
extension Persons: MJCompatible {}
//扩展
extension MJ where Base: ExpressibleByStringLiteral {
//计算string中数字个数
var numberCoun: Int {
var count = 0
for c in base as! String where ("0"..."9").contains(c) {
count += 1
}
return count
}
//类方法
static func log() { print("MJ static log") }
}
extension MJ where Base: Persons {
func run() { print("person run---") }
}
let pss = Persons()
print(pss.mj.run())
print("abc123".mj.numberCoun)
print(String.mj.log())
var str2: NSString = "abd12345"
print(str2.mj.numberCoun)
- x
//是否数组
func isArray(_ value: Any) -> Bool { return value is [Any] }
print(isArray([1, "2"]))
print(isArray(NSArray()))
print(isArray("abc"))
/*
true
true
false
*/
- snapkit使用
lbMsg.snp.makeConstraints { (make) in
if #available(iOS 11, *) {
make.top.equalTo(view.safeAreaLayoutGuide.snp.top).offset(0)
make.bottom.equalTo(view.safeAreaLayoutGuide.snp.bottom).offset(0)
} else {
//self.topLayoutGuide.snp.top y在导航栏顶部 无导航栏在状态栏顶部
//self.topLayoutGuide.snp.bottom y在导航栏底部 无导航栏在状态栏底部
make.top.equalTo(self.topLayoutGuide.snp.top).offset(0)
//self.bottomLayoutGuide.snp.top y在tabbar上面 无tabbar在屏幕底部
//self.bottomLayoutGuide.snp.bottom y在tabbar下面 无tabbar在屏幕底部
make.bottom.equalTo(self.bottomLayoutGuide.snp.top).offset(0)
}
make.width.equalTo(100)
make.right.equalTo(0).labeled("标记tag")
}
[oc] tableview效果
if (@available(iOS 11, *)) {
[UIScrollView appearance].contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentAlways;
} else {
self.automaticallyAdjustsScrollViewInsets = NO;
}
cell正常显示.gif
- 归档解档 NSKeyedArchiver & NSKeyedUnarchiver
Employee & Toy 类
import Foundation
public class Toy: NSObject, Codable, NSCoding {
var name: String
init(name: String) {
self.name = name
}
public func encode(with aCoder: NSCoder) {
aCoder.encode(name, forKey: "name")
}
required public init?(coder aDecoder: NSCoder) {
self.name = aDecoder.decodeObject(forKey: "name") as! String
}
}
public class Employee: NSObject, Codable, NSCoding {
var name: String
var id: Int
var favoriteToy: Toy
init(name: String, id: Int, favoriteToy: Toy) {
self.name = name
self.id = id
self.favoriteToy = favoriteToy
}
public func encode(with aCoder: NSCoder) {
aCoder.encode(name, forKey: "name")
aCoder.encode(id, forKey: "id")
aCoder.encode(favoriteToy, forKey: "favoriteToy")
}
required public init?(coder aDecoder: NSCoder) {
self.name = aDecoder.decodeObject(forKey: "name") as! String
self.id = aDecoder.decodeInteger(forKey: "id")
self.favoriteToy = aDecoder.decodeObject(forKey: "favoriteToy") as! Toy
}
}
调用
private func archiverUnarchiver() {
let toy = Toy(name: "John-Toy")
let employee = Employee(name: "John", id: 11, favoriteToy: toy)
print(employee.name, employee.id, employee.favoriteToy.name)
// NSKeyedArchiver & NSKeyedUnarchiver
let archiverData = NSKeyedArchiver.archivedData(withRootObject: employee)
NSKeyedArchiver().finishEncoding()
//changed
employee.name = "Jack"
employee.id = 22
employee.favoriteToy.name = "Jack-Toy"
let ue = NSKeyedUnarchiver.unarchiveObject(with: archiverData) as! Employee
print("now eee:", employee.name, employee.id, employee.favoriteToy.name)
print("old eee:", ue.name, ue.id, ue.favoriteToy.name)
}
/* 打印
now eee: Jack 22 Jack-Toy
old eee: John 11 John-Toy
*/
- json object
menu.json
{
"menu":
{
"id": "file",
"value": "File",
"menuitem":
[
{
"value": "New",
"onclick": "CreateNewDoc()"
},
{
"value": "OPen",
"onclick": "OPenDoc()"
},
{
"value": "Close",
"onclick": "CloseDoc()"
}
]
}
}
private func json2Dic() {
let jsonDic: [String: Any]?
let path = Bundle.main.path(forResource: "menu", ofType: "json")
guard let jsonData = try? Data(contentsOf: URL(fileURLWithPath: path!)) else { return }
//data -> dic
do {
jsonDic = try JSONSerialization.jsonObject(with: jsonData, options: JSONSerialization.ReadingOptions.mutableContainers) as? [String : Any]
} catch {
print(error)
return
}
guard let dic: [String: Any] = jsonDic?["menu"] as? [String : Any] else { return }
//dic -> array
guard let menuItem: [Any] = dic["menuitem"] as? [Any] else { return }
guard menuItem.count>0 else { return }
for item in menuItem {
print(item)
}
}
private func json2Dic1() {
let path = Bundle.main.path(forResource: "menu", ofType: "json")
if let jsonData = try? Data(contentsOf: URL(fileURLWithPath: path!)) {
do {
if let jsonObj: Dictionary<String, Any> = try JSONSerialization.jsonObject(with: jsonData, options: JSONSerialization.ReadingOptions()) as? Dictionary<String, Any> {
if let menuDic: Dictionary<String, Any> = jsonObj["menu"] as? Dictionary<String, Any> {
if let menuItems: [Any] = menuDic["menuitem"] as? [Any] {
for item in menuItems {
print("item: \(item)")
}
}
}
}
} catch {
print("catch error")
}
}
}
- Selector & #selector
passwordTextField.addTarget(self, action: Selector(("changeText")), for: .touchUpInside)
passwordTextField.addTarget(self, action: #selector(abc), for: .touchUpInside)
@objc func abc() {}
func changeText(textField:UITextField) -> Void {}
-
Timer
变量声明初始化用不了self
的属性方法
- 数组以
元祖
形式打印
let titles = ["11", "22", "33", "44"]
for (index, title) in titles.enumerated() {
DebugLog("\(index):" + title)
}
- 类型转换成
String
if let code = notify.object as? String {
loginTest(code: code)
}
if let code = notify.object {
loginTest(code: code as! String)
}
- tabBar设置
图片原色
、标题颜色
func setupUI() {
///用图片的原色
if let items = self.tabBar.items {
for item in items {
item.selectedImage = item.selectedImage?.withRenderingMode(.alwaysOriginal)
}
}
///标题颜色 #81D8D0
tabBar.tintColor = UIColor.extHexDecimalColor(hexadecimal: "#81D8D0")
}
- tableview 默认选中cell
///默认选中第一行
let indexPath = IndexPath(row: 0, section: 0)
DispatchQueue.main.asyncAfter(deadline: .now()) {
self.tvClass.selectRow(at: indexPath, animated: false, scrollPosition: .middle)
self.tableView(self.tvClass, didSelectRowAt: indexPath)
}
- 全局
import
在extension UIViewController
扩展中
@_exported import MBProgressHUD
其它的ViewController
不用import MBProgressHUD
,就可以用MBProgressHUD
-
聊天气泡拉伸
fileprivate func stretchableImageDemo() {
let iv = UIImageView(frame: CGRect(x: 50, y: 100, width: 200, height: 110))
view.addSubview(iv)
iv.backgroundColor = .extRandom
iv.contentMode = .scaleToFill
iv.image = UIImage(named: "chatSend")
//拉伸图片
if let image = UIImage(named: "chatSend") {
iv.image = image.stretchableImage(withLeftCapWidth: Int(image.size.width*0.5), topCapHeight: Int(image.size.height*0.5))
}
}
- 定位请求权限
The app's Info.plist must contain both “NSLocationAlwaysAndWhenInUseUsageDescription” and “NSLocationWhenInUseUsageDescription” keys with string values explaining to the user how the app uses this data
- 精确小数点后2位
///检测改变过的文本是否匹配正则表达式,如果匹配表示可以键入,否则不能键入
func isValid(text: String) -> Bool {
//正则表达式(只支持两位小数)
let regex = "^\\-?([1-9]\\d*|0)(\\.\\d{0,2})?$"
let predicte = NSPredicate(format:"SELF MATCHES %@", regex)
return predicte.evaluate(with: text)
}