もう数日間ずっと調べても解決方法が見いだせなかったので質問させていただきます。
TableViewのSectionを開閉できるようにしているのですが、そのときのアニメーションがとてもキレイとは言えないおかしな挙動をしてしまいます。
無知なりに数日間ずっと解決法を調べて試してみましたが解決に至りませんでした。
どうかアドバイスを頂けないでしょうか?
ちなみにHeaderは複数のラベルなどを設置しているカスタムHeaderです。
必要と思われる部分のコードを抜き出しました。
Swift
1override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 2 3 return taskItems[section].isOpen ? taskItems[section].details.count : 0 4} 5 6// Sectionがタップされたときの処理 7@objc func sectionTapAction(_ sender: UIGestureRecognizer) { 8 if let section = sender.view?.tag { 9 10 taskItems[section].taskName = taskItems[section].details[0] 11 selectedSectionIndex = section 12 self.taskItems[self.selectedSectionIndex].isOpen = !self.taskItems[self.selectedSectionIndex].isOpen 13 self.tableView.reloadSections(IndexSet(integer: self.selectedSectionIndex) , with: .automatic) 14 15 } 16 }
追記
頂いた回答を踏まえて、TableView.reloadSectionsを
TableView.insertRowsおよびTableView.deleteRowsに変更してみました。
しかしまだおかしな挙動は改善されませんでした。
Swift
1// Sectionがタップされたときの処理 2@objc func sectionTapAction(_ sender: UIGestureRecognizer) { 3 if let section = sender.view?.tag { 4 5 taskItems[section].taskName = taskItems[section].details[0] 6 selectedSectionIndex = section 7 self.taskItems[self.selectedSectionIndex].isOpen = !self.taskItems[self.selectedSectionIndex].isOpen 8 9 var indexPaths = [IndexPath]() 10 for row in taskItems[section].details.indices { 11 let indexPath = IndexPath(row: row, section: section) 12 indexPaths.append(indexPath) 13 } 14 15 16 17 18 if taskItems[selectedSectionIndex].isOpen { 19 tableView.insertRows(at: indexPaths, with: .none) 20 tableView.endUpdates() 21 22 }else { 23 tableView.deleteRows(at: indexPaths, with: .none) 24 tableView.endUpdates() 25 } 26 } 27 }
追記
SectionのViewを返すviewForHeaderInSectionメソッドの中身を追加させていただきます。
Swift
1override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { 2 let sectionView = UIView(frame:CGRect(x: 0,y: 0,width: 0,height: 0)) 3 4 5 6 let vividColors = ["FF7F3B","FF96D7","FF279F","BE00E8","5A2199","2D23D2","FF433B","3DB2FA"] 7 8 9 sectionView.backgroundColor = UIColor(hex: vividColors[Int.random(in: 0..<vividColors.count)]) 10 11 12 let dateLabel = UILabel(frame:CGRect(x: 50,y: 10,width: self.view.frame.width - 100 ,height: 20)) 13 dateLabel.font = UIFont.boldSystemFont(ofSize: 20) 14 dateLabel.textColor = .white 15 16 17 var repeatIconImageView: UIImageView = UIImageView() 18 if taskItems[section].details[2] != "なし" { 19 dateLabel.frame = CGRect(x: 70,y: 10,width: self.view.frame.width - 100 ,height: 20) 20 repeatIconImageView = UIImageView(frame: CGRect(x: 50,y: 13,width: 15 ,height: 15)) 21 repeatIconImageView.image = UIImage(named: "repeat") 22 }else { 23 repeatIconImageView = UIImageView(frame: CGRect(x: 50,y: 10,width: 0 ,height: 0)) 24 } 25 26 27 if taskItems[section].details[1] != "なし" { 28 let a = taskItems[section].details[1].replace("年", "/") 29 let b = a.replace("月", "/") 30 let c = b.replace("日", "") 31 32 let formatter = DateFormatter() 33 formatter.locale = Locale(identifier: "ja_JP") 34 formatter.dateFormat = "yyyy/MM/dd HH:mm" 35 let date = formatter.date(from: c) 36 let calendar = Calendar.current 37 38 39 let isSameDate = calendar.isDate(date!, inSameDayAs: Date()) 40 let isTomorrow = calendar.isDate(date!, inSameDayAs: calendar.date(byAdding: .day, value: 1, to: calendar.startOfDay(for: Date()))!) 41 let isDayAfterTomorrow = calendar.isDate(date!, inSameDayAs: calendar.date(byAdding: .day, value: 2, to: calendar.startOfDay(for: Date()))!) 42 43 if isSameDate { 44 formatter.dateFormat = "今日 HH:mm" 45 dateLabel.text = formatter.string(from: date!) 46 }else if isTomorrow { 47 formatter.dateFormat = "明日 HH:mm" 48 dateLabel.text = formatter.string(from: date!) 49 }else if isDayAfterTomorrow { 50 formatter.dateFormat = "明後日 HH:mm" 51 dateLabel.text = formatter.string(from: date!) 52 }else { 53 dateLabel.text = taskItems[section].details[1] 54 } 55 56 if date! < Date() { 57 dateLabel.textColor = .red 58 sectionView.backgroundColor = .quaternaryLabel 59 60 dateLabel.text! += " 【超過!!】" 61 62 } 63 64 }else { 65 dateLabel.text = "日時設定なし" 66 } 67 68 69 sectionView.tag = section 70 var sectionTitle: UILabel! 71 sectionTitle = UILabel(frame:CGRect(x: 50,y: 40,width: self.view.frame.width - 100 ,height: 20)) 72 sectionTitle.font = UIFont.boldSystemFont(ofSize: 18) 73 sectionTitle.text = taskItems[section].taskName 74 sectionTitle.textColor = .white 75 sectionTitle.numberOfLines = 0 76 sectionTitle.sizeToFit() 77 78 // let tickBtn = UIButton(frame: CGRect(x: 10,y: sectionTitle.frame.maxY - 15,width: 30 ,height: 30)) 79 let tickBtn = UIButton(frame: CGRect(x: 10,y: 10,width: 30 ,height: 30)) 80 tickBtn.setImage(UIImage(named: taskItems[section].isComplete ? "interfaces" : "done"), for: .normal) 81 tickBtn.tag = section 82 tickBtn.addTarget(self, action: #selector(self.tickBtnAction(_:)), for: .touchDown) 83 84 let priorityLabel: UILabel = UILabel() 85 if taskItems[section].details[5] != "なし" { 86 priorityLabel.textColor = .systemBlue 87 priorityLabel.textAlignment = .center 88 priorityLabel.frame = CGRect(x: 50, y: 40, width: 15, height: 15) 89 sectionTitle.frame = CGRect(x: 70,y: 40,width: self.view.frame.width - 100 ,height: 20) 90 sectionTitle.sizeToFit() 91 92 93 switch taskItems[section].details[5] { 94 case "低": 95 priorityLabel.text = "!" 96 case "中": 97 priorityLabel.text = "!!" 98 case "高": 99 priorityLabel.text = "!!!" 100 default: break 101 } 102 priorityLabel.sizeToFit() 103 }else { 104 priorityLabel.frame = CGRect(x: 50, y: 50, width: 0, height: 0) 105 } 106 107 108 sectionView.layer.cornerRadius = 15 109 110 let memoLabel = UILabel() 111 if taskItems[section].details[3] != "" { 112 113 memoLabel.frame = CGRect(x: 50,y: (sectionTitle.frame.maxY + 10),width: self.view.frame.width - 100 ,height: 50) 114 memoLabel.numberOfLines = 0 115 memoLabel.font = UIFont.boldSystemFont(ofSize: 15) 116 memoLabel.textColor = .white 117 memoLabel.text = taskItems[section].details[3] 118 memoLabel.sizeToFit() 119 }else { 120 memoLabel.frame = CGRect(x: 50,y: sectionTitle.frame.maxY,width: 0 ,height: 0) 121 } 122 123 let urlBtn = UIButton(type: .system) 124 if taskItems[section].details[4] != "" { 125 urlBtn.frame = CGRect(x: 50,y: memoLabel.frame.maxY,width: self.view.frame.width - 100 ,height: 20) 126 urlBtn.tag = section 127 urlBtn.titleLabel!.font = UIFont.boldSystemFont(ofSize: 15) 128 urlBtn.contentHorizontalAlignment = .left 129 urlBtn.addTarget(self, action: #selector(self.urlBtnAction(_:)), for: .touchDown) 130 131 if let component: NSURLComponents = NSURLComponents(string: taskItems[section].details[4]) { 132 urlBtn.setTitle(component.host ?? taskItems[section].details[4], for: .normal) 133 } 134 urlBtn.sizeToFit() 135 }else { 136 urlBtn.frame = CGRect(x: 50,y: memoLabel.frame.maxY,width: 0 ,height: 10) 137 } 138 139 140 //セクションにタップジェスチャーを追加 141 sectionView.addGestureRecognizer(UITapGestureRecognizer(target: self,action:#selector(sectionTapAction(_:)))) 142 sectionView.addGestureRecognizer(UILongPressGestureRecognizer(target: self, action: #selector(sectionLongTapAction(_:)))) 143 sectionView.addSubview(tickBtn) 144 sectionView.addSubview(dateLabel) 145 sectionView.addSubview(sectionTitle) 146 sectionView.addSubview(memoLabel) 147 sectionView.addSubview(repeatIconImageView) 148 sectionView.addSubview(priorityLabel) 149 sectionView.addSubview(urlBtn) 150 151 152 153 urlBtn.bottomAnchor.constraint(equalTo: sectionView.bottomAnchor, constant: 0).isActive = true 154 155 156 return sectionView 157 }
Sectionをタップしたときにコンソールに表示されるメッセージ
不正な制約という内容のメッセージですが、もしかするとこれが関係ありそうな気がしています。
[LayoutConstraints] Unable to simultaneously satisfy constraints. Probably at least one of the constraints in the following list is one you don't want. ~~~省略~~~
reloadSectionsの挙動
insertRowsおよびdeleteRowsの挙動
回答1件
あなたの回答
tips
プレビュー