swift - Swift 文本框问题
问题描述
此应用程序旨在让他们的用户对约克学院的宿舍进行评分。为了学习语言,我使用了苹果开发者网站并按照他们的分步说明制作了基本应用程序。添加一些小功能后,我尝试添加一个文本框,供用户添加每个宿舍的描述。它运行,但似乎没有显示已添加到描述部分的文本。这是用旧版本的 Swift 编写的。
**MealTableViewController.swift**
// MealTableViewController.swift
// FoodTracker
//
// Created by Jane Appleseed on 11/15/16.
// Copyright © 2016 Apple Inc. All rights reserved.
//
import UIKit
import os.log
class MealTableViewController: UITableViewController {
//MARK: Properties
var meals = [Meal]()
override func viewDidLoad() {
super.viewDidLoad()
// Use the edit button item provided by the table view controller.
navigationItem.leftBarButtonItem = editButtonItem
// Load any saved meals, otherwise load sample data.
if let savedMeals = loadMeals() {
meals += savedMeals
}
else {
// Load the sample data.
loadSampleMeals()
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
//MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return meals.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// Table view cells are reused and should be dequeued using a cell identifier.
let cellIdentifier = "MealTableViewCell"
guard let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as? MealTableViewCell else {
fatalError("The dequeued cell is not an instance of MealTableViewCell.")
}
// Fetches the appropriate meal for the data source layout.
let meal = meals[indexPath.row]
cell.nameLabel.text = meal.name
cell.photoImageView.image = meal.photo
cell.ratingControl.rating = meal.rating
cell.descriptionLabel?.text = meal.desc
print(meal.desc!)
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: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
// Delete the row from the data source
meals.remove(at: indexPath.row)
saveMeals()
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?) {
super.prepare(for: segue, sender: sender)
switch(segue.identifier ?? "") {
case "AddItem":
os_log("Adding a new meal.", log: OSLog.default, type: .debug)
case "ShowDetail":
guard let mealDetailViewController = segue.destination as? MealViewController else {
fatalError("Unexpected destination: \(segue.destination)")
}
guard let selectedMealCell = sender as? MealTableViewCell else {
fatalError("Unexpected sender: \(String(describing: sender))")
}
guard let indexPath = tableView.indexPath(for: selectedMealCell) else {
fatalError("The selected cell is not being displayed by the table")
}
let selectedMeal = meals[indexPath.row]
mealDetailViewController.meal = selectedMeal
default:
fatalError("Unexpected Segue Identifier; \(String(describing: segue.identifier))")
}
}
//MARK: Actions
@IBAction func unwindToMealList(sender: UIStoryboardSegue) {
if let sourceViewController = sender.source as? MealViewController, let meal = sourceViewController.meal {
if let selectedIndexPath = tableView.indexPathForSelectedRow {
// Update an existing meal.
meals[selectedIndexPath.row] = meal
tableView.reloadRows(at: [selectedIndexPath], with: .none)
}
else {
// Add a new meal.
let newIndexPath = IndexPath(row: meals.count, section: 0)
meals.append(meal)
tableView.insertRows(at: [newIndexPath], with: .automatic)
}
// Save the meals.
saveMeals()
os_log("Saved Meals?", log: OSLog.default, type: .debug)
}
}
//MARK: Private Methods
//*** MAKE SAMPLE DORMS ***
private func loadSampleMeals() {
let photo1 = UIImage(named: "meal1")
let photo2 = UIImage(named: "meal2")
let photo3 = UIImage(named: "meal3")
guard let meal1 = Meal(name: "Northside Commons", photo: photo1, rating: 5, desc: "Great Rooms, air conditioning") else {
fatalError("Unable to instantiate dorm1")
}
guard let meal2 = Meal(name: "Beard Hall", photo: photo2, rating: 2, desc: "Lots of space") else {
fatalError("Unable to instantiate meal2")
}
guard let meal3 = Meal(name: "Mannor Hall", photo: photo3, rating: 3, desc: "No air conditioning, fun floor mates") else {
fatalError("Unable to instantiate meal2")
}
meals += [meal1, meal2, meal3]
}
private func saveMeals() {
let isSuccessfulSave = NSKeyedArchiver.archiveRootObject(meals, toFile: Meal.ArchiveURL.path)
if isSuccessfulSave {
os_log("Meals successfully saved.", log: OSLog.default, type: .debug)
} else {
os_log("Failed to save meals...", log: OSLog.default, type: .error)
}
}
private func loadMeals() -> [Meal]? {
return NSKeyedUnarchiver.unarchiveObject(withFile: Meal.ArchiveURL.path) as? [Meal]
}
}
//
// Meal.swift
// FoodTracker
//
// Created by Jane Appleseed on 11/10/16.
// Copyright © 2016 Apple Inc. All rights reserved.
//
import UIKit
import os.log
class Meal: NSObject, NSCoding {
//MARK: Properties
var name: String
var photo: UIImage?
var rating: Int
var desc: String?
//MARK: Archiving Paths
static let DocumentsDirectory = FileManager().urls(for: .documentDirectory, in: .userDomainMask).first!
static let ArchiveURL = DocumentsDirectory.appendingPathComponent("meals")
//MARK: Types
struct PropertyKey {
static let name = "name"
static let photo = "photo"
static let rating = "rating"
static let desc = "desc"
}
//MARK: Initialization
init?(name: String, photo: UIImage?, rating: Int, desc: String?) {
// The name must not be empty
guard !name.isEmpty else {
return nil
}
/*
guard !desc?.isEmpty else {
return nil
}
*/
// The rating must be between 0 and 5 inclusively
guard (rating >= 0) && (rating <= 5) else {
return nil
}
// The rates must be above 0
guard (rating >= 0) else {
return nil
}
// Initialization should fail if there is no name or if the rating is negative.
if name.isEmpty || rating < 0 {
return nil
}
// Initialize stored properties.
self.name = name
self.photo = photo
self.rating = rating
self.desc = desc
}
//MARK: NSCoding
func encode(with aCoder: NSCoder) {
aCoder.encode(name, forKey: PropertyKey.name)
aCoder.encode(photo, forKey: PropertyKey.photo)
aCoder.encode(rating, forKey: PropertyKey.rating)
aCoder.encode(desc, forKey: PropertyKey.desc)
}
required convenience init?(coder aDecoder: NSCoder) {
// The name is required. If we cannot decode a name string, the initializer should fail.
guard let name = aDecoder.decodeObject(forKey: PropertyKey.name) as? String else {
os_log("Unable to decode the name for a Meal object.", log: OSLog.default, type: .debug)
return nil
}
/*
guard (aDecoder.decodeObject(forKey: PropertyKey.desc) as? String) != nil else {
os_log("Unable to decode the description for a Meal object.", log: OSLog.default, type: .debug)
return nil
}
*/
// Because photo is an optional property of Meal, just use conditional cast.
let photo = aDecoder.decodeObject(forKey: PropertyKey.photo) as? UIImage
let rating = aDecoder.decodeInteger(forKey: PropertyKey.rating)
// Must call designated initializer.
self.init(name: name, photo: photo, rating: rating, desc: "desc")
}
}
解决方案
我知道这不是一个硬性和快速的答案(很难给出一个没有 XIB/Storyboard 文件的答案),但我看到您的描述标签 ( cell.descriptionLabel?
) 是可选的。我会检查您的描述标签是否确实存在,如下所示:
if let descriptionLabel = cell.descriptionLabel? {
descriptionLabel.text = meal.desc
} else {
print("This label doesn't exist!")
}
然后检查你的输出!
推荐阅读
- html - Vue.js物化日期选择器不显示
- javascript - 如何使用 Javascript 将多个音频文件附加到当前正在播放的音频中?
- android - 是否有任何方法可以清除我所有低于 21 的 android 应用程序任务(活动返回堆栈)?
- node.js - 有问题。邮政。评论模式 - Mongoose/Typescript
- mongodb - MongoDB - 如何在插入时引用父级中的子级/嵌套文档_id
- haskell - 如何确定一个 Enum 值是否是另一个 Enum 值的后继值?
- docker - 下载 Hyperledger Fabric docker 图像时遇到问题
- reactjs - 使用 Enzyme 更改 React 功能组件的 Props
- javascript - 如何将两个字段组合成第三个标签?
- azure - 在 Azure App Service for Containers 上启用 gzip 压缩