点击/ reloadData不更改单元格时TableView单元格消失?
Posted
技术标签:
【中文标题】点击/ reloadData不更改单元格时TableView单元格消失?【英文标题】:TableView cells disappearing when tapped / reloadData not changing cells? 【发布时间】:2018-12-29 22:08:21 【问题描述】:我的 TableView 有两个问题;第一个是每当一个单元格被点击时,它就会消失。单元格的内容视图逐渐消失,并在上下单元格之间留下空隙。我的 didSelect 中没有任何东西可以操纵内容视图。
第二个问题是 reloadData 实际上并没有更新 TableView 的数据。我的 TableView 应该代表一个日历,并且每当调用第二天或前一天按钮(下面代码中的nextDay()
和prevDay()
)时,displayDay
int 就会更改并调用tableView.reloadData()
。 cellForRowAt
依赖于displayDay
来确定应该在单元格中显示哪一天的事件,因此理论上更改displayDay
会更改单元格的内容。然而,相反,每当按下第二天或前一天的按钮时,单元格的内容根本不会改变(即,它仍然显示第一天的事件)。唯一改变的是如果第一天的事件少于第二天,例如,如果第一天有 3 个事件,第二天有 5 个,表格视图将在第一天的底部显示第二天的最后 2 个事件当天的活动。我的代码在下面
import UIKit
import Foundation
import Alamofire
import SwiftyJSON
class ScheduleTableViewController: UITableViewController
var schedule: [DayItem]
var displayDay: Int
var numDays: Int?
@IBOutlet weak var prevDayButton: UIBarButtonItem!
@IBOutlet weak var nextDayButton: UIBarButtonItem!
override func viewDidLoad()
super.viewDidLoad()
// Uncomment the following line to preserve selection between presentations
// self.clearsSelectionOnViewWillAppear = false
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem
//schedule = scrapeSchedule()
// let add = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: nil)//action: #selector(addTapped))
// navigationController!.toolbarItems = [add]
let rightSwipe = UISwipeGestureRecognizer(target: self, action: #selector(handleSwipes(_:)))
rightSwipe.direction = .right
view.addGestureRecognizer(rightSwipe)
let leftSwipe = UISwipeGestureRecognizer(target: self, action: #selector(handleSwipes(_:)))
leftSwipe.direction = .left
view.addGestureRecognizer(leftSwipe)
required init?(coder aDecoder: NSCoder)
self.displayDay = 0
self.schedule = [DayItem]()
self.numDays = 0
super.init(coder: aDecoder)
refresh(self)
@objc func handleSwipes(_ sender: UISwipeGestureRecognizer)
if sender.direction == .right
if prevDayButton.isEnabled
prevDay(self)
else
dismiss(animated: true, completion: nil)
else if sender.direction == .left
if nextDayButton.isEnabled
nextDay(self)
func reloadData()
tableView.reloadData()
if schedule.count != 0
self.navigationItem.title = self.schedule[self.displayDay].day
func configureDayButtons()
if schedule.count == 0
prevDayButton.isEnabled = false
nextDayButton.isEnabled = false
else
prevDayButton.isEnabled = true
nextDayButton.isEnabled = true
if displayDay == 0
prevDayButton.isEnabled = false
if displayDay == numDays! - 1
nextDayButton.isEnabled = false
@IBAction func prevDay(_ sender: Any)
if displayDay != 0
displayDay -= 1
configureDayButtons()
reloadData()
@IBAction func nextDay(_ sender: Any)
if displayDay != numDays! - 1
displayDay += 1
configureDayButtons()
reloadData()
override func didReceiveMemoryWarning()
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
override func numberOfSections(in tableView: UITableView) -> Int
// #warning Incomplete implementation, return the number of sections
return 1
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
// #warning Incomplete implementation, return the number of rows
if schedule.count != 0
return schedule[displayDay].events.count
else
return 0
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
let dayItem = schedule[displayDay]
print("display day = \(displayDay)")
let eventItem = dayItem.events[indexPath.row]
let identifier = eventItem.identifier
let eventOrTimeText = eventItem.event
let cell = tableView.dequeueReusableCell(withIdentifier: identifier, for: indexPath)
let label = cell.viewWithTag(1000) as! UILabel
label.text = eventOrTimeText
if identifier == "event" || identifier == "eventDDI"
label.adjustsFontSizeToFitWidth = true
else if identifier == "time" || identifier == "location"
label.sizeToFit()
return UITableViewCell()
override func tableView(_ tableView: UITableView, accessoryButtonTappedForRowWith indexPath: IndexPath)
self.tableView(self.tableView, didSelectRowAt: indexPath)
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
tableView.deselectRow(at: indexPath, animated: true)
if schedule[displayDay].events[indexPath.row].information != nil
let message = schedule[displayDay].events[indexPath.row].information
let alert = UIAlertController(title: schedule[displayDay].events[indexPath.row].event, message: message, preferredStyle: .alert)
let action = UIAlertAction(title: "Close", style: .default, handler: nil)
alert.addAction(action)
present(alert, animated: true, completion: nil)
@IBAction func close(_ sender: Any)
dismiss(animated: true, completion: nil)
@IBAction func refresh(_ sender: Any)
scrapeSchedule schedule in
self.schedule = schedule!
DispatchQueue.main.async
self.reloadData()
self.numDays = self.schedule.count
self.configureDayButtons()
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
// if schedule.
if schedule.count != 0
let event = schedule[displayDay].events[indexPath.row]
if event.identifier == "time" && event.event.count > 51
return 75
else if event.identifier == "time" && event.event.count > 31
let additionalChars = event.event.count - 31
var quotient: Float = Float(additionalChars) / 20.0
quotient = quotient.rounded(.up)
return CGFloat(quotient * 14 + 40)
return 34
func scrapeSchedule(completion: @escaping ([DayItem]?) -> Void)
var schedule = [DayItem]()
URLCache.shared.removeAllCachedResponses()
Alamofire.request("my api that functions correctly", method: .get).validate().responseData response in
switch response.result
case .success(let data):
do
let json = try JSON(data: data)
for (index,day):(String, JSON) in json
schedule.append(self.organizeScheduleJSON(dayJSON: day))
completion(schedule)
catch
completion(nil)
case .failure(let error):
print(error.localizedDescription)
completion(nil)
func organizeScheduleJSON(dayJSON: JSON) -> DayItem
var events = [EventItem]()
for (index,event):(String, JSON) in dayJSON["eventTimes"]
if event["information"] != nil
events.append(EventItem(event: event["event"].string!, identifier: "eventDDI", information: event["information"].string!))
else
events.append(EventItem(event: event["event"].string!, identifier: "event"))
if event["location"] != nil
events.append(EventItem(event: event["location"].string!, identifier: "location"))
if event["times"] != nil
var timeArray = event["times"].arrayValue.map($0.stringValue)
for time in timeArray
events.append(EventItem(event: time, identifier: "time"))
return DayItem(day: dayJSON["day"].string!, events: events)
【问题讨论】:
您的cellForRow(at:)
看起来不正确。它总是return UITableViewCell()
而不是你配置的cell
。
解决了它...不知道我是怎么错过的。谢谢!
【参考方案1】:
您的cellForRow(at:)
始终返回一个空的UITableViewCell
,而不是您配置的cell
对象。
将return UITableViewCell()
替换为return cell
【讨论】:
以上是关于点击/ reloadData不更改单元格时TableView单元格消失?的主要内容,如果未能解决你的问题,请参考以下文章
使用自我调整大小的单元格后,reloadData 不再起作用