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

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

ただいまの
回答率

89.21%

swift3で、配列の要素の有無でラベルの表示・非表示を設定したい。

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 972

torkia

score 24

配列の要素をラベルに表示させたいのですが、配列の各行の要素数が同じ数ではないので、要素数に応じた表示にしたいのですが、やり方が分からず、とりあえずviewDidLoad内にラベルを全て(一番多い数)表示させています。そうすると、少ない要素数の配列の行を呼んだ場合、テキスト表示のないラベルも表示されるので、これを何とかしたいのですが・・・。

ラベルの生成はStoryboardで、ラベルの色付けもしてあります。
テーブルビューのセルからindex番号を渡して、csvファイルから読み込んだテキストを表示させています。

この場合は、ラベルの生成はコード入力した方がよろしいのでしょうか?
コード入力でラベルを生成した場合のやり方も知りたいです。

汚いコードですが、どうぞよろしくお願い致します。

xcode8  swift3 で作成しています。

import UIKit
class ViewController: UIViewController {

  @IBOutlet weak var dayLabel: UILabel!
    @IBOutlet weak var categoryLabel: UILabel!
    @IBOutlet weak var titleLabel: UILabel!
    @IBOutlet weak var questionLabel: UILabel!
    @IBOutlet weak var q1Label: UILabel!
    @IBOutlet weak var q2Label: UILabel!
    @IBOutlet weak var q3Label: UILabel!
    @IBOutlet weak var q4Label: UILabel!
    @IBOutlet weak var q5Label: UILabel!
    @IBOutlet weak var q6Label: UILabel!
    @IBOutlet weak var q7Label: UILabel!
    @IBOutlet weak var q8Label: UILabel!
    @IBOutlet weak var q9Label: UILabel!
    @IBOutlet weak var q10Label: UILabel!

    //シーン移動の際に設定されるデータ
    var received:Int?

    //csvArrayから取り出した問題を格納する配列dayArray
    var dayArray:[String] = []

    override func viewDidLoad() {
        super.viewDidLoad()

        //CSVファイル名を引数にしてloadCSVメソッドを使用し、CSVファイルを読み込む
    let csvArray = loadCSV("time")

        //csvArrayの行をタップされた番号で取得
        dayArray = csvArray[received!].components(separatedBy: ";")
      
    //ラベルにテキストを設定
        dayLabel.text = dayArray[0]
        categoryLabel.text = dayArray[1]
        titleLabel.text = dayArray[2]
        questionLabel.text = dayArray[3]

        q1Label.text = dayArray[5]
        q2Label.text = dayArray[7]
        q3Label.text = dayArray[9]
        q4Label.text = dayArray[11]
        q5Label.text = dayArray[13]
        q6Label.text = dayArray[15]
        q7Label.text = dayArray[17]
        q8Label.text = dayArray[19]
        q9Label.text = dayArray[21]
        q10Label.text = dayArray[23]
    }

(略)   

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

質問への追記・修正、ベストアンサー選択の依頼

  • MasakiHori

    2017/11/08 17:06

    「少ない要素数の配列の行を呼んだ場合」とありますが、お示しのコードは要素が少ない場合クラッシュします。要素は規定数あるが、内容が空文字列("")であるということでしょうか?

    キャンセル

  • torkia

    2017/11/08 18:50

    追記ありがとうございます。q1Label〜q10Labelまでに問題文を表示させているのですが、問題が10問だったり7問だったりとバラバラで、それぞれ表示はできるのですが、余分なラベルまで表示されるので、「テキスト表示のないラベルは非表示にさせたい」ということなのですが・・・。配列の中身はcsvファイルから内容を取得していて、空文字列(" ")のようなものは作成しておりません。

    キャンセル

回答 2

check解決した方法

0

csvファイルの作成をOpenOffice(フリーソフト)で作成しているのですが、csvファイルの行末を見ると「フィールドの区切り記号」に設定した記号が、一番多い要素数の行に合わせて他の行(要素数が少ない行)にも既成されてました。その行末の記号群が空文字列として扱われていたようです。
<例> 
あ;;;;
か;き;く;;
さ;し;す;せ;そ    //一番多い数の要素数

なので、ラベルはfor_in文で量産して配列labelsに入れてif文で空文字列の表示を不可にしました。

for  index in 0..<31 { //最大要素数分のラベルを生成
            let label = UILabel()
           (略)
            label.text = dayArray[6 + (4 * index)]
            labels.append(label)
            scrollView.addSubview(label)
        }

// 空文字列が入ったラベルは表示させない
        for index in 0..<labels.count {
            if labels[index].text == "" {
                labels[index].isHidden = true
           }
        }


もしくは、行末の空文字列(フィールドの区切り記号の群)を消せば、行末に自動的に既成された空文字列は認識されなくなります。
そうすると各配列の要素数でラベルを量産してその数だけラベルを表示させられます。

for  index in 0..<((dayArray.count - 5) / 4) {  //各配列の要素数でラベルを生成
            let label = UILabel()
            (略)
            label.text = dayArray[6 + (4 * index)]
            labels.append(label)
            scrollView.addSubview(label)
        }


記号群を消す方法は
● csvファイルをswiftに読み込んだ後でそのファイルをクリックして表示させ、直接消す。
● csvファイルをテキストエディット(Mac付属のソフト)などで開きなおして行末の記号群を消してからswiftに取り込む。(↑OpenOfficeで作成した場合しかわかりませんが)
※OpenOfficeの方でcsv保存するときに行末にフィールドの区切り記号の群を既成させない方法は分かりません。 なので、使用するcsvファイルの内容(行数やファイル数)が多い場合は記号群を消す方が大変かもしれません。保存時に既成させない方法がわかればいいのですが・・・。

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/07/18 12:51

    >>タブ区切りの記号が一番多いタブ数の行に合わせて...
    csvってそういうものですよ。
    非表示にするのではなく、そもそも生成しなければいいと思うのですが?

    キャンセル

  • 2018/07/18 14:47

    ご回答ありがとうございます。
    回答欄に不足していた説明文とコードを追加致しました。
    >>そもそも生成しなければいいと思うのですが?
    全くその通りで、はじめからその方法を模索しておりましたが、なかなか解決策が浮かばず・・・
    csvファイルの仕様自体を分かっていなかったのと、既成された記号群をもてあましておりました。
    とりあえず、最適な方法かどうか分かりませんが、
    既成された記号群を後で手動で消す方法で解決と致しました。
    ご指摘ありがとうございました。参考になりました。

    キャンセル

0

10個程度であれば、現在のやり方でも許容範囲かなと思います。
表示させたくないラベルは非表示にすればいいです。
label.isHidden = true

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/11/10 15:53 編集

    ご回答ありがとうございます。
    別ページのテーブルビューのセルから値をもらって配列の行を呼び出しているのですが、問題数の数が一定でないのと、数が20〜30ぐらいの時もあり、各々 label.isHiddenの設定をすると大変なので、if文などを使って、値の有無によって表示・非表示させたいのですが・・・。

    キャンセル

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

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