我正在Xcode 9.3中为iOS构建一个房间预订应用程序。
这是基本布局:
第一个TableViewController
(TVC1):开始为空。按“ +”会弹出
第二个TableViewController
(TVC2)有很多字段要填写。
按下TVC2上的“完成”按钮后,我回到TVC1,现在它具有一个包含已插入详细信息的单元格(字幕样式)。
我现在想点击该单元格,然后回到TVC2来检查或修改数据。
我已经创建了序列,但是点击后会得到与按“ +”时得到的相同版本的TVC2,而不是填充的版本。
我究竟做错了什么?
这是我需要编辑的与TVC1相关的代码:
import UIKit
class RegistrationTableViewController: UITableViewController {
var registrations: [Registration] = []
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return registrations.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "RegistrationCell", for: indexPath)
let registration = registrations[indexPath.row]
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .short
cell.textLabel?.text = registration.firstName + " " + registration.lastName
cell.detailTextLabel?.text = dateFormatter.string(from: registration.checkInDate) + " - " + registration.roomType.name
return cell
}
@IBAction func unwindFromAddRegistration(unwindSegue: UIStoryboardSegue) {
guard let addRegistrationTableViewController = unwindSegue.source as? AddRegistrationTableViewController,
let registration = addRegistrationTableViewController.registration else { return }
registrations.append(registration)
tableView.reloadData()
}
// MARK: Challenge.
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "ViewReservationDetails" {
}
}
这是(TVC2)的代码,以便您拥有或多或少的所有可用应用程序。
import UIKit
class AddRegistrationTableViewController: UITableViewController, SelectRoomTypeTableViewControllerDelegate {
// MARK: Properties
let checkInDatePickerCellIndexPath = IndexPath(row: 1, section: 1)
let checkOutDatePickerCellIndexPath = IndexPath(row: 3, section: 1)
var isCheckInDatePickerShown: Bool = false {
didSet {
checkInDatePicker.isHidden = !isCheckInDatePickerShown
}
}
var isCheckOutDatePickerShown: Bool = false {
didSet {
checkOutDatePicker.isHidden = !isCheckOutDatePickerShown
}
}
var roomType: RoomType?
var registration: Registration? {
guard let roomType = roomType else { return nil }
let firstName = firstNameTextField.text ?? ""
let lastName = lastNameTextField.text ?? ""
let email = emailTextField.text ?? ""
let checkInDate = checkInDatePicker.date
let checkOutDate = checkOutDatePicker.date
let numberOfAdults = Int(numberOfAdultsStepper.value)
let numberOfChildren = Int(numberOfChildrenStepper.value)
let hasWifi = wifiSwitch.isOn
return Registration(firstName: firstName, lastName: lastName, emailAddress: email, checkInDate: checkInDate, checkOutDate: checkOutDate, numberOfAdults: numberOfAdults, numberOfChildren: numberOfChildren, roomType: roomType, wifi: hasWifi)
}
var selectedItem: Registration?
// MARK: Outlets
@IBOutlet weak var firstNameTextField: UITextField!
@IBOutlet weak var lastNameTextField: UITextField!
@IBOutlet weak var emailTextField: UITextField!
@IBOutlet weak var checkInDateLabel: UILabel!
@IBOutlet weak var checkInDatePicker: UIDatePicker!
@IBOutlet weak var checkOutDateLabel: UILabel!
@IBOutlet weak var checkOutDatePicker: UIDatePicker!
@IBOutlet weak var numberOfAdultsLabel: UILabel!
@IBOutlet weak var numberOfAdultsStepper: UIStepper!
@IBOutlet weak var numberOfChildrenLabel: UILabel!
@IBOutlet weak var numberOfChildrenStepper: UIStepper!
@IBOutlet weak var roomTypeLabel: UILabel!
@IBOutlet weak var wifiSwitch: UISwitch!
// MARK: Actions
@IBAction func datePickerValueChanged(_ sender: UIDatePicker) {
updateDateViews()
}
@IBAction func stepperValueChanged(_ sender: UIStepper) {
updateNumberOfGuests()
}
@IBAction func wifiSwitchChanged(_ sender: UISwitch) {
// implemented later
}
@IBAction func cancelButtonTapped(_ sender: Any) {
dismiss(animated: true, completion: nil)
}
// MARK: Methods
func updateDateViews() {
checkOutDatePicker.minimumDate = checkInDatePicker.date.addingTimeInterval(86400)
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .medium
checkInDateLabel.text = dateFormatter.string(from: checkInDatePicker.date)
checkOutDateLabel.text = dateFormatter.string(from: checkOutDatePicker.date)
}
func updateNumberOfGuests() {
numberOfAdultsLabel.text = "\(Int(numberOfAdultsStepper.value))"
numberOfChildrenLabel.text = "\(Int(numberOfChildrenStepper.value))"
}
func updateRoomType() {
if let roomType = roomType {
roomTypeLabel.text = roomType.name
} else {
roomTypeLabel.text = "Not Set"
}
}
func didSelect(roomType: RoomType) {
self.roomType = roomType
updateRoomType()
}
override func viewDidLoad() {
super.viewDidLoad()
let midnightToday = Calendar.current.startOfDay(for: Date())
checkInDatePicker.minimumDate = midnightToday
checkInDatePicker.date = midnightToday
updateDateViews()
updateNumberOfGuests()
updateRoomType()
}
// MARK: TableView Data
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
switch (indexPath.section, indexPath.row) {
case (checkInDatePickerCellIndexPath.section, checkInDatePickerCellIndexPath.row):
if isCheckInDatePickerShown {
return 216.0
} else {
return 0.0
}
case (checkOutDatePickerCellIndexPath.section, checkOutDatePickerCellIndexPath.row):
if isCheckOutDatePickerShown {
return 216.0
} else {
return 0.0
}
default:
return 44.0
}
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
switch (indexPath.section, indexPath.row) {
case (checkInDatePickerCellIndexPath.section, checkInDatePickerCellIndexPath.row - 1):
if isCheckInDatePickerShown {
isCheckInDatePickerShown = false
} else if isCheckOutDatePickerShown {
isCheckOutDatePickerShown = false
isCheckInDatePickerShown = true
} else {
isCheckInDatePickerShown = true
}
tableView.beginUpdates()
tableView.endUpdates()
case (checkOutDatePickerCellIndexPath.section, checkOutDatePickerCellIndexPath.row - 1):
if isCheckOutDatePickerShown {
isCheckOutDatePickerShown = false
} else if isCheckInDatePickerShown {
isCheckInDatePickerShown = false
isCheckOutDatePickerShown = true
} else {
isCheckOutDatePickerShown = true
}
tableView.beginUpdates()
tableView.endUpdates()
default:
break
}
}
// MARK: Navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "SelectRoomType" {
let destinationViewController = segue.destination as? SelectRoomTypeTableViewController
destinationViewController?.delegate = self
destinationViewController?.roomType = roomType
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
本教程面临的挑战是,从这里开始:
“使用segue更新
RegistrationTableViewController
(TVC1),允许用户选择并查看AddRegistrationTableViewController
(TVC2)中的注册详细信息。希望这有助于提供正确的解决方案。
最佳答案
在TVC2屏幕中创建一个属性,例如selectedItem
。
var selectedItem: Registration?
修改准备单元格...
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "ViewReservationDetails" {
let sourceCell = sender as! UITableViewCell
if let indexPath = tableView.indexPath(for: sourceCell) {
if let dest = segue.destination as? <#Destination view controller#> {
dest.selectedItem = registrations[indexPath.row]
}
}
}
}
最后,在目标视图控制器(具有TVC2)中,您需要检查
selectedItem
并在viewDidLoad:
或任何地方分配值。 override func viewDidLoad() {
super.viewDidLoad()
if let item = selectedItem {
//here set value as you want to views
}
}
关于ios - 如何选择回到TableViewController的填充版本(Swift)?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50367545/