Swift Playgrounds 中的简单笔记应用
Posted
技术标签:
【中文标题】Swift Playgrounds 中的简单笔记应用【英文标题】:A simple notes app in Swift Playgrounds 【发布时间】:2017-10-28 07:14:57 【问题描述】:我正在尝试在 Swift Playgrounds 中创建一个简单的笔记应用程序,但我卡住了。
由于没有情节提要,如何在没有 prepareForSegue
的情况下将数据从主视图(UITableView
)发送到详细视图(UITextView
),反之亦然?
我错过了什么或做错了什么?
我一直在努力寻找解决方案,因此我们将不胜感激。
这是我的游乐场:
import UIKit
import PlaygroundSupport
class MasterViewController: UITableViewController
var noteData: [String] = []
var selectedRow: Int = -1
var newRowLabel: String = ""
override func viewDidLoad()
configureNavigationBar()
loadNote()
override func viewWillAppear(_ animated: Bool)
super.viewWillAppear(animated)
if selectedRow == -1
return
noteData[selectedRow] = newRowLabel
if newRowLabel == ""
noteData.remove(at: selectedRow)
tableView.reloadData()
saveNote()
@objc func newNote()
let noteTitle: String = ""
noteData.insert(noteTitle, at: 0)
let indexPath: IndexPath = IndexPath(row: 0, section: 0)
tableView.insertRows(at: [indexPath], with: .automatic)
tableView.selectRow(at: indexPath, animated: true, scrollPosition: .none)
navigationController?.pushViewController(DetailViewController(), animated: true)
func configureNavigationBar()
title = "Notes"
let addButton = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(newNote))
navigationItem.rightBarButtonItem = addButton
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
return noteData.count
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
var cell = tableView.dequeueReusableCell(withIdentifier: "Cell")
if cell == nil
cell = UITableViewCell(style: .default, reuseIdentifier: "Cell")
cell?.textLabel?.text = noteData[indexPath.row]
return cell!
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath)
noteData.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: .fade)
saveNote()
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
navigationController?.pushViewController(DetailViewController(), animated: true)
override func prepare(for segue: UIStoryboardSegue, sender: Any?)
let detailView: DetailViewController = segue.destination as! DetailViewController
selectedRow = tableView.indexPathForSelectedRow!.row
detailView.masterView = self
detailView.setText(noteText: noteData[selectedRow])
func saveNote()
UserDefaults.standard.set(noteData, forKey: "Notes")
UserDefaults.standard.synchronize()
func loadNote()
if let loadedNote = UserDefaults.standard.value(forKey: "notes") as? [String]
noteData = loadedNote
tableView.reloadData()
class DetailViewController: UIViewController
let textView = UITextView()
var noteText: String = ""
var masterView: MasterViewController!
override func loadView()
configureDetailView()
override func viewDidLoad()
configureTextView()
func configureDetailView()
view = textView
func configureTextView()
textView.text = noteText
func setText(noteText: String)
if isViewLoaded
textView.text = noteText
override func viewWillDisappear(_ animated: Bool)
super.viewWillDisappear(animated)
masterView?.newRowLabel = noteText
let masterViewController = MasterViewController()
let navigationController = UINavigationController(rootViewController: masterViewController)
PlaygroundPage.current.liveView = navigationController
【问题讨论】:
【参考方案1】:在您的didSelectRow
方法中:
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
navigationController?.pushViewController(DetailViewController(), animated: true)
您正在创建您的DetailViewController()
,但当您的视图控制器有变量来接受数据时,您没有将任何数据传递给它,所以为了做到这一点而不是这样做:
navigationController?.pushViewController(DetailViewController(), animated: true)
你可以这样做:
let detailVC = DetailViewController()
detailVC.noteText = noteData[indexPath.row]
navigationController?.pushViewController(detailVC, animated: true)
编辑:我正在从这里更新我的答案,因为您的解决方案需要进行大量更改才能完成,就像我在上面解释的如何传递数据的方式一样,您必须以各种方式执行此操作以及创建新笔记的地方
首先要保存新的表格视图单元格并自行更新,您需要将 newNote()
函数调整为:
@objc func newNote()
let noteTitle: String = ""
noteData.insert(noteTitle, at: 0)
let indexPath: IndexPath = IndexPath(row: 0, section: 0)
tableView.insertRows(at: [indexPath], with: .automatic)
tableView.selectRow(at: indexPath, animated: true, scrollPosition: .none)
selectedRow = indexPath.row
let detailVC = DetailViewController()
detailVC.masterView = self
navigationController?.pushViewController(detailVC, animated: true)
您将selectedRow
变量设置为插入的indexPath
并将masterView
传递给DetailsViewController()
其次,您还需要更改didSelectRow
,使用我发布的相同解决方案,但同样也将您的masterView
和selectedRow
传递给那里,所以它应该看起来像这样:
let detailVC = DetailViewController()
detailVC.noteText = noteData[indexPath.row]
detailVC.masterView = self
selectedRow = indexPath.row
navigationController?.pushViewController(detailVC, animated: true)
第三,您的 DetailViewController 缺少一件事,每当在您的文本视图中输入文本时,它都不会更新 noteText
并且您的 viewWillDisappear
方法依赖于此,您需要将文本视图的委托设置为 self 并收听文本更改,但是为了更简单的解决方案,将您的viewWillDisappear
更改为直接访问textView
,如下所示:
override func viewWillDisappear(_ animated: Bool)
super.viewWillDisappear(animated)
masterView?.newRowLabel = textView.text
第四,当您从该屏幕返回时,您的 MasterViewController 需要将其保存在您的 viewWillAppear
方法中,那里也需要进行一些更改,实际上您只需要重置您的 selectedRow
变量即可打电话后保存:
saveNote()
在下一行还添加:
selectedRow = -1
【讨论】:
@BoleTzar 我刚刚更新了我的答案,指出了代码中需要解决的问题【参考方案2】:代替
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
navigationController?.pushViewController(DetailViewController(), animated: true)
你可以像这样创建DetailViewController并分配noteText
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
let detailViewController = DetailViewController()
detailViewController.noteText = noteData[indexPath.row]
detailViewController.masterView = self
navigationController?.pushViewController(detailViewController, animated: true)
函数prepare
可以删除,因为你不用storyboard所以没用。
别忘了适应newNote()
:
@objc func newNote()
let noteTitle: String = ""
noteData.insert(noteTitle, at: 0)
let indexPath: IndexPath = IndexPath(row: 0, section: 0)
tableView.insertRows(at: [indexPath], with: .automatic)
tableView.selectRow(at: indexPath, animated: true, scrollPosition: .none)
let detailViewController = DetailViewController()
detailViewController.masterView = self
navigationController?.pushViewController(detailViewController, animated: true)
【讨论】:
我删除了prepare
函数并添加了您建议的代码,但在UITextView
中输入的文本没有保存,表格单元格仍然没有更新。有什么想法吗?
我将detailViewController.masterView = self
添加到didSelectRowAt...
。而且你必须调整newNote
函数来设置masterView
以上是关于Swift Playgrounds 中的简单笔记应用的主要内容,如果未能解决你的问题,请参考以下文章
Swift Playgrounds 可以查看同一个项目中的其他源文件吗?
Swift Playgrounds 中的 JavaScriptCore
Swift Playgrounds 中的 UIGestureRecognizer