成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Swift 2.0 下面向協議的MVVM架構實踐

移動開發 iOS
自從令人興奮的[《面向協議的編程方法》]在Swift的WWDC大會上發布以來。我對協議的使用考慮了很多。但是在現實中,我并沒有太多的顧及和使用這些功能。我還仍舊在消化到底面向協議的編程方法是什么,在代碼的哪些地方應該使用,而不是使用我目前使用的`go-to`編程方法。

自從令人興奮的[《面向協議的編程方法》]在Swift的WWDC大會上發布以來。我對協議的使用考慮了很多。但是在現實中,我并沒有太多的顧及和使用這些功能。我還仍舊在消化到底面向協議的編程方法是什么,在代碼的哪些地方應該使用,而不是使用我目前使用的`go-to`編程方法。

 

...所以,當我想起來要在哪里應用這些概念性的東西時,我非常激動,那就是MVVM !我已經在之前的博客中使用過MVVM架構,如果你想了解更多MVVM相關知識請參考[這里]。接下來我將講解,如何添加面向協議。

 

我將會使用一個簡單的例子。一個只有一個設置選項的設置頁面,把應用設置為Minion模式,當然你也可以擴展為多個設置選項。

[[149011]]

View Cell

一個極其普通的Cell,它包含一個Label和一個開關控件。你也可以在其他地方使用這個Cell,例如注冊頁面添加一個“記住我”的開關選項。所以,你應該保持這個頁面通用性。

一個復雜的配置

通常,我在cell中使用一個設置方法,來監聽所有對應用設置可能的變更,這看起來是這樣的:

  1. class SwitchWithTextTableViewCell: UITableViewCell { 
  2.  
  3. @IBOutlet private weak var label: UILabel! 
  4. @IBOutlet private weak var switchToggle: UISwitch! 
  5.  
  6. typealias onSwitchToggleHandlerType = (switchOn: Bool) -> Void 
  7. private var onSwitchToggleHandler: onSwitchToggleHandlerType? 
  8.  
  9. override func awakeFromNib() { 
  10. super.awakeFromNib() 
  11.  
  12. func configure(withTitle title: String, 
  13. switchOn: Bool, 
  14. onSwitchToggleHandler: onSwitchToggleHandlerType? = nil) 
  15. label.text = title 
  16. switchToggle.on = switchOn 
  17.  
  18. self.onSwitchToggleHandler = onSwitchToggleHandler 
  19.  
  20. @IBAction func onSwitchToggle(sender: UISwitch) { 
  21. onSwitchToggleHandler?(switchOn: sender.on) 

通過 Swift 的默認參數,可以添加其他的設置選項到這個設置方法,而不必改變代碼中的其他地方,使用起來非常方便。例如,當設計師說開關按鈕的顏色需應該各不相同,這時候我就可以添加一個默認參數。

  1. func configure(withTitle title: String, 
  2. switchOn: Bool, 
  3. switchColor: UIColor = .purpleColor(), 
  4. onSwitchToggleHandler: onSwitchToggleHandlerType? = nil) 
  5. label.text = title 
  6. switchToggle.on = switchOn 
  7. // color option added! 
  8. switchToggle.onTintColor = switchColor 
  9.  
  10. self.onSwitchToggleHandler = onSwitchToggleHandler 

雖然在這種情況下看起來并不是什么大問題,但是隨著時間的增加,事實上這個方法將會變得非常冗長、復雜!是時候由面向協議的編程方法登場了。

面向協議的編程方法

  1. protocol SwitchWithTextCellProtocol { 
  2. var title: String { get } 
  3. var switchOn: Bool { get } 
  4.  
  5. func onSwitchTogleOn(on: Bool) 
  6.  
  7. class SwitchWithTextTableViewCell: UITableViewCell { 
  8.  
  9. @IBOutlet private weak var label: UILabel! 
  10. @IBOutlet private weak var switchToggle: UISwitch! 
  11.  
  12. private var delegate: SwitchWithTextCellProtocol? 
  13.  
  14. override func awakeFromNib() { 
  15. super.awakeFromNib() 
  16.  
  17. func configure(withDelegate delegate: SwitchWithTextCellProtocol) { 
  18. self.delegate = delegate 
  19.  
  20. label.text = delegate.title 
  21. switchToggle.on = delegate.switchOn 
  22.  
  23. @IBAction func onSwitchToggle(sender: UISwitch) { 
  24. delegate?.onSwitchTogleOn(sender.on) 

當設計師說需要改變開關控件顏色的時候會發生什么?以下代碼可以展現協議擴展的奇妙之處。

 

 

  1. extension SwitchWithTextCellProtocol { 
  2.  
  3. // set the default color here! 
  4. func switchColor() -> UIColor { 
  5. return .purpleColor() 
  6.  
  7. class SwitchWithTextTableViewCell: UITableViewCell { 
  8.  
  9. // truncated, see above 
  10.  
  11. func configure(withDelegate delegate: SwitchWithTextCellProtocol) { 
  12. self.delegate = delegate 
  13.  
  14. label.text = delegate.title 
  15. switchToggle.on = delegate.switchOn 
  16. // color option added! 
  17. switchToggle.onTintColor = delegate.switchColor() 

在以上代碼中協議的擴展實現了默認的switchColor選項,所以,任何已經實現了這個協議或者并不關心設置開關顏色的人,不用關注這個擴展。只有一個具有不同顏色的新的開關控件可以實現。

ViewModel

所以現在剩下的事情將會非常簡單。我將會為MinionMode的設置cell寫一個ViewModel。

  1. import UIKit 
  2.  
  3. struct MinionModeViewModel: SwitchWithTextCellProtocol { 
  4. var title = "Minion Mode!!!" 
  5. var switchOn = true 
  6.  
  7. func onSwitchTogleOn(on: Bool) { 
  8. if on { 
  9. print("The Minions are here to stay!"
  10. else { 
  11. print("The Minions went out to play!"
  12.  
  13. func switchColor() -> UIColor { 
  14. return .yellowColor() 
  15.  
  16. ViewController 

 

***一步就是在ViewController中設置cell的時候將ViewModel傳給cell。

  1. import UIKit 
  2.  
  3. class SettingsViewController: UITableViewController { 
  4.  
  5. enum Setting: Int { 
  6. case MinionMode 
  7. // other settings here 
  8.  
  9. override func viewDidLoad() { 
  10. super.viewDidLoad() 
  11.  
  12. // MARK: - Table view data source 
  13.  
  14. override func tableView(tableView: UITableView, 
  15. numberOfRowsInSection section: Int) -> Int 
  16. return 1 
  17.  
  18. override func tableView(tableView: UITableView, 
  19. cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell 
  20. if let setting = Setting(rawValue: indexPath.row) { 
  21. switch setting { 
  22. case .MinionMode: 
  23. let cell = tableView.dequeueReusableCellWithIdentifier("SwitchWithTextTableViewCell", forIndexPath: indexPath) as! SwitchWithTextTableViewCell 
  24.  
  25. // this is where the magic happens! 
  26. cell.configure(withDelegate: MinionModeViewModel()) 
  27. return cell 
  28.  
  29. return tableView.dequeueReusableCellWithIdentifier("defaultCell", forIndexPath: indexPath) 
  30.  

通過使用協議的擴展,是面向協議的編程方法有了很大的意義,并且我在尋找更多的使用場景。以上代碼的全部內容放在[github]上。

更新:將數據源和代理分開

在評論中,Marc Baldwin 建議分開cell的數據源和代理方法到兩個協議中,就像UITableView中的那樣。我很贊成這個意見,以下是我修改后的代碼。

View Cell

Cell將擁有兩個協議,并且任何一個協議都可以設置這個cell。

  1. import UIKit 
  2.  
  3. protocol SwitchWithTextCellDataSource { 
  4. var title: String { get } 
  5. var switchOn: Bool { get } 
  6.  
  7. protocol SwitchWithTextCellDelegate { 
  8. func onSwitchTogleOn(on: Bool) 
  9.  
  10. var switchColor: UIColor { get } 
  11. var textColor: UIColor { get } 
  12. var font: UIFont { get } 
  13.  
  14. extension SwitchWithTextCellDelegate { 
  15.  
  16. var switchColor: UIColor { 
  17. return .purpleColor() 
  18.  
  19. var textColor: UIColor { 
  20. return .blackColor() 
  21.  
  22. var font: UIFont { 
  23. return .systemFontOfSize(17
  24.  
  25. class SwitchWithTextTableViewCell: UITableViewCell { 
  26.  
  27. @IBOutlet private weak var label: UILabel! 
  28. @IBOutlet private weak var switchToggle: UISwitch! 
  29.  
  30. private var dataSource: SwitchWithTextCellDataSource? 
  31. private var delegate: SwitchWithTextCellDelegate? 
  32.  
  33. override func awakeFromNib() { 
  34. super.awakeFromNib() 
  35.  
  36. func configure(withDataSource dataSource: SwitchWithTextCellDataSource, delegate: SwitchWithTextCellDelegate?) { 
  37. self.dataSource = dataSource 
  38. self.delegate = delegate 
  39.  
  40. label.text = dataSource.title 
  41. switchToggle.on = dataSource.switchOn 
  42. // color option added! 
  43. switchToggle.onTintColor = delegate?.switchColor 
  44.  
  45. @IBAction func onSwitchToggle(sender: UISwitch) { 
  46. delegate?.onSwitchTogleOn(sender.on) 

ViewModel

你現在可以在擴展里把數據源和delegate邏輯分開了:

  1. import UIKit 
  2.  
  3. struct MinionModeViewModel: SwitchWithTextCellDataSource { 
  4. var title = "Minion Mode!!!" 
  5. var switchOn = true 
  6.  
  7. extension MinionModeViewModel: SwitchWithTextCellDelegate { 
  8.  
  9. func onSwitchTogleOn(on: Bool) { 
  10. if on { 
  11. print("The Minions are here to stay!"
  12. else { 
  13. print("The Minions went out to play!"
  14.  
  15. var switchColor: UIColor { 
  16. return .yellowColor() 

ViewController

這一部分是我不十分確定,ViewController不能傳遞ViewModel兩次:

 

 

 

  1. override func tableView(tableView: UITableView, 
  2. cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell 
  3. if let setting = Setting(rawValue: indexPath.row) { 
  4. switch setting { 
  5. case .MinionMode: 
  6. let cell = tableView.dequeueReusableCellWithIdentifier("SwitchWithTextTableViewCell", forIndexPath: indexPath) as! SwitchWithTextTableViewCell 
  7.  
  8. // this is where the magic happens! 
  9. let viewModel = MinionModeViewModel() 
  10. cell.configure(withDataSource: viewModel, delegate: viewModel) 
  11. return cell 
  12.  
  13. return tableView.dequeueReusableCellWithIdentifier("defaultCell", forIndexPath: indexPath) 

代碼已經上傳[GitHub]

責任編輯:chenqingxiang 來源: CocoaChina
相關推薦

2015-08-04 08:56:14

swift子類

2018-05-10 13:45:15

Swift網絡層協議

2018-07-23 15:55:28

協議自定義viewSwift

2022-04-29 13:43:00

谷歌SWIFT參考架構

2022-07-30 23:41:53

面向過程面向對象面向協議編程

2015-08-14 11:37:37

Swift語言中文版

2010-07-09 11:12:09

UDP協議

2021-08-02 06:49:46

OIDC認證協議

2019-02-21 08:30:00

邊緣計算物聯網5G

2010-07-28 09:18:03

Flex2.0

2015-01-29 09:52:43

Swift 開源蘋果

2015-06-23 15:48:41

Swift 2.0iOS9

2016-12-12 15:22:41

編程

2024-04-28 10:22:08

.NETMVVM應用工具包

2009-07-24 13:54:39

MVVM模式

2021-06-04 09:01:27

Cocoa 協議編程 Swift

2021-06-03 08:55:58

面向協議編程

2018-05-23 16:20:30

IoT協議思考

2017-07-17 15:19:10

MVVM模式iOS開發MVP

2022-04-01 10:27:04

面向對象串口協議代碼
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 精品免费国产一区二区三区四区 | 亚洲综合资源 | 中文字幕人成乱码在线观看 | 国产精品久久久久国产a级 欧美日本韩国一区二区 | 在线观看av不卡 | 四虎影| 盗摄精品av一区二区三区 | 日韩欧美在线免费 | 国内精品视频在线观看 | 中文字幕第100页 | 亚洲h视频| 男女性毛片 | 最新国产精品 | 啪一啪| 天天操天天干天天透 | 亚洲伊人久久综合 | 欧美高清性xxxxhdvideosex | 99九九久久 | 欧美1区2区 | 一区二区三区视频在线观看 | 中文字幕视频在线 | 国产成人精品免费 | 免费久久精品视频 | 亚洲首页 | 国产精品一区二区在线 | 黄色大片在线播放 | 天堂视频一区 | 深爱激情综合 | 国产成人网| 范冰冰一级做a爰片久久毛片 | 日韩中文字幕在线视频 | 国产成人精品网站 | 精品不卡| 在线免费av电影 | 精品欧美一区二区三区久久久 | 男人的天堂在线视频 | 武道仙尊动漫在线观看 | 中文字幕一区在线观看视频 | 免费国产一区二区 | 黄色毛片在线观看 | 亚洲综合日韩精品欧美综合区 |