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

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

ただいまの
回答率

87.58%

[Swift]昇順表示した開始時刻の配列にセットで終了時刻とタイトルも表示させる方法

受付中

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 1,768

score 37

言葉にするのが難しく、分かりづらい質問になってしまうと思います。
現在、スケジュールアプリを作成しております。
そこで、ユーザーが指定した「タイトル」「開始時刻」「終了時刻」をtableviewcellに表示させたいと思っています。

その際に「開始時刻」のみを昇順にし、「開始時刻」にセットで「終了時刻」と「タイトル」も付随させたいのですが、
開始時刻のみが昇順表示になるため、「タイトル」と「終了時刻」は登録した順番に表示されてしまいます。

SimulatorのScreenShotを添付いたします。
登録した順番
開始時刻:2:00 終了時刻:2:00 タイトル:2
開始時刻:1:00 終了時刻:1:00 タイトル:2

実現したい順番
開始時刻:1:00 終了時刻:1:00 タイトル:2
開始時刻:2:00 終了時刻:2:00 タイトル:1

イメージ説明

下記にcellForRowAt内の現在のコードを記します。
その他に確認が必要な箇所のコードがありましたら、お申し付けください。
ご教示のほど、お願い申しあげます。

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! TableViewCell

func dateString(date: NSDate) -> String {
let dateFormatter = DateFormatter()
dateFormatter.calendar = NSCalendar(calendarIdentifier: NSCalendar.Identifier.gregorian)! as Calendar!
dateFormatter.locale = NSLocale.system
dateFormatter.timeZone = NSTimeZone.system
dateFormatter.dateFormat = "H:mm"
let dateString: String = dateFormatter.string(from: date as Date)
return dateString
}

let sortArray = dateArray1.sorted { $0 < $1 }

strBox.append(dateString(date: sortArray[indexPath.row] as NSDate))
strBox2.append(dateString(date: dateArray2[indexPath.row] as NSDate))
dateInStr = dateString(date: sortArray[indexPath.row] as NSDate)
dateInStr2 = dateString(date: dateArray2[indexPath.row] as NSDate)

strCount = dateInStr.characters.count
strCount2 = dateInStr2.characters.count

if strCount < 5 {

timeLabelText1 = " " + strBox[indexPath.row]! + "  "

} else {

timeLabelText1 = strBox[indexPath.row]! + "  "

}

if strCount2 < 5 {

timeLabelText2 = "   " + strBox2[indexPath.row]!

} else {

timeLabelText2 = "  " + strBox2[indexPath.row]!

}

let attrText = NSMutableAttributedString(string: timeLabelText1 + ">>>" + timeLabelText2)
attrText.addAttribute(NSForegroundColorAttributeName,
value: UIColor.red,
range: NSMakeRange(7, 3))

attrText.addAttribute(NSForegroundColorAttributeName,
value: UIColor.white,
range: NSMakeRange(0, 5))
attrText.addAttribute(NSForegroundColorAttributeName,
value: UIColor.white,
range: NSMakeRange(12, 5))

cell.timeLabel?.attributedText = attrText

cell.titleLabel?.text = "   " + titleArray[indexPath.row]!

// 枠のカラー
cell.titleLabel.layer.borderColor = UIColor.darkGray.cgColor

// 枠の幅
cell.titleLabel.layer.borderWidth = 1.0

// 枠を角丸にする
cell.titleLabel.layer.cornerRadius = 10.0
cell.titleLabel.layer.masksToBounds = true

return cell

}

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

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

  • fuzzball

    2017/05/22 08:49

    コードは ``` で囲って下さい。

    キャンセル

回答 2

+1

3つのデータを一纏めにしましょう。
ArrayでもDictionaryでもタプルでもいいです。

タプルを使ったサンプルです。

let array = [
    ("1", "5", "first"),
    ("8", "9", "fifth"),
    ("4", "5", "third"),
    ("6", "8", "fourth"),
    ("2", "7", "second"),
]

let sorted = array.sorted {$0.0 < $1.0}
sorted.forEach {
    print("start:\($0.0) end:\($0.1) title:\($0.2)")
}

出力

start:1 end:5 title:first
start:2 end:7 title:second
start:4 end:5 title:third
start:6 end:8 title:fourth
start:8 end:9 title:fifth

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

0

解決方法:
各個別データを1つの構造体、クラスなどのオブジェクトとしてデータを保持する

現象理由:
表示する各データのデータ構造に関連性が無いため

色々情報が不足しているので、こちらで読み取った内容で記載します。
過不足あればご指摘ください。また、swift構文は私ほとんど知らないため、
構文ミスなどは適宜読み替えてください。
あとこのメソッドは恐らく呼び出し元がループ処理となっていると想定されるため
当該メソッド内でソートすると、スケジュール作成ごとにソート処理されるため無駄
処理かと。

titleArray:タイトルが保持されている
dateArray1:開始時間が保持されている
dateArray2:終了時間が保持されている

let sortArray = dateArray1.sorted { $0 < $1 }

上記のコードで「開始時間」のソートを行う。行った時点で、dateArray1が昇順で
ソートされる。
だがしかし、この時点においてソート前の各データの関連性が消失する。
例)以下のようにデータがあるとする時

titleArray:["2番目のデータです","1番目のデータです"]
dateArray1:["2:00","1:00"]
dateArray2:["2:00","1:00"]

dateArray1をソートすると

titleArray:["2番目のデータです","1番目のデータです"]
dateArray1:["1:00","2:00"]// 昇順データ
dateArray2:["2:00","1:00"]

この時点で、dateArray1の情報とほかのtitleArrayとdateArray2の情報の関連性
がなくなってしまう。なくなった状態で

strBox.append(dateString(date: sortArray[indexPath.row] as NSDate)) 
strBox2.append(dateString(date: dateArray2[indexPath.row] as NSDate)) 

cell.titleLabel?.text = "   " + titleArray[indexPath.row]!

と行ってしまえば実質的に各々のデータが昇順なったデータとそうではない順番の
データが混在することになってしまう。
よって、各データを1つのデータ構造として利用する
※今回はデータの利用内容などが不明慮なため、構造体として保持

/* 表示データ */
struct ScheduleData{
    // スケジュールのコメント
    var title: String = ""
    // スケジュールの開始時間
    var startDate: date!
    // スケジュールの終了時間
    var endDate: date!

    init(title : String , startDate : Date , endDate : Date){
       self.title = title
       self.startDate = startDate 
       self.endDate = endDate 
    }
}
// データ作成
var schedules = [ScheduleData]()
// startとendの各DATEには適切な時間を代入してください
schedules.append(ScheduleData(title : "1番目のデータです", startDate : Date() , endDate : Date()))
// startとendの各DATEには適切な時間を代入してください
schedules.append(ScheduleData(title : "2番目のデータです", startDate : Date() , endDate : Date()))

// tableViewの呼び出し元
// スケジュールのソート
var sortedSchedules = schedules.sorted(by: { $0.startDate>$1.startDate})
let count = sortedSchedules.count
for i in 0..<count{
   var cell = tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath)
}

// 実装例
// IndexPathではなく、上記呼び出しもとで構造体を渡してもいいと思いますが。
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! TableViewCell

func dateString(date: NSDate) -> String { 
let dateFormatter = DateFormatter() 
dateFormatter.calendar = NSCalendar(calendarIdentifier: NSCalendar.Identifier.gregorian)! as Calendar! 
dateFormatter.locale = NSLocale.system 
dateFormatter.timeZone = NSTimeZone.system 
dateFormatter.dateFormat = "H:mm" 
let dateString: String = dateFormatter.string(from: date as Date) 
return dateString 
}

// ソートは終わってるのでソートしない
// let sortArray = dateArray1.sorted { $0 < $1 }

dateInStr = dateString(date: sortedSchedules[indexPath.row].startDate as NSDate)
dateInStr2 = dateString(date: sortedSchedules[indexPath.row].endDate as NSDate)
strBox.append(dateInStr) 
strBox2.append(dateInStr2) 


timeLabelText1 = dateStrFormat(dateInStr) + "  "
timeLabelText2 = "  " + dateStrFormat(dateInStr2) 


let attrText = NSMutableAttributedString(string: timeLabelText1 + ">>>" + timeLabelText2) 
attrText.addAttribute(NSForegroundColorAttributeName, 
value: UIColor.red, 
range: NSMakeRange(7, 3))

attrText.addAttribute(NSForegroundColorAttributeName, 
value: UIColor.white, 
range: NSMakeRange(0, 5)) 
attrText.addAttribute(NSForegroundColorAttributeName, 
value: UIColor.white, 
range: NSMakeRange(12, 5))

cell.timeLabel?.attributedText = attrText

cell.titleLabel?.text = "  " + sortedSchedules[indexPath.row].title 

// 枠のカラー 
cell.titleLabel.layer.borderColor = UIColor.darkGray.cgColor

// 枠の幅 
cell.titleLabel.layer.borderWidth = 1.0

// 枠を角丸にする 
cell.titleLabel.layer.cornerRadius = 10.0 
cell.titleLabel.layer.masksToBounds = true

return cell

}

func dateStrFormat(_ dateStr :String)-> String{
 var strCount = dateStr.characters.count 
 var PADDING_STRING_COUNT = 5
if strCount  < PADDING_STRING_COUNT {
  return " " + dateStr!
}
 return dateStr!
}

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/05/22 18:10

    ご回答有り難うございます。

    // tableViewの呼び出し元
    // スケジュールのソート
    var sortedSchedules = schedules.sorted(by: { $0.startDate>$1.startDate})
    let count = sortedSchedules.count
    for i in 0..<count{
    var cell = tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath)}
    こちらはどこに書けばいいのでしょうか?

    キャンセル

  • 2017/05/23 16:52

    nishipさん

    nishipさんのコードの全容がわからないので、どこに書くかと言われても困ります。
    nishipさんのコードの中で、tableViewメソッドを呼び出しているメソッドがあるのではないでしょうか?tableViewメソッドを呼び出している元のメソッド内で処理することになります

    キャンセル

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

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

関連した質問

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