足够的MVC,适合初学者及更多

小介绍


全部404!大多数iOS开发人员不了解如何使用Apple-MVC。因此,存在不合理的批评,小型项目试图在不适合此目的的体系结构上进行编写,因此ViewController变得庞大,难以读取等。

在本文中,我将展示一种简单的方法,使自己变得轻松,让自己的生活变得更轻松。3个月后,这个人(当然是所有ViewController)都对项目进行了研究。适合谁?对于初学者或具有小型项目的开发人员,这些项目的最终结构是干净美观的。

每个人都在哪里淹死?


首先,让我们看一下每个人最喜欢的标准漂亮MVC。

图片

现在,让我们看看大多数人正在实施什么。

图片

凉?没有!因此,我们不会这样做,但是会实现第一个选项。

打造美丽的结构


我们创建通常的Single View App。我将Swift放在语言选择字段中,不包括任何其他内容:测试和CoreDat都没有。

我将以创建商店橱窗的示例进行演示,因为 我们需要影响MVC的所有部分,我们将从控制器中的模型中获取数据以进行分发并在视图中显示。

好的,有一个任务,有一个空项目。现在进入该项目,我将把所有内容分发到文件夹中并创建空文件,以便您了解它们将来的位置。还附有情节提要结构,以免将来浪费时间。我写了ProductCell,不要忘了在单元格上指定重用ID。

图片

帅吗 当然很漂亮。我们继续 ...

一些魔术般的迅捷


现在我们可以开始执行了。让我们从一个简单的视图开始。我们需要创建所有IBOutlet以及视图的设置。

//    ,   view     UIKit. 
import UIKit

class ShopView: UIView{
    //       storyboard. 
    @IBOutlet weak var tableView: UITableView!
    //      view. 
    func configure(){
        //     ,    ,      ...
        tableView.estimatedRowHeight = 50
        tableView.rowHeight = 100
    }
}

这就是我们视图的外观,在configure()函数中,我只是设置了设置,但是视图需要用于动画以及更改按钮标题的标题等。但是为什么那么少利用这个优势呢?因此,例如,我在controller'e中使用了动画:view.hideBorders(自身),仅此而已,view已经可以制作出精美的动画。

//    view  . 
func hideBorders(view: UIView){
    UIView.animate(withDuration: 0.3,
                   delay: 0,
                   options: .curveEaseInOut,
                   animations: {
           //         constraint. 
           self.createViewHeighConstraint.constant = view.bounds.height * 0.6
           //   ,   ,    . 
           self.editButton.layer.cornerRadius = 20
           self.postView.layer.shadowOpacity = 0
           self.postView.layer.cornerRadius = 0
           view.layoutIfNeeded()
    }, completion: nil)
}

火!但是回到我们的项目,是时候实施模型了。因此,我们将拥有货物,可能还有他们的团体。

//   ,   model       View.
// ,    ,       Foundation.
import Foundation
//      ,  . 
public struct Product {
  public let name: String
}
//    ,      ,   . 
public struct ProductGroup {
  public let products: [Product]
  public let title: String
}
//  swift   ()    extension. 
extension ProductGroup{
    //  ,     ( Product). 
    public static func vegetables() -> ProductGroup{
       //   .
        let products = [
            Product(name: ""),
            Product(name: ""),
            Product(name: "")
        ]
        //      "". 
        return ProductGroup(products: products, title: "")
    }
}

太好了,我们的模型已经准备好了,它仍然可以组装控制器,让我们越过吧。首先,我们需要创建两个主要实体,模型和视图。然后,我将在私有扩展中删除控制器设置,并将数据从模型传输到我们的表中。

//  controller'e      ,      UIKit.
import UIKit

class ShopController: UIViewController {
    //  -     .
    private var shopModel = ProductGroup.vegetables()
    
    //     (       )
    private var shopView: ShopView! {
        guard isViewLoaded else { return nil }
        return (view as! ShopView)
    }
    //      view,         controller'a  view  . 
    override func viewDidLoad() {
        super.viewDidLoad()
        //    view      .
        configure()
    }
}

private extension ShopController{
    //          .
    func configure(){
        shopView.tableView.delegate = self
        shopView.tableView.dataSource = self
    }
}

//      . 
extension ShopController: UITableViewDataSource, UITableViewDelegate{

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        //  -   -   
        return shopModel.products.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        //   ,   reuse Id ,      .
        let cell = tableView.dequeueReusableCell(withIdentifier: "ProductCell")
        //    label  cell     . 
        cell?.textLabel?.text = shopModel.products[indexPath.row].name
        return cell!
    }
}

他答应解释一下视图,不是吗?)我们的shopView是一个计算属性。在这里,我们检查isViewLoaded,以免在访问此属性时导致视图意外加载。如果视图已经加载,我们将其强制转换为ShopView。

就是这样,我们的MVC准备好了!仍然需要按Command + R并看到三个单元格。

到底我们有什么?


  • 简单明了的架构
  • 均匀加载模型,视图,控制器
  • 易于重用的视图
  • 易于扩展我们的项目

结论


我真的希望本文能帮助初学者保持项目整洁,不要迷失在代码中,而将精力集中在任务上。所有好的和更少的错误^^

All Articles