UITableView:reloadRows(at :)需要两次命中才能更新表并每次滚动 [英] UITableView: reloadRows(at:) takes two hits for table to be updated and scroll every time
问题描述
我有一个表视图(控制器: MetricsViewController ),该视图从CoreData数据库进行更新。我使用了根据需要定制的原型单元( MetricsViewCell )。它包含一个分段控件,一个UIView(metricsChart,用于显示图表-animationCircle)和一些UILabel。
I have a table view (controller: MetricsViewController) which gets updated from a CoreData database. I have used prototype cells (MetricsViewCell) which I have customized for my needs. It contains a segmented control, a UIView (metricsChart, which is used to display a chart - animatedCircle), and some UILabels.
MetricsViewCell :
class MetricsViewCell: UITableViewCell {
var delegate: SelectSegmentedControl?
var animatedCircle: AnimatedCircle?
@IBOutlet weak var percentageCorrect: UILabel!
@IBOutlet weak var totalPlay: UILabel!
@IBOutlet weak var metricsChart: UIView! {
didSet {
animatedCircle = AnimatedCircle(frame: metricsChart.bounds)
}
}
@IBOutlet weak var recommendationLabel: UILabel!
@IBOutlet weak var objectType: UISegmentedControl!
@IBAction func displayObjectType(_ sender: UISegmentedControl) {
delegate?.tapped(cell: self)
}
}
protocol SelectSegmentedControl {
func tapped(cell: MetricsViewCell)
}
MetricsViewController :
class MetricsViewController: FetchedResultsTableViewController, SelectSegmentedControl {
func tapped(cell: MetricsViewCell) {
if let indexPath = tableView.indexPath(for: cell) {
tableView.reloadRows(at: [indexPath], with: .none)
}
}
var container: NSPersistentContainer? = (UIApplication.shared.delegate as? AppDelegate)?.persistentContainer { didSet { updateUI() } }
private var fetchedResultsController: NSFetchedResultsController<Object>?
private func updateUI() {
if let context = container?.viewContext {
let request: NSFetchRequest<Object> = Object.fetchRequest()
request.sortDescriptors = []
fetchedResultsController = NSFetchedResultsController<Object>(
fetchRequest: request,
managedObjectContext: context,
sectionNameKeyPath: "game.gameIndex",
cacheName: nil)
try? fetchedResultsController?.performFetch()
tableView.reloadData()
}
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Object Cell", for: indexPath)
if let object = fetchedResultsController?.object(at: indexPath) {
if let objectCell = cell as? MetricsViewCell {
objectCell.delegate = self
let request: NSFetchRequest<Object> = Object.fetchRequest()
...
...
}
}
}
return cell
}
当用户在某个节的分段控件中选择一个分段时,MetricsViewController应该在该特定行中重新加载数据。 (有两个部分,每个部分一行)。因此,我在MetricsViewCell中定义了一个协议,以通知控制器我的用户操作。
When a user selects one of the segments in a certain section's segmented control, MetricsViewController should reload the data in that particular row. (There are two sections with one row each). Hence, I've defined a protocol in MetricsViewCell to inform inform my controller on user action.
正在使用 FetchedResultsTableViewController
更新数据-它基本上充当CoreData和TableView之间的委托。一切都很好,这意味着我可以在TableView中获取正确的数据。
Data is being updated using FetchedResultsTableViewController
- which basically acts as a delegate between CoreData and TableView. Everything is fine with that, meaning I am getting the correct data into my TableView.
有两个问题:
-
我必须点按两次细分控件的细分,以重新加载点击了细分控件的行中的数据。
I have to tap segmented control's segment twice to reload the data in the row where segmented control was tapped.
表格滚动每次从分段控制中选择一个分段后,都可以上下备份。
The table scrolls back up and then down every time a segment from segmented control is selected.
非常感谢您的帮助。我在开发过程中遇到了很多问题,现在都依靠这个社区,并且已经很感激了:)
Help would be very much appreciated. I've depended on this community for a lot of issues I've faced during the development and am thankful already :)
例如,在动物识别部分,我必须点击中级两次以重新加载该行(如果您仔细观察,我第一次点击中级时,它会被选中一秒钟的时间,然后又回到基本或首先选择的任何段。第二次是当我点击中级,转到中级)。另外,该表可以上下滚动,这是我不希望的。
For example, in Animal Recognition section, I have to hit "Intermediate" two times for its row to be reloaded (If you look closely, the first time I hit Intermediate, it gets selected for a fraction of second, then it goes back to "Basic" or whatever segment was selected first. Second time when I hit intermediate, it goes to Intermediate). Plus, the table scroll up and down, which I don't want.
编辑:为我对CoreData和持久性容器的使用添加了更多上下文。
Edit: Added more context around my usage of CoreData and persistent container.
推荐答案
您的 UISegmentedControl
正在重用[UITableView的默认行为]。
Your UISegmentedControl
are reusing [Default behaviour of UITableView].
为避免这种情况,请保留 dictionary
来获取和存储值。
To avoid that, keep dictionary
for getting and storing values.
另一件事,在 UIViewController <中尝试将
出口连接作为操作
用于 UISegmentedControl
/ code>本身,而不是您的 UITableViewCell
Another thing, try outlet connection as Action
for UISegmentedControl
in UIViewController
itself, instead of your UITableViewCell
以下代码将不会在您重新加载tableview时使用点击 UISegmentedControl
。您可以避免,代表也可以打电话。
The below code will not reload your tableview when you tap UISegmentedControl
. You can avoid, delegates call too.
以下代码是 UISegmentedControl
的基本演示。根据您的需要进行自定义。
Below codes are basic demo for UISegmentedControl
. Do customise as per your need.
var segmentDict = [Int : Int]()
override func viewDidLoad() {
super.viewDidLoad()
for i in 0...29 // number of rows count
{
segmentDict[i] = 0 //DEFAULT SELECTED SEGMENTS
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! SOTableViewCell
cell.mySegment.selectedSegmentIndex = segmentDict[indexPath.row]!
cell.selectionStyle = .none
return cell
}
@IBAction func mySegmentAcn(_ sender: UISegmentedControl) {
let cellPosition = sender.convert(CGPoint.zero, to: tblVw)
let indPath = tblVw.indexPathForRow(at: cellPosition)
segmentDict[(indPath?.row)!] = sender.selectedSegmentIndex
print("Sender.tag ", indPath)
}
这篇关于UITableView:reloadRows(at :)需要两次命中才能更新表并每次滚动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!