![](/img/trans.png)
[英]How to properly implement protocols and delegates between different view controllers in Swift?
[英]How to setup protocols and delegates on a static table view?
我正在嘗試設置一個 static 表視圖,該表視圖與另一個帶有列表的表視圖有一個segue。 然后用戶從列表中選擇一個項目,並更新主(靜態)表視圖。 我有設置代表,但我認為我遺漏了一些東西。 從列表中選擇一個項目時,它會引發“強制展開可選時意外找到'nil'”的異常。 看來可選的是協議本身。
主表視圖文件
//
// AddAssetTableViewController.swift
// ItemizePro
//
// Created by Tyler Wasick on 5/27/20.
// Copyright © 2020 Tyler Wasick. All rights reserved.
//
import UIKit
class AddAssetTableViewController: UITableViewController {
// TODO: Add image IBOutlet
@IBOutlet weak var nameTextField: UITextField!
@IBOutlet weak var descriptionTextField: UITextField!
@IBOutlet weak var datePurchasedTextField: UITextField!
@IBOutlet weak var manufactureTextField: UITextField!
@IBOutlet weak var modelTextField: UITextField!
@IBOutlet weak var serialNumberTextField: UITextField!
@IBOutlet weak var costTextField: UITextField!
@IBOutlet weak var roomTextField: UITextField!
@IBOutlet weak var notesTextView: UITextView!
@IBOutlet weak var receiptTextField: UITextField!
@IBOutlet weak var addUIButton: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
// Uncomment the following line to preserve selection between presentations
// self.clearsSelectionOnViewWillAppear = false
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem
}
// MARK: - Table view data source
/*
override func numberOfSections(in tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 0
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return 0
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "imageCell", for: indexPath)
// Configure the cell...
return cell
}
*/
/*
// Override to support conditional editing of the table view.
override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
// Return false if you do not want the specified item to be editable.
return true
}
*/
/*
// Override to support editing the table view.
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
// Delete the row from the data source
tableView.deleteRows(at: [indexPath], with: .fade)
} else if editingStyle == .insert {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
*/
/*
// Override to support rearranging the table view.
override func tableView(_ tableView: UITableView, moveRowAt fromIndexPath: IndexPath, to: IndexPath) {
}
*/
/*
// Override to support conditional rearranging of the table view.
override func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
// Return false if you do not want the item to be re-orderable.
return true
}
*/
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destination.
// Pass the selected object to the new view controller.
}
*/
// MARK: - Functions
// MARK: - IBAction outlets
@IBAction func addButtonTapped(_ sender: UIButton) {
}
}
extension AddAssetTableViewController : RoomDelegate {
func tappedOnRoom(room: String) {
roomTextField.text = room
}
}
帶有項目(房間)列表到 select 的表視圖,它被傳遞回第一個表視圖 controller
//
// RoomListViewController.swift
// ItemizePro
//
// Created by Tyler Wasick on 5/25/20.
// Copyright © 2020 Tyler Wasick. All rights reserved.
//
import UIKit
protocol RoomDelegate {
func tappedOnRoom(room: String)
}
class RoomListViewController : UIViewController {
var selectionDelegate : RoomDelegate!
@IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
// Configure table view
tableView.dataSource = self
tableView.delegate = self
}
// When user taps on a room, it returns the room to the delagate and dismisses
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
// Assign the selection to 'selectedRoom'
let selectedRoom = UserSettings.roomList[indexPath.row]
// Return the room to the delegate
selectionDelegate.tappedOnRoom(room: selectedRoom)
}
}
extension RoomListViewController: UITableViewDataSource, UITableViewDelegate {
// UITableViewDelegate
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return UserSettings.roomList.count
}
// UITableViewDataSource
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// Setup cell
let cell = tableView.dequeueReusableCell(withIdentifier: "RoomListCell", for: indexPath) as! RoomListView
// Set the details for the cell
let room = UserSettings.roomList[indexPath.row]
cell.setRoomCell(room)
// Return the cell
return cell
}
}
崩潰是由於您使用了未為其提供值的強制解包委托。
使您的Protocol
class 綁定:這將允許您創建對您的委托的弱引用
protocol RoomDelegate: class {
func tappedOnRoom(room: String)
}
使您的委托變得弱且可選:
weak var selectionDelegate: RoomDelegate?
在 AddAssetTableViewController 的prepareForSegue
方法中設置委托。 這是您缺少的代碼。
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let vc = segue.destination as? RoomListViewController {
vc.selectionDelegate = self
}
}
調用委托時使用可選鏈
selectionDelegate?.tappedOnRoom(room: selectedRoom)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.