私はModel-View-ControllerデザインパターンをCocoaアプリケーション(Swiftで書かれています)に適用したいと思います。有名人の例を想定してみましょう:アプリケーションはテキストフィールドと追加ボタンを表示する必要があります。人物の名前をテキストフィールドに入力し、追加ボタンをクリックすることで配列に格納することができます(配列の内容はテーブルビューで表示されます)。ここで、ストーリーボードにはすべてのビュー関連のものが含まれ、Personクラス(変数名付き)はModelクラスを構成します。ビューコントローラは、データの表示(たとえば、テーブルビューのデリゲートとデータソース)を受け取り、その名前を抽出してどこかに配置するIBActionを持っています。しかし、私は実際にどこの名前を保持する配列を配置するか分からない。ビューコントローラーでもそれを使用できますか(これは最も簡単な解決策です)。それとも別の場所?もし、アプリケーションが異なるビュー(異なるビューコントローラを持つ)に複数のデータ保持構造を持つようになると、ますます複雑になるでしょうか? UITableViewControllerまたはのUIViewControllerからMVC:データを保存する場所は?
答えて
1)のViewController():必要ならば入力セル又は個人の細胞を含む:
class ViewController: UITableViewController, UITextFieldDelegate {
var model = ViewModel()
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "personCell")
let nib = UINib(nibName: "InputTableViewCell", bundle: nil)
tableView.register(nib, forCellReuseIdentifier: "inputCell")
// Request or load the data into model
// requestData() & tableView.reloadData() here
}
// MARK: - UITableViewDataSource
override func numberOfSections(in tableView: UITableView) -> Int {
return 2
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return section == 0 ? 1 : model.persons?.count ?? 0
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.section == 0 {
let cell = tableView.dequeueReusableCell(withIdentifier: "inputCell", for: indexPath)
if let inputCell = cell as? InputTableViewCell {
inputCell.textField.text = model.input
inputCell.textField.delegate = self
inputCell.textField.addTarget(self, action: #selector(textFieldEditing(_:)), for: .editingChanged)
inputCell.buttonAdd.addTarget(self, action: #selector(buttonAddTapped(_:)), for: .touchUpInside)
}
return cell
} else {
let cell = tableView.dequeueReusableCell(withIdentifier: "personCell", for: indexPath)
let person = model.persons?[indexPath.row]
cell.textLabel?.text = person?.name
return cell
}
}
// MARK: - Event Handler
func textFieldEditing(_ sender: UITextField) {
model.input = sender.text
}
func buttonAddTapped(_ sender: UIButton) {
if let name = model.input, name.characters.count > 0 {
let person = Person()
person.name = name
model.addPerson(person)
model.input = nil
// Also save data to CoreData if you want to retrieve them again later
// saveData()
}
tableView.reloadData()
}
}
2)セルを定義します。新しいクラスを作成するときは、「XIBファイルも作成する」もチェックして接続し、UIを作成します。モデルの定義)
class ViewModel {
var persons: [Person]?
var input: String?
func addPerson(_ person: Person) {
if persons == nil { persons = [] }
persons?.append(person)
}
}
4:
class InputTableViewCell: UITableViewCell {
@IBOutlet weak var textField: UITextField!
@IBOutlet weak var buttonAdd: UIButton!
}
3)ビューモデルを定義
class Person {
var name: String?
}
モデル:は
あなたはデータベースをしたい、またはコアデータになります。
ITのいくつかのコーナーでは、mySQLデータベースまたはXMLファイルの後ろに「モデル」があると考えられているので、CDを分けています。ディスカッションのために何かを開いているように、CDには長所と短所があります。多くの人々は、実装後に物事を拡大する最大の弱点の1つを考えています。
異なるビュー(異なるビューコントローラ)で複数のデータを保持する構造でアプリケーションがますます複雑になる場合はどうなりますか?
これは私にとってはモデルにとって重要なことです。これは単純なSQL(またはリレーショナル)データベースを意味します。私がリレーショナルで何を意味するのかわからない場合は、それを見て、数日間それを勉強してください。 (ヒント:あなたがすでに "人格クラス"と話しているときにあなたはすでにそこにいます。あなたのクラス(名前、タイプ、プロパティ)に合わせて、あなたのクラスをデータベーステーブルに合わせてください。
しかし、スケーラビリティとティア(モデル、ビュー、コントローラ)を心に留めておいてください。スウィフトはプロパティを計算しました。「ヨーロッパに住んでいる人の数」などのクエリを実行する場合は、データをパイプクリーナー上に残して、より良いパフォーマンスを発揮しますが、「John Doeの誕生日までの日数」のようなものを表示したい場合は、コントローラー側の計算されたプロパティーまたは呼び出し可能な関数
あなたはまた、ローカルまたはクラウドを決定したいと思います。Facebookには明らかにデータベースがありますそれは雲の中にある。しかし、私のサードパーティのポッドキャストアプリ(曇りのないBTW)には、ある種のローカルデータベースがあります。
ビュー:
あなたはこの上の良いハンドルを持っているように見えます。 Xcodeは、ほとんどの場合、MVCに頼っています。 Interface Builderで完全に固執することができれば、あなたはすでにこれを持っています。
しかし、(私のような)一部のコーダーはそれを行うことができません。すべてのAppleが自動レイアウトの制約でうまくやっているので、iPad上のすべての向き(分割画面やスライドアウトが使用されていない場合を含む)が現在の通常のサイズと同じように、私のアプリケーションは、私のGLKViewの画面スペースを最大にするために、UISliderコントロールを下(縦)から右(横)に移動する必要があります。これは、少なくともいくつかのものをコーディングすることを意味します(オリエンテーションの変更とスーパービューの境界)。 IBは設計時にコードを処理できないため、すべてのサブビューをコードに移動してIBを削除することに決めました。私はIBを使うことができるXcode 8を期待していました。新しいIBの両方のもので遊んだ後も、それはまだ価値がないことに気が付きました - スーパービューの境界に基づいてアクティブ/非アクティブにするための制約配列が必要です。
短いストーリー:IBはうまく機能し、可能な限り使用してください。しかし、制限があることを覚えておき、必要に応じてビューレイヤのコードに入るのを恐れないでください。
コントローラー:
まず第一に、残ってすべては「コントローラ」で、あなたは「モデル」との事から、「ビュー」を削除した後ことに注意してください。
もちろんです。もちろん!ビューコントローラはビュー(およびサブビュー)にデータを表示する必要があります。また、ボタン押下スライダの変更など、ユーザからのアクションを処理する必要があります。しかし、データベースのデータを取得するのはどうですか?サードパーティのWebサービスから価格や税務情報を取得するのはどうでしょうか?またはあなたのために、UITableViewの人々(連絡先?)のリストを表示するのはどうですか?
あなたのすべてをあなたのビューコントローラに入れたら、おめでとうございます! UIViewController "cruft"について学習しました。私たちはこれをすべてやってきました.Xcode MVCのやり方を学ぶことのすべてです。それは科学の何か、そして何がうまくいくかを知る何かのアートです。 (それは主に経験ですが)
あなたのアプリが成長するにつれ、より多くのUIViewControllerがあるはずです。 Person、Countryなどのような他のクラスもあるでしょう。最終的に、さまざまなクラスの拡張を作成し、クラスのプロトコルを作成します。今すぐ、簡単な質問:これらのものをどのように整理しておきますか?別々のファイル、グループ、何?あなたは、フレームワークターゲットが最も効果的であることが分かります。
"コントローラ"組織をコーディングする前に、あなたの "モデル"を釘付けするよりも、もっと重要なことかもしれません。
- 1. 保存場所データは
- 2. /tomcatで永続データを保存する場所/方法は?
- 3. カスタムメタデータを保存する場所は?
- 4. MVC Webアプリ - データの有効性を保証する場所
- 5. ブラウザはオートフィルデータを保存/保存する場所
- 6. MVC - blittingデータを配置する場所
- 7. mousedownの場所を保存
- 8. ブラウザユーザーの認証データを保存する場所
- 9. ビッグXMLデータを保存するのに最適な場所
- 10. Eclipse RCPアプリケーションに「グローバル」データを保存する場所
- 11. スタティックアレイを目的の場所に保存する場所
- 12. Symfony2でサービスを保存する場所
- 13. ファイルを保存する場所
- 14. ファイルを保存する場所
- 15. Androidにアプリケーションデータを保存する場所
- 16. テーマのビューを保存する場所
- 17. ファシリティ設定を保存する場所
- 18. アクティベーションキーを保存する場所
- 19. アプリケーション設定を保存する場所
- 20. WPF NLogログを保存する場所
- 21. XMLファイルを保存する場所
- 22. M2Cryptoファイルを保存する場所
- 23. Googleマップに場所を保存する
- 24. Laravelがユーザーセッションを保存する場所
- 25. asp.net MVC 4 webappにユーザーがアップロードしたファイルを保存する場所は?
- 26. Windowsモバイルと保存場所
- 27. PrefPanes&Plist保存場所10.7
- 28. Portable Executableの保存場所
- 29. mvcプロジェクトにデータを保存
- 30. ApplicationDataは、onPauseでデータを保存する場所として安全ですか?
実際のプロジェクトでは、この配列をデータベース、ローカルまたはリモートデータベースに保存する必要があります。この場合、モデルの保存またはデータベースからの取得を担当するサービスを持つことができます。どのViewControllerもそのServiceClassを使用します。 –
私が正しく理解していれば、あなたは@bubuxuの答えを説明しますが、いくつかの保存/書き込み機能(ディスクまたはデータベースのいずれか)を使用して説明します。つまり、一部のビューコントローラがアクセスする必要があるときはいつでも、データをロード/保存する必要があります。処理に多くのデータがある場合は特に計算コストがかかりませんか? – DaPhil