Small introduction
All 404! Most iOS developers do not understand how to work with Apple-MVC. Because of which there is unreasonable criticism, small projects try to write on architectures that are not intended for this, ViewControllers become huge, unreadable, and so on.In this article I will show a simple way to make life easier for myself, life for myself, who has looked into the project after 3 months, and, of course, for all ViewControllers. Who is it suitable for? For beginners or developers with small projects that end up with a clean and beautiful structure.Where does everyone drown?
To get started, let's look at everyone's favorite standard beautiful MVC.
Now let's look at what is being implemented by the majority.
Cool? No! Therefore, we will not do this, but will implement the first option.Making the structure of beauty
We create the usual Single View App. I put Swift in the language selection field, not including anything else: neither tests, nor CoreDat's.I will show by the example of creating a shop window, because we need to affect all parts of MVC, we will take the data from model to controller to distribute and show in view.Okay, there is a task, there is an empty project. Now diving into the project, I will distribute everything into folders and create empty files so that you understand where they should lie in the future. Also attached a storyboard structure, so as not to waste time in the future. Do not forget to specify reuse id at cell, I wrote ProductCell.
Handsomely? Of course it's beautiful. We continue ...Some magic swift
Now we can begin implementation. Let's start with a simple view. We need to create all IBOutlets, and the settings for our view.
import UIKit
class ShopView: UIView{
@IBOutlet weak var tableView: UITableView!
func configure(){
tableView.estimatedRowHeight = 50
tableView.rowHeight = 100
}
}
This is how our view will look like, in the configure () function, I just set the settings, but view needs to be used for animations, and for changing the title of the buttonβs title, etc. ... So primitively say? But why then use this advantage so little ?! So, for example, I use animations in the controller'e: view.hideBorders (self) and that's it, and view will already make a beautiful animation.
func hideBorders(view: UIView){
UIView.animate(withDuration: 0.3,
delay: 0,
options: .curveEaseInOut,
animations: {
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)
}
Fire! But back to our project, time to implement model. And so we will have goods, and may their groups be.
import Foundation
public struct Product {
public let name: String
}
public struct ProductGroup {
public let products: [Product]
public let title: String
}
extension ProductGroup{
public static func vegetables() -> ProductGroup{
let products = [
Product(name: ""),
Product(name: ""),
Product(name: "")
]
return ProductGroup(products: products, title: "")
}
}
Great, our model is ready, it remains to assemble the controller, let's transgress. First of all, we will need to create two of our main entities, model and view. Then I will take out the controller settings in the private extension and transfer the data from model to our table.
import UIKit
class ShopController: UIViewController {
private var shopModel = ProductGroup.vegetables()
private var shopView: ShopView! {
guard isViewLoaded else { return nil }
return (view as! ShopView)
}
override func viewDidLoad() {
super.viewDidLoad()
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 {
let cell = tableView.dequeueReusableCell(withIdentifier: "ProductCell")
cell?.textLabel?.text = shopModel.products[indexPath.row].name
return cell!
}
}
He promised to explain about view, didnβt forget?) Our shopView is a calculated property. Here we check isViewLoaded so as not to cause the view to load unintentionally when accessing this property. If the view is already loaded, we force it to be converted to ShopView.That's it, our mvc is ready! It remains to press command + R and see three cells.What do we have in the end?
- Simple, clear architecture
- Uniform load on model, view, controller
- Easy reuse view
- Easy extensibility of our project
Conclusion
I really hope that this article will help beginners to keep their projects clean, not to get lost in the code, but to concentrate on tasks. All good and less bugs ^^