Skip to content

Instantly share code, notes, and snippets.

View monsoir's full-sized avatar

Monsoir monsoir

View GitHub Profile
@monsoir
monsoir / String+Regex.swift
Last active December 24, 2019 05:21
String regex
extension String {
/// 是否为合法邮箱地址
var isValidEmail: Bool {
// https://stackoverflow.com/a/41782027/5211544
let firstPart = "[A-Z0-9a-z]([A-Z0-9a-z._%+-]{0,30}[A-Z0-9a-z])?"
let serverPart = "([A-Z0-9a-z]([A-Z0-9a-z-]{0,30}[A-Z0-9a-z])?\\.){1,5}"
let regex = "\(firstPart)@\(serverPart)[A-Za-z]{2,8}"
let predicate = NSPredicate(format: "SELF MATCHES %@", regex)
return predicate.evaluate(with: self)
@monsoir
monsoir / Shortcuts.swift
Last active December 24, 2019 05:22
Shortcuts for frequently used objects or functions
import Foundation
import UserNotifications
/// 系统文件夹路径
enum SystemDirectories {
case document
case caches
case library
case tmp
@monsoir
monsoir / CLLocationManager+extension.swift
Created November 12, 2019 17:23
CLLocationManager extensions
extension CLLocationManager {
/// 检测是否可以请求「总是使用」的地理位置权限
/// - 对于「总是使用」的地理位置权限,只有当当前权限为 `.notDetermined` 或 `.authorizedWhenInUse` 才可以申请
static var canRequestAlways: Bool {
let status = CLLocationManager.authorizationStatus()
let result = [CLAuthorizationStatus.authorizedWhenInUse,
CLAuthorizationStatus.notDetermined].contains(status)
return result
}
@monsoir
monsoir / UIButton+Extension.swift
Last active November 30, 2019 19:30
UIButton extensions
extension UIButton {
/// 在 button 不闪烁的情况下设置按钮
func setTitleWithoutFlashing(_ title: String, for state: UIControl.State) {
UIView.setAnimationsEnabled(false)
setTitle(title, for: .normal)
layoutIfNeeded()
UIView.setAnimationsEnabled(true)
}
@monsoir
monsoir / runtime-in-swift.swift
Created October 16, 2019 17:19
Runtime invoke in swift
import ObjectiveC
// 获取私有类
let theClass = NSClassFromString("MKLocationManager")
// 获取方法的 selector, 注意,这里是类方法
let sharedInstanceSelector = NSSelectorFromString("sharedLocationManager")
// 调用类方法并获取结果
let sharedInstance = (theClass as! NSObjectProtocol).perform(sharedInstanceSelector)?.takeUnretainedValue()
extension CLLocationCoordinate2D {
/// 地球坐标 WGC-84 转为为火星坐标 GCJ-02(限中国境内)
/// - CLLocationManager 获取的是地球坐标,但地图上显示的需要火星坐标
/// - 通过 CLLocationManager 获取到中国境内地理坐标,若需要在地图上显示,则需要转换为火星坐标
var wgc84ToGCJ02: CLLocationCoordinate2D {
if isLocatedInChina {
let a = 6378245.0
let ee = 0.00669342162296594323
var adjustedLatitude = transformedLatitude
@monsoir
monsoir / CompatibleValue.swift
Created October 11, 2019 17:46
自定义命名空间
// 参考 Kingfisher 对 `kf` 的实现与使用
// 可以创建一个命名空间,来扩写类型的 extension, 用于特定环境下使用,避免污染全局
// 使用方法:
// 1. 根据数据类型,声明目标类型遵从 `Compatible` 或 `CompatibleValue` 协议,只需声明一次
// - 对于 Foundation 的类型,推荐声明在本文件下方
// - 对于自定义类型,怎么方便怎么来吧
// 2. 对 `Compatible` 或 `CompatibleValue` 协议提供一个默认实现,并在其中定义一个属性,作为命名空间
// 3. 对 `Wrapper` 进行扩展,同时需要约束好类型,在其中添加对目标类型的扩展方法
// 针对对象类型, object
@monsoir
monsoir / UITableView+Extension.swift
Last active December 24, 2019 05:19
UITableView extensions
extension UITableView {
/// 使用自动布局时,动态设置 table view 的 tableHeaderView 的高度
/// - https://stackoverflow.com/a/28102157/5211544
/// - Parameter headerView: 即将设置的 tableHeaderView
func setAndLayoutTableHeaderView(headerView: UIView) {
tableHeaderView = headerView
headerView.setNeedsLayout()
headerView.layoutIfNeeded()
headerView.frame.size = headerView.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize)
@monsoir
monsoir / HorizontalCenterImageLabelView.swift
Last active September 10, 2019 15:50
Horizontally centered view with image view and label inside
// https://stackoverflow.com/a/41195368/5211544
class HorizontalCenterImageLabelView: UIView {
private var imageSize = CGSize(width: 30, height: 30)
override init(frame: CGRect) {
super.init(frame: frame)
setupSubviews()
}
@monsoir
monsoir / AttributedString+extension.swift
Created September 10, 2019 15:47
NSAttributedString extension
extension NSAttributedString {
// https://stackoverflow.com/a/36319475/5211544
// 缺点:富文本字符串开头可能会有一个空格的距离大小
static func attributedString(
with leadingImage: UIImage?,
offsetY: CGFloat,
imageDesiredWidth: CGFloat,
content: String,
attributes: [NSAttributedString.Key: Any] = [:]