TableViewのcellに保存されている配列が表示されないのはなぜか。
画面遷移する前は表示されているのですが画面遷移から戻ると初期状態に戻ってしまうのはなぜですか。どうすれば望む処理になるでしょうか。
import UIKit
class TableViewController: UITableViewController {
@IBOutlet var myTableView: UITableView!
var array : Array<String> = ["\(UserDefaults.standard.object(forKey: UserDefaultsController.shard.fastTitleKey + "0") as! String)"]
let arrayNameKey = "arrayNameKey"
override func viewDidLoad() {
super.viewDidLoad()
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return array.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "customTableViewCell", for: indexPath) as! costomViewCell
if let skillNameArray = (UserDefaults.standard.array(forKey: self.arrayNameKey) as? Array<String>) {
cell.skillName.text = "\(skillNameArray[indexPath.row])"
} else {
cell.skillName.text = array[indexPath.row]
}
cell.goalCountLabel.text = secondsToGoalTimerLabel(UserDefaults.standard.integer(forKey: UserDefaultsController.shard.goalCountNumberKey))
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let storyboard : UIStoryboard = self.storyboard!
let nextView =
storyboard.instantiateViewController(withIdentifier: "ViewController")
let navi = UINavigationController(rootViewController: nextView)
UserDefaults.standard.set(indexPath.row, forKey: UserDefaultsController.shard.currentNumberKey)
if let arr = UserDefaults.standard.array(forKey: self.arrayNameKey) {
let arrConversion = arr as! [String]
UserDefaults.standard.set(arrConversion[indexPath.row], forKey: UserDefaultsController.shard.titleCurrentNumberKey)
}
present(navi, animated: true, completion: nil)
}
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
array.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: .fade)
UserDefaults.standard.set(self.array, forKey: self.arrayNameKey)
}
}
@IBAction func addSkillButton(_ sender: UIBarButtonItem) {
var alertTextFeld: UITextField?
let alert = UIAlertController(title: "Skill Name", message: "Enter new name", preferredStyle: UIAlertController.Style.alert)
alert.addTextField { (textField: UITextField!) in
alertTextFeld = textField
}
alert.addAction(UIAlertAction(title: "キャンセル", style: .cancel, handler: nil))
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: { _ in
if let text = alertTextFeld?.text {
self.array.append(text)
UserDefaults.standard.set(self.array, forKey: self.arrayNameKey)
self.myTableView.reloadData()
}
}))
self.present(alert, animated: true, completion: nil)
}
@IBAction func secret(_ sender: UIBarButtonItem) {
}
func saveDate() {
}
}
import UIKit
class costomViewCell: UITableViewCell {
@IBOutlet weak var skillName: UILabel!
@IBOutlet weak var goalCountLabel: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
import UIKit
class UserDefaultsController {
static let shard = UserDefaultsController()
let currentNumberKey = "currentNumberKey"
let fastTitleKey = "fastTitleKey"
let goalCountKey = "goalCountKey"
let userCurrentNumberKey = String(UserDefaults.standard.integer(forKey: "currentNumberKey"))
let titleCurrentNumberKey = "fastTitleKey" + String(UserDefaults.standard.integer(forKey: "currentNumberKey"))
let goalCountNumberKey = "goalCountKey" + String(UserDefaults.standard.integer(forKey: "currentNumberKey"))
init() {
}
↓UIViewCountroller
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var characterImage: UIImageView!
@IBOutlet weak var timerlabel: UILabel!
@IBOutlet weak var startButton: UIButton!
let fastTitleKey = UserDefaultsController.shard.fastTitleKey
override func viewDidLoad() {
super.viewDidLoad()
if let myTitle = UserDefaults.standard.string(forKey: UserDefaultsController.shard.titleCurrentNumberKey) {
self.title = myTitle
} else {
let alert = UIAlertController(title: "Title Name", message: "Please enter new name", preferredStyle: .alert)
alert.addTextField(configurationHandler: nil)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: { _ in
if let text = alert.textFields?[0].text {
self.title = text
UserDefaults.standard.set(0, forKey: UserDefaultsController.shard.currentNumberKey)
UserDefaults.standard.set(text, forKey: UserDefaultsController.shard.titleCurrentNumberKey)
}
}))
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
present(alert, animated: true, completion: nil)
}
startButton.layer.cornerRadius = 25.0
guard let obj = UserDefaults.standard.object(forKey: UserDefaultsController.shard.goalCountNumberKey) else {
return
}
let goalString = "\(obj)"
timerlabel.text = secondsToGoalTimerLabel(Int(goalString)!)
}
override func viewWillAppear(_ animated: Bool) {
guard let obj = UserDefaults.standard.object(forKey: UserDefaultsController.shard.goalCountNumberKey) else {
return
}
let goalString = "\(obj)"
timerlabel.text = secondsToGoalTimerLabel(Int(goalString)!)
}
}
/*****************************************************************/
変更コード
import Foundation
//「1つのセル」に捉われず、「1つのスキル」を表すデータがあればここに追加していく
struct Skill {
var title: String
var goalCount: Int
}
class SkillModal{
//アプリ全体で1インスタンスしかいらないならひたすらシングルトン
static let shared = SkillModal()
//このクラスはシングルトンとしてしかアクセスさせない
private init() { }
//配列としての`skills`を公開しておくと辻褄の合わない更新をしてしまう可能性があるのでprivateにする
private var skills: [Skill] = []
//`ViewController`側ではcurrentな要素を扱う
private var currentIndex: Int? = nil
//currentとなるindexを設定する
func setCurrentIndex(_ newIndex: Int) {
currentIndex = newIndex
}
//currentの要素を返す
var currentSkill: Skill? {
if let index = currentIndex,skills.indices.contains(index) { //indicesて何?containsは指定された範囲内に含まれているか。ではindicesはコレクションを購読するのに有効なインデックス(昇順)とは?
return skills[index]
} else {
return nil
}
}
//一軒追加して、それをcurrentにする
func addAndSetCurrent(_ newSkill: Skill) {
currentIndex = skills.count
skills.append(newSkill)
}
func relode(){
if let skillArray = UserDefaults.standard.array(forKey: "skillArray") as? [Skill] {
skills = skillArray
}
}
//一件追加
func add(_ newSkill: Skill) {
skills.append(newSkill)
}
//一件削除
func remove(at index: Int) {
currentIndex = nil
skills.remove(at: index)
}
//`index`けんめんを取り出す
//`Skill`は値型なので、このメソッドの戻り値のプロパティを変更しても`skills`に反映されない
func skill(at index: Int) -> Skill {
return skills[index]
}
//プロパティを変更したい場合には、専用のメソッドを用意してそれを呼ぶ
//`index`件目の`goalCount`を変更する
func setGoalCount(_ newGoalCount: Int, at index: Int) {
skills[index].goalCount = newGoalCount
}
//要素を返す
var count: Int {
return skills.count
} //なぜここは func count() -> Int { return skills.count }ではなく計算型puropatyなのですか??
func save() {
UserDefaults.standard.set(skill, forKey: "skillArray")
}
func load() -> [Skill] {
let userDefaultsSkill = UserDefaults.standard.array(forKey: "skillArray")
return userDefaultsSkill as! [Skill]
}
}
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var characterImage: UIImageView!
@IBOutlet weak var timerlabel: UILabel!
@IBOutlet weak var startButton: UIButton!
let fastTitleKey = UserDefaultsController.shard.fastTitleKey
override func viewDidLoad() {
super.viewDidLoad()
SkillModal.shared.relode()
SkillModal.shared.load()
if let myTitle = SkillModal.shared.skill(at: 0) {
self.title = myTitle.title
} else {
let alert = UIAlertController(title: "Title Name", message: "Please enter new name", preferredStyle: .alert)
alert.addTextField(configurationHandler: nil)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: { _ in
if let text = alert.textFields?[0].text {
self.title = text
SkillModal.shared.add(Skill(title: text, goalCount: 60 * 60 * 20))
SkillModal.shared.save()
}
}))
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
present(alert, animated: true, completion: nil)
}
startButton.layer.cornerRadius = 25.0
}
override func viewWillAppear(_ animated: Bool) {
guard let skill = SkillModal.shared.currentSkill else {
return
}
self.title = skill.title
timerlabel.text = secondsToGoalTimerLabel(skill.goalCount)
}
}
import UIKit
class TableViewController: UITableViewController {
@IBOutlet var myTableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
SkillModal.shared.relode() // It is this!!
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return SkillModal.shared.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "customTableViewCell", for: indexPath) as! costomViewCell
let skill = SkillModal.shared.skill(at: indexPath.row)
cell.skillName.text = skill.title
cell.goalCountLabel.text = secondsToGoalTimerLabel(skill.goalCount)
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
SkillModal.shared.setCurrentIndex(indexPath.row)
self.navigationController?.popViewController(animated: true)
}
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete { //後で変えて遊んでみる
tableView.deleteRows(at: [indexPath], with: .fade)
}
SkillModal.shared.remove(at: indexPath.row)
}
@IBAction func addSkillButton(_ sender: UIBarButtonItem) {
var alertTextFeld: UITextField?
let alert = UIAlertController(title: "Skill Name", message: "Enter new name", preferredStyle: UIAlertController.Style.alert)
alert.addTextField { (textField: UITextField!) in
alertTextFeld = textField
}
alert.addAction(UIAlertAction(title: "キャンセル", style: .cancel, handler: nil))
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: { _ in
if let text = alertTextFeld?.text {
let indexPath = IndexPath(row: SkillModal.shared.count, section: 0)
SkillModal.shared.add(Skill(title: text, goalCount: 60 * 60 * 20))
self.tableView.insertRows(at: [indexPath], with: .automatic)
SkillModal.shared.save()
}
}))
self.present(alert, animated: true, completion: nil)
}
@IBAction func secret(_ sender: UIBarButtonItem) {
}
}