質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Core Data

Core DataはAppleのOS X and iOSのためのオブジェクトモデリングと持続性を持ったフレームワークです。Xcodeはエンティティー、属性そして関係性を特定するためのオブジェクトモデルの編集機能を提供します。

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

3回答

488閲覧

テーブルビューのセルに置いたTextFieldへ入力して計算を行いたい

Haruto513

総合スコア52

Core Data

Core DataはAppleのOS X and iOSのためのオブジェクトモデリングと持続性を持ったフレームワークです。Xcodeはエンティティー、属性そして関係性を特定するためのオブジェクトモデルの編集機能を提供します。

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2019/06/13 08:02

swiftは素人です。
今日の午前に、ちょっとしたデータ管理アプリの制作にあたって躓いたところを質問させていただきました。
https://teratail.com/questions/194689

セルの中に置いたテキストフィールドとラベルの入力操作について、「UITextFieldDelegateか、notificationを使ってみてはどうか」というアドバイスを受け、それを参考に進めていきました。
そこで、通知を受け取ってfuncを走らせることができたのはいいものの、発生したエラーのために先に進められない状況です。

swift

1class TableviewCell, UITableViewCell, UITextFieldDelegate { 2 3override func awakeFromNib() { 4 super.awakeFromNib() 5 6 NotificationCenter.default.addObserver(self, selector: #selector(self.changeText(sender:)), name: UITextField.textDidEndEditingNotification, ocject: nil) 7 8} 9 10@IBOutlet weak var x: UITextField! 11@IBOutlet weak var y: UITextField! 12@IBOutlet weak var total: UILabel! 13. 14. 15. 16 17func changeText(sender: Notification) { 18 guard let textview = sender.object as? UITextField else { 19 print("失敗") 20 return 21 } if textview != nil { 22 print("一応成功") 23 var Total: Int = Int(total.text!)! 24 var X: Int = Int(x.text!)! 25 var Y: Int = Int(y.text!)! 26 Total = X + Y 27 total.text = "(Total)" 28 } 29} 30func textFieldShouldReturn(_ textField: UITextField) -> Bool { 31 textField.resignFirstResponder() 32 self.endEditing(true) 33 return true 34} 35 36. 37. 38. 39 40} 41

このように書いてシミュレーターを起動し、実際に入力してtotalの値が変わるのかどうかを確かめようとしたところ、入力し終わり、リターンキーを押してキーボードが閉じるタイミングでアプリがクラッシュし、var Totalが書かれた行に以下のようなエラー文が表示されました。

Thread 1: Fattal error: Unexpectedly found nil while implicitly unwrapping an Optional Value

コンソールを見たところ、確かにTotal,X,Yのところは =(int) 0 と表示されており、本来入っている値が入っていませんでした。

試してみたこと

・・・と、言っていいかわかりませんが、変数に入れる前のオブジェクトの中の文字列をprint文で出力してみると、一番上の行以外に入力しても必ず一番上の値になっていました。(一番上に入力した時は値が入力したものに変わっていました。)
イメージ説明

func changeText(sender: Notification) { guard let textview = sender.object as? UITextField else { print("失敗") return } if textview != nil { print("一応成功") print(total.text.debugDescription)   //必ずOptional("500") print(x.text.debugDescription) //必ずOptional("250") print(y.text.debugDescription) //必ずOptional("250") var Total: Int = Int(total.text!)! var X: Int = Int(x.text!)! var Y: Int = Int(y.text!)! Total = X + Y total.text = "(Total)" } }

拙い質問で恐縮ですが、なんとか突破口を見出したいです。
教えていただけると助かります。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

自己解決

質問からいろいろと調べて、とりあえずの解決はできたので自己解決として記します。

swift

1 2class TableviewCell, UITableViewCell, UITextFieldDelegate { 3 4var delegate: CustomTableviewCellDelegate! = nil 5 6override func awakeFromNib() { 7 super.awakeFromNib() 8} 9 10@IBOutlet weak var x: UITextField! 11@IBOutlet weak var y: UITextField! 12@IBOutlet weak var total: UILabel! 13 14func Calculation(Item: Entity) { 15 x.text = Item.cell1?.stringValue 16 y.text = Item.cell2?.stringValue 17 total.text = Item.total.stringValue 18} 19 20func textFieldShouldReturn(_ textField: UITextField) -> Bool { 21 textField.resignFirstResponder() 22 self.endEditing(true) 23 return true 24} 25 26//追加記述です 27func textFieldDidBeginEditing(_ textField: UITextField) { 28 delegate.textFieldDidBeginEditing(cell: self, TextField: textField) 29} 30 31//追加記述です 32func textFieldDidEndEditing(_ textField: UITextField) { 33 delegate.textFieldDidEndEditing(cell: self, TextField: textField) 34} 35} 36 37//追加記述です。 38protocol CustomTableviewCellDelegate { 39 func textFieldDidBeginEditing(cell: UITableViewCell, TextField: UITextField) -> () 40 func textFieldDidEndEditing(cell: UITableViewCell, TextField: UITextField) -> () 41} 42 43

テーブルビューセルでこのような記述をしてから、テーブルビューが置いてあるビューコントローラーにて以下のように記述しました。

swift

1 2class ViewContloller: UIViewController, UITableViewDataSource, UITableViewDelegate, CustomTableviewCellDelegate { 3 4@IBOutlet weak var CalculationTable: UITableView! 5 6func textFieldDidBeginEditing(cell: UITableViewCell, TextField: UITextField) { 7 let row = CalculationTable.indexPathForRow(at: cell.convert(cell.bounds.origin, to: CalculationTable))!.row 8 switch TextField.tag { 9 case 0: 10 CalculationTable.selectRow(at: IndexPath.init(row: row, section: 0), animated: true, scrollPosition: .middle) 11 case 1: 12 CalculationTable.selectRow(at: IndexPath.init(row: row, section: 0), animated: true, scrollPosition: .middle) 13 default: 14 break 15

カスタムセルのXibファイルに置いたテキストフィールドに、アトリビュートインスペクタでタグとして番号を振りました。
これにより、テキストフィールを押下したときにそのテキストフィールドがあるセルが選択状態となります。
エラーの原因はセルが選択されていなかったからのようでした。

続けて計算して、ラベルを変える処理です。

private var ItemRec: [Entity] = [] func textFieldDidEndEditing(cell: UITableViewCell, TextField: UITextField) { let items = ItemRec[CalculationTable.indexPathForSelectedRow!.row] let CurrentCell = CalculationTable.cellForRow(at: CalculationTable.indexPathForSelectedRow!) as! TableviewCell let X = CurrentCell.x.text! let Y = CurrentCell.y.text! let Total = { (x: Int, y: Int) -> Int in let total = x + y return total } let Result = Total(Int(X)!, Int(Y)!) items.cell1 = Int(X)! items.cell2 = Int(Y)! items.total = Result //ここで、変更したデータを保存します。 //テーブルビューをリフレッシュします。   CalculationTable.reloadData() //選択状態を解除して、処理が終了します。   CurrentCell.isSelected = false }

テーブルのデータは永続ストアから読み込んだものを流し込んでいるので、永続ストアに変更したデータを保存して、テーブルをリフレッシュすれば、ラベルに表示される数字が新しいものに変わります。

こんな感じでやりたかった操作を実現させました。
正直まだいろいろやり方はあるかもしれないと思うところもありますが・・・。

質問に答えてくださった方、ご協力ありがとうございました。

投稿2019/07/01 05:49

Haruto513

総合スコア52

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

Swift

1NotificationCenter.default.addObserver(self, selector: #selector(self.changeText(sender:)), name: UITextField.textDidEndEditingNotification, object: nil)

ですと、全てのUITextFieldから通知が届きます。

Swift

1NotificationCenter.default.addObserver(self, selector: #selector(self.changeText(sender:)), name: UITextField.textDidEndEditingNotification, object: x)

のようにobjectに対象とするUITextFieldを指定すると、そのUITextFieldインスタンスからの通知のみが届きます。xとy、2回addObserverを記述してみてください。そのxインスタンスとyインスタンスからの通知のみが届くはずです。

投稿2019/06/13 09:02

rizumita

総合スコア84

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Haruto513

2019/07/01 05:51

回答からお返事が遅くなってしまい、申し訳ありませんでした。コメントとても参考になりました。ありがとうございました!
guest

0

話の流れは判っていませんが、突破口とのことですので、

Thread 1: Fattal error: Unexpectedly found nil while implicitly unwrapping an Optional Value

は基本的にはオプショナル変数の値がnilになっているものを(中がnilかどうかを確認せずに)無理やり使っている時にでます。

nilになっている変数を見つけるところから始めてください。

投稿2019/06/13 08:54

takabosoft

総合スコア8356

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Haruto513

2019/07/01 05:51

回答からお返事が遅くなってしまい、申し訳ありませんでした。コメントとても参考になりました。ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問