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

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

新規登録して質問してみよう
ただいま回答率
85.35%
TableView

TableView(UITableView)とは、リスト形式で表示するコントロールで、ほとんどのアプリに使用されています。画面を「行」に分けて管理し、一般的には各行をタップした際に詳細画面に移動します。

Swift

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

Q&A

1回答

1975閲覧

【swift】TableViewCellを任意の場所までスクロールさせたい

syoco0330

総合スコア30

TableView

TableView(UITableView)とは、リスト形式で表示するコントロールで、ほとんどのアプリに使用されています。画面を「行」に分けて管理し、一般的には各行をタップした際に詳細画面に移動します。

Swift

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

0グッド

0クリップ

投稿2020/05/08 14:33

現在、日ごとに簡単な日記を保存できるカレンダーアプリを開発しています。
カレンダーの機能はFSCalendar、データベースはRealmを導入しています。
日記を付けた箇所は日付の下に青い点マークが表示されています。

実装したいことは
カレンダーの日付とTableViewの日付を連動させたいです。

詳しく説明すると
カレンダーの日付を押すと、カレンダー下にあるTableViewがTOPに来るようにスクロールさせたい
画像で説明すると、カレンダーの6を押した時に
現在、TableViewが「2020/05/02」の部分が「2020/05/06」になるようにしたい。

TableViewを上下にスクロールすると青い点マークも移動するようにしたい。
画像で説明すると、TableViewを上下させて、
TOPが「2020/05/02」の場合、5月6日が青になっているのを5月2日が青になるようにしたい。

tableView.scrollToRowで色々試してみましたが、力が及ばずでした。
どなたかご教授いただけたら幸いです。
よろしくお願いいたします。

イメージ説明

現在のソースコードがこちらになります。

swift

1 2import UIKit 3import FSCalendar 4import CalculateCalendarLogic 5import RealmSwift 6 7// ディスプレイしサイズを取得する 8let w = UIScreen.main.bounds.size.width 9let h = UIScreen.main.bounds.size.height 10 11class MainController: UIViewController,FSCalendarDelegate,FSCalendarDataSource,FSCalendarDelegateAppearance,UITableViewDelegate,UITableViewDataSource { 12 13 14 15 // スケジュール内容 16 let labelDate = UILabel(frame: CGRect(x: 5,y: 580,width: 400,height: 50)) 17 // 「主なスケジュール」の内容 18 let labelTitle = UILabel(frame: CGRect(x: 0,y: 530,width: 180,height: 50)) 19 // カレンダー部分 20 let dateView = FSCalendar(frame: CGRect(x: 0,y: 30,width: w,height: 400)) 21 // 日付の表示 22 let Date = UILabel(frame: CGRect(x: 5,y: 430,width: 200,height: 100)) 23 24 let tableView = UITableView(frame: CGRect(x: 0, y: 430, width: w, height: 400)) 25 26 override func viewDidLoad() { 27 super.viewDidLoad() 28 // カレンダーの設定 29 self.dateView.dataSource = self 30 self.dateView.delegate = self 31 self.dateView.today = nil 32 self.dateView.tintColor = .red 33 self.view.backgroundColor = .white 34 dateView.backgroundColor = .white 35 view.addSubview(dateView) 36 37 38 // スケジュール追加ボタン 39 let addBtn = UIButton(frame: CGRect(x: w - 70,y: h - 70,width: 60,height: 60)) 40 addBtn.setTitle("+", for: UIControl.State()) 41 addBtn.setTitleColor(.white, for: UIControl.State()) 42 addBtn.backgroundColor = .orange 43 addBtn.layer.cornerRadius = 30.0 44 addBtn.addTarget(self, action: #selector(onClick(_:)), for: .touchUpInside) 45 view.addSubview(addBtn) 46 47 // テーブルの設定 48 tableView.delegate = self 49 tableView.dataSource = self 50 tableView.backgroundColor = .lightText 51 tableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell") 52 view.addSubview(tableView) 53 54 // セパレータの色 55 tableView.separatorColor = .blue 56 tableView.rowHeight = 50 57 58 // 指定した日付を選択した状態にする 59 let calendar = Calendar.current 60 let selectDate = calendar.date(from: DateComponents(year: 2020, month: 5, day: 10)) 61 dateView.select(selectDate) 62 63 } 64 65 66 67 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 68 let realm = try! Realm() 69 let results = realm.objects(Event.self) 70 71 return results.count 72 } 73 74 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 75 let cell = UITableViewCell(style: .subtitle, reuseIdentifier: "Cell") 76 let realm = try! Realm() 77 let results = realm.objects(Event.self) 78 let result = results[indexPath.row] 79 80 cell.textLabel?.text = result.date 81 cell.detailTextLabel?.text = result.event 82 cell.accessoryType = .disclosureIndicator 83 84 return cell 85 } 86 87 fileprivate let gregorian: Calendar = Calendar(identifier: .gregorian) 88 fileprivate lazy var dateFotmatter: DateFormatter = { 89 let formatter = DateFormatter() 90 formatter.dateFormat = "yyyy-MM-dd" 91 return formatter 92 }() 93 94 // 祝日判定を行い結果を返すメソッド 95 func judgeHoliday(_ date : Date) -> Bool { 96 //祝日設定ようのカレンダークラスのインスタンス 97 let tmpCalendar = Calendar(identifier: .gregorian) 98 99 //祝日判定を行う日にちの年、月、日を取得 100 let year = tmpCalendar.component(.year, from: date) 101 let month = tmpCalendar.component(.month, from: date) 102 let day = tmpCalendar.component(.day, from: date) 103 104 let holiday = CalculateCalendarLogic() 105 106 return holiday.judgeJapaneseHoliday(year: year, month: month, day: day) 107 } 108 109 // date型 -> 年月日をIntで取得 110 func getDay(_ date:Date) -> (Int,Int,Int){ 111 let tmpCalender = Calendar(identifier: .gregorian) 112 let year = tmpCalender.component(.year, from: date) 113 let month = tmpCalender.component(.month, from: date) 114 let day = tmpCalender.component(.day, from: date) 115 return (year,month,day) 116 } 117 118 // 曜日判定 119 func getWeekIdx(_ date: Date) -> Int { 120 let tmpCalendar = Calendar(identifier: .gregorian) 121 return tmpCalendar.component(.weekday, from: date) 122 } 123 124 //リストの数だけ日付に点マークをつける 125 func calendar(_ calendar: FSCalendar, numberOfEventsFor date: Date) -> Int { 126 var tmpList: Results<Event>! 127 let tmpDate = Calendar(identifier: .gregorian) 128 let year = tmpDate.component(.year, from: date) 129 let month = tmpDate.component(.month, from: date) 130 let day = tmpDate.component(.day, from: date) 131 let m = String(format: "%02d", month) 132 let d = String(format: "%02d", day) 133 134 let da = "(year)/(m)/(d)" 135 136 //対象の日付が設定されているデータを取得する 137 let realm = try! Realm() 138 var result = realm.objects(Event.self) 139 result = result.filter("date = '(da)'") 140 141 if result.count >= 1 { 142 return 1 143 } else { 144 return 0 145 } 146 } 147 148 // 日の始まりと終わりを取得 149 private func getBeginingAndEndOfDay(_ date:Date) -> (begining: Date, end: Date) { 150 let begining = Calendar(identifier: .gregorian).startOfDay(for: date) 151 let end = begining + 24*60*60 152 return (begining, end) 153 } 154 155 156 @objc func onClick(_: UIButton) { 157 let storyBoard = UIStoryboard(name: "Main", bundle: nil) 158 let SecondController = storyBoard.instantiateViewController(withIdentifier: "Insert") 159 present(SecondController,animated: true, completion: nil) 160 } 161 162 //カレンダー処理(スケジュール表示処理) 163 func calendar(_ calendar: FSCalendar, didSelect date: Date, at monthPosition: FSCalendarMonthPosition) { 164 let tmpDate = Calendar(identifier: .gregorian) 165 let year = tmpDate.component(.year, from: date) 166 let month = tmpDate.component(.month, from: date) 167 let day = tmpDate.component(.day, from: date) 168 let m = String(format: "%02d", month) 169 let d = String(format: "%02d", day) 170 let da = "(year)/(m)/(d)" 171 172 let realm = try! Realm() 173 let results = realm.objects(Event.self).filter("date = '(da)'") 174 if results.count != 0 { 175 let result = results[0].date 176 } 177 } 178} 179 180

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

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

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

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

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

guest

回答1

0

FSCalendarはほとんど使ったことがありませんが、こんな感じでいかがでしょうか。

・カレンダーの日付を押すと、カレンダー下にあるTableViewがTOPに来るようにスクロールさせたい。

指定した IndexPath がトップに来るようにするにはこんな感じでしょうか。

scrollToRowはお試しになったということですが、もしかしたら TableView の再描画と重なったのかもしれません。

メインキューに追加するとうまく行くかもしれませんが、いかがでしょうか。

swift

1 let indexPath = IndexPath(row: 10, section: 0) 2 DispatchQueue.main.async { 3 self.tableView.scrollToRow(at: indexPath, at: .top, animated: true) 4 }

・TableViewを上下にスクロールすると青い点マークも移動するようにしたい。

良いコードとは思えませんが、新しいセルが表示される時のdelegate内で表示されているセルの[IndexPath]を取得し、そのトップから一番上のセルを推測するとなるとこんな感じでしょうか。

あとは、FSCalendar のメソッドを用いて指定した日付に飛べば良さそうな感じがします。

ただし、セルの描画が行われるたびにこのメソッドは呼び出されるため、セルがViewに表示された時にはセルの数だけ呼び出しがかかってしまいますのでもう一工夫必要かもしれません。

また、必ずしも見た目の最上位のセルとtableView.indexPathsForVisibleRows?.first?.rowの値が一致しないこともあるようです。たとえば、ごくわずかにでも直前のセルが表示されていれば、得られる値はその行になってしまうため、こちらも工夫が必要かもしれません。

swift

1 func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) { 2 if let row = tableView.indexPathsForVisibleRows?.first?.row { 3 label.text = "トップのセル番号: (row + 1)" 4 } 5 }

投稿2020/05/08 15:55

TsukubaDepot

総合スコア5086

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

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

SadajiroOkuno

2020/08/29 08:45

syoco0330さん  トピックの外から失礼します。 勝手に高評価してすいません。 TsukubaDepotさん 同じ悩みでしたのでこちらの回答で同期できました!ありがとございます!!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問