1. The 6 Swift Extensions I Use in Every iOS Project

每当我开始一个新的iOS Swift项目,我做的第一件事是导入我的实用程序和扩展文件。它们帮助我提高编程效率。让我们来看看我最喜欢和最基本的六个扩展。


1.1. 1. Dropping Shadow Under UIView

当实现现代设计时,在UIView下放置阴影是经常需要的。我不用为每个视图编写多行代码,而是使用了一个扩展:

extension UIView {
    func dropShadow() {
        self.layer.shadowColor = UIColor.gray.cgColor 
        self.layer.shadowOpacity = 0.3
        self.layer.shadowOffset = CGSize(width: 2, height: 4)
        self.layer.shadowRadius = 5
    }
}

当然,每个项目都可能需要对阴影风格做一些微小的改变,但可以在中心位置进行改变。

1.2. 2. Presenting a ViewController From Everywhere

在处理应用程序时,经常需要动态地更改ViewController流。你可以使用UIViewController的扩展,而不是编写函数并选择模态显示样式。如果你不想每次都打开Settings作为模态,你可以声明一次并使用viewController.openSettings()函数!只需一行代码,您就完成了!

extension UIViewController {
    func openMain() {
        if let viewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(identifier: "MainViewController") as? MainViewController {
          viewController.modalPresentationStyle = .fullScreen
          self.present(viewController, animated: true, completion: nil)
     }
}
//Use like this:
someViewController.openMain()

1.3. 3. Making Localization Easier

Swift的Localization可能非常难看——尤其是当你试图将多个单词连接成一个句子时

let string = NSLocalizedString("Hello", comment: "") + " " + NSLocalizedString("World", comment: "")

这就是为什么我使用我的扩展字符串来简化这个过程:

let string = "Hello".localized + " " + "World".localized

扩展是超级简单的,看起来像这样:

extension String {
    var localized: String {
        return NSLocalizedString(self, comment: "")
    }
}

1.4. 4. Writing Async Code Block With Delay in 3 Lines of Code

编写异步函数和队列可能会很难看。让我分享一个扩展,在不到三行代码以简化运行一个异步后台任务与延迟完成处理程序:

extension DispatchQueue {
    static func background(delay: Double = 0.0, background: (()->Void)? = nil, completion: (() -> Void)? = nil) {
        DispatchQueue.main.async {
            background?()
            if let completion = completion {
                DispatchQueue.main.asyncAfter(deadline: .now() + delay, execute: {
                    completion()
                })
            }
        }
    }
}

这使得编写带有延迟的两部分异步代码块就像这样简单:

DispatchQueue.background(delay: 1.0, background: {
    print("First")
}, completion: {
    print("Run async after 1 second")
})

1.5. 5. Shaking a View

在使用用户输入验证时,您经常希望通过晃动视图来给出不正确的用户输入反馈。让我们为这种抖动行为创建一个扩展,这样我们就不必再编写另一个了晃动代码块:

func shake() {
    let shake = CABasicAnimation(keyPath: "position")
    shake.duration = 0.05
    shake.repeatCount = 2
    shake.autoreverses = true
    let fromPoint = CGPoint(x: center.x - 5, y: center.y)
    let fromValue = NSValue(cgPoint: fromPoint)
    let toPoint = CGPoint(x: center.x + 5, y: center.y)
    let toValue = NSValue(cgPoint: toPoint)
    shake.fromValue = fromValue
    shake.toValue = toValue
    layer.add(shake, forKey: "position")
}
//Use like this: 
someView.shake()

就这么简单!

1.6. 6. Rounding Double to a Specific Number of Places as String

另一个经常需要的扩展是将Double或Float四舍五入到特定数量的位置。通常,我必须计算并表示一个值,所以我需要它作为一个格式化的字符串(例如,1.42432四舍五入到两位就是1.42)。但是,当返回一个四舍五入的双位数时,1.40432将返回1.4而不是1.40。让我们看看扩展来获得一个漂亮的格式化字符串:

extension Double {
    func rounded(toPlaces places:Int) -> String {
        let divisor = pow(10.0, Double(places))
        var returnValue = "\((self * divisor).rounded() / divisor)"
        if(returnValue.split(separator: ".")[1].count == 1 && places > 1) {
            returnValue += "0"
        }
        return returnValue
    }
}
//Use like this: 
1.403843.rounded(toPlaces: 2) >> "1.40"

1.7. Conclusion

我希望你能在未来的努力中运用扩展的力量。