面向协议编程

一、Views

  • 使用extension UIView { } 意图不明显
import UIKit

extension UIView {

    func shake() {
        let animation = CABasicAnimation(keyPath: "position")
        animation.duration = 0.05
        animation.repeatCount = 5
        animation.autoreverses = true
        animation.fromValue = NSValue(CGPoint: CGPointMake(self.center.x - 4.0, self.center.y))
        animation.toValue = NSValue(CGPoint: CGPointMake(self.center.x + 4.0, self.center.y))
        layer.addAnimation(animation, forKey: "position")
    }
}

class FoodImageView: UIImageView {
    // other customization here
}

class ActionButton: UIButton {
    // other customization here
}

class ViewController: UIViewController {
    @IBOutlet weak var foodImageView: FoodImageView!
    @IBOutlet weak var actionButton: ActionButton!

    @IBAction func onShakeButtonTap(sender: AnyObject) {
        foodImageView.shake()
        actionButton.shake()
    }
}
  • 使用协议
import UIKit

protocol Shakeable { }

extension Shakeable where Self: UIView {

     func shake() {
        let animation = CABasicAnimation(keyPath: "position")
        animation.duration = 0.05
        animation.repeatCount = 5
        animation.autoreverses = true
        animation.fromValue = NSValue(CGPoint: CGPointMake(self.center.x - 4.0, self.center.y))
        animation.toValue = NSValue(CGPoint: CGPointMake(self.center.x + 4.0, self.center.y))
        layer.addAnimation(animation, forKey: "position")
    }
}

class FoodImageView: UIImageView, Shakeable {

}

class ActionButton: UIButton, Shakeable {

}

class ViewController: UIViewController {
    @IBOutlet weak var foodImageView: FoodImageView!
    @IBOutlet weak var actionButton: ActionButton!

    @IBAction func onShakeButtonTap(sender: AnyObject) {
        foodImageView.shake()
        actionButton.shake()
    }
}

二、ViewControllers

  • 一般方法
override func viewDidLoad() {
    super.viewDidLoad()

    let foodCellNib = UINib(NibName: "FoodTableViewCell", bundle: nil)
    tableView.registerNib(foodCellNib,
                          forCellReuseIdentifier: "FoodTableViewCell")
}

let foodCellNib = UINib(NibName: String(FoodTableViewCell), bundle: nil)
tableView.registerNib(foodCellNib,
                      forCellReuseIdentifier: String(FoodTableViewCell))
  • 使用协议
protocol ReusableView: class {}

extension ReusableView where Self: UIView {

    static var reuseIdentifier: String {
        return String(self)
    }
}

extension UITableViewCell: ReusableView { }

protocol NibLoadableView: class { }

extension NibLoadableView where Self: UIView {

    static var NibName: String {
        return String(self)
    }
}

extension FoodTableViewCell: NibLoadableView { }

extension UITableView {

    func register(_: T.Type) {

        let Nib = UINib(NibName: T.NibName, bundle: nil)
        registerNib(Nib, forCellReuseIdentifier: T.reuseIdentifier)
    }
}

tableView.register(FoodTableViewCell)
  • 一般方法
guard let cell = tableView.dequeueReusableCellWithIdentifier(“FoodTableViewCell", forIndexPath: indexPath)
    as? FoodTableViewCell
    else {
      fatalError("Could not dequeue cell with identifier: FoodTableViewCell")
}
  • 使用协议
extension UITableView {

    func dequeueReusableCell(forIndexPath indexPath: NSIndexPath) -> T {
        guard let cell = dequeueReusableCellWithIdentifier(T.reuseIdentifier, forIndexPath: indexPath) as? T else {
            fatalError("Could not dequeue cell with identifier: \(T.reuseIdentifier)")
        }
        return cell
      }
}
let cell = tableView.dequeueReusableCell(forIndexPath: indexPath) as FoodTableViewCell
if indexPath.row == 0 {
    return tableView.dequeueReusableCell(forIndexPath: indexPath) as DesertTableViewCell
}
return tableView.dequeueReusableCell(forIndexPath: indexPath) as FoodTableViewCell

三、网络

enum Result {
    case Success(T)
    case Failure(ErrorType)
}

protocol Gettable {
    associatedtype T

    func get(completionHandler: Result -> Void)
}

struct FoodService: Gettable {

    func get(completionHandler: Result<[Food]> -> Void) {
        // make asynchronous API call
        // and return appropriate result
    }
}

override func viewDidLoad() {
    super.viewDidLoad()
    getFood(fromService: FoodService())
}

func getFood(fromService service: S) {
    service.get() { [weak self] result in

        switch result {
        case .Success(let food):
            self?.dataSource = food
        case .Failure(let error):
            self?.showError(error)
        }
    }
}

你可能感兴趣的:(面向协议编程)