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

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

ただいまの
回答率

87.58%

単語帳アプリでデータベースを1つずつ読み出したい

解決済

回答 1

投稿

  • 評価
  • クリップ 1
  • VIEW 2,199

score 12

コード

前提・実現したいこと

Xcode 7.3.1/Swift/sqliteで単語帳アプリを作っています。
FMDBを設定し、libsqlite3.tbdも設定しました。
データベースはテーブルが20個ぐらいあって、カラムは、ID、JPN、ENG、KANAです。

メイン画面に章のタイトルを20個ぐらい表示し、タイトルを選ぶと画面遷移。
そこに、その章の最初の日本語を表示させ→ボタンをクリックすると→英語とカナが表示され→[次へ]ボタンをクリックすると→次の日本語が表示される、というものです。

メイン画面からsegueで章のタイトルを次の画面に表示させること、そのタイトルのIDに応じて、最初に表示させる日本語を切り替えることはできました。また、データベースのパスもラベルに表示させることができました。
ViewLoadで最初に表示させる日本語を設定しています。
ボタンをクリックすると、それに対応する英語と仮名を表示させます。
それぞれのテーブルの最初のカラムです。

ただ、その先が分かりません。
[Next]ボタンをクリックしたら、どうやって1つ1つインクリメントしていくのか?
いろいろネットを探しても出てきません。。。

なにとぞ、よろしくお願いいたします。

該当のソースコード

import Foundation
import UIKit

class DetailViewController: UIViewController {

@IBOutlet var nameLabel: UILabel?
@IBOutlet weak var tvJpn: UITextView!
@IBOutlet weak var tvEng: UITextView!
@IBOutlet weak var tvKana: UITextView!    
@IBOutlet weak var btnModel: UIButton!
@IBOutlet weak var btnEngKana: UIButton!
@IBOutlet weak var btnNext: UIButton!

var databasePath = NSString()

var recipe: Recipe?

override func viewDidLoad() {
super.viewDidLoad()
navigationItem.title = recipe?.name

let dirPaths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
let docsDir = dirPaths[0]
databasePath = docsDir.stringByAppendingPathComponent("Dic.db")

nameLabel?.text = databasePath as String
let contactDB = FMDatabase(path: databasePath as String)
contactDB.open()

switch recipe!.ID {
case 1:
tvJpn.text = "僕の名前は浅野力也です。"
case 2:
tvJpn.text = "2番目です"
case 3:
tvJpn.text = "3番目です"
case 4:
tvJpn.text = "4番目です"
case 5:
tvJpn.text = "5番目です"
case 6:
tvJpn.text = "6番目です"
case 7:
tvJpn.text = "7番目です"
case 8:
tvJpn.text = "8番目です"
case 9:
tvJpn.text = "9番目です"
case 10:
tvJpn.text = "10番目です"
default:
break
}

}
@IBAction func btnAnswerPressed(sender: AnyObject) {
case 1:
tvEng.text = "My name is Rikiya Asano."
tvKana.text = "マイネイムイズリキヤアサノ"
case 2:
tvEng.text = "My name is 2."
tvKana.text = "マイネイムイズ2"
case 3:
tvEng.text = "My name is 3."
tvKana.text = "マイネイムイズ3"
case 4:
tvEng.text = "My name is 4."
tvKana.text = "マイネイムイズ4"
case 5:
tvEng.text = "My name is 5."
tvKana.text = "マイネイムイズ5"
case 6:
tvEng.text = "My name is 6."
tvKana.text = "マイネイムイズ6"
case 7:
tvEng.text = "My name is 7."
tvKana.text = "マイネイムイズ7"
case 8:
tvEng.text = "My name is 8."
tvKana.text = "マイネイムイズ8"
case 9:
tvEng.text = "My name is 9."
tvKana.text = "マイネイムイズ9ノ"
case 10:
tvEng.text = "My name is 10."
tvKana.text = "マイネイムイズ10"
default:
break
}

}

@IBOutlet weak var btnNextPressed: UIButton!

}

```

試したこと

課題に対してアプローチしたことを記載してください

補足情報(言語/FW/ツール等のバージョンなど)

より詳細な情報

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+1

IDでソートしてデータを全て取得して配列を作成、一問ごとに配列から取り出して表示するのが処理的にも簡単だと思いますがいかがでしょうか?

サンプル

teratail_46871 Sample
BundleのDatabaseをコピーして使用しています、分からない所があればコメントください。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/09/08 18:10

    早速のお返事、さらにサンプルコードありがとうございました!
    本当に本当にありがとうございました。
    お返事が遅くなりまして申し訳ございません。
    きちんとできたらご報告しようと思っておりました。

    コードを拝見しながら、複数のテーブルを表示させるのは、どうしたら良いのだろうといろいろ(本当にいろいろ)がんばってみました。

    それで、
    データベースを2つ用意する。
    →最初の画面の目次はテーブル1つのみ。遷移後は18のテーブルを持つデータベース。
    データベースマネージャーファイルも2つ用意。
    Caseによって、読み込むテーブルを切り分ける。

    ところまでは、できました。ビルドすると、最初の画面で選んだ項目が次の画面に表示されます。ViewLoadで、それぞれのテーブルの最初の日本語が無事表示されました。ボタンをクリックすると、その日本語に対する英語も表示されました。

    しかし。もう一度ボタンをクリックしても、次に進みません。同じ日本語が表示され、もう一度クリックすると、その日本語に対する英語が表示されます。

    インクリメントができていないということでしょうか?tocItem.countは、どこか別の場所で宣言してやらないといけないのでしょうか?

    あと一歩な気がするのですが。
    本当に申し訳ございません。なにとぞ、よろしくお願いいたします!!!

    import UIKit

    class DetailViewController: UIViewController {

    var dataArray: [DataModel] = []

    enum RecipeStatus {
    case jpn, eng

    mutating func statusNext() {
    switch self {
    case jpn: return self = .eng
    case eng: return self = .jpn
    }
    }
    }

    @IBOutlet weak var jpnLabel: UILabel!
    @IBOutlet weak var engLabel: UILabel!
    @IBOutlet weak var kanaLabel: UILabel!
    @IBOutlet weak var button: UIButton!

    var data: [TocDataModel]!
    var tocItem: [DataModel]!
    var index: Int = 0
    var status = RecipeStatus.jpn
    var swindex: Int = 0
    var sindex: Int = 0




    override func viewDidLoad() {
    super.viewDidLoad()
    navigationItem.title = data[index].name




    switch swindex {
    case 1:
    tocItem = TableDataBaseManager.sharedInstance.select1AllData()

    setRecipe()

    case 2:
    tocItem = TableDataBaseManager.sharedInstance.select2AllData()
    .
    .
    .
    case 18:
    tocItem = TableDataBaseManager.sharedInstance.18AllData()
    setRecipe()

    default:
    break
    }
    }

    func setRecipe() {

    jpnLabel.text = tocItem[index].jpn
    engLabel.text = tocItem[index].eng
    kanaLabel.text = tocItem[index].kana
    }

    @IBAction func pushButton(sender: UIButton) {

    switch status {
    case .jpn:
    engLabel.hidden = false
    kanaLabel.hidden = false
    button.setTitle("次へ", forState: .Normal)

    case .eng:
    if sindex < tocItem.count - 1 {
    sindex += 1
    setRecipe()
    } else {
    print("Finish!")
    return
    }
    engLabel.hidden = true
    kanaLabel.hidden = true
    button.setTitle("英語", forState: .Normal)
    }
    self.title = "No.\(index + 1)"
    status.statusNext()
    }

    override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    }
    }

    キャンセル

  • 2016/09/08 20:59

    すみません!!わかりました!!!だいじょうぶです!!!

    キャンセル

  • 2016/09/08 21:02

    [index]は[sindex]でした!

    func setRecipe() {

    jpnLabel.text = tocItem[sindex].jpn
    engLabel.text = tocItem[sindex].eng
    kanaLabel.text = tocItem[sindex].kana
    }
    に変えたら行けました!!ありがとうございました!!

    キャンセル

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

  • ただいまの回答率 87.58%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る