I am creating an app that is retrieving data from Firebase. In my 'MealViewController' I have a TableView that has the view controller as it's delegate and data source. I am getting the issue "Type 'MealViewController" does not conform to protocol 'UITableViewDataSource' because it requires both :numberOfRowsInSection: and :cellForRowAtIndexPath: . However, when I add both, another issue appears - 'Definition conflict with previous value'. I've looked through all the Stack Overflow issues related to this, and no luck has been had. Here's my View Controller:
class MealViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
var bgImage: UIImageView?
var image : UIImage = UIImage(named: "pizza")!
@IBOutlet weak var blurEffect: UIVisualEffectView!
@IBOutlet weak var mealTableView: UITableView!
var items = [MealItem]()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
bgImage = UIImageView(image: image)
bgImage?.contentMode = .ScaleAspectFill
bgImage!.frame = view.layer.bounds
self.view.addSubview(bgImage!)
//self.bgImage?.addSubview(blurEffect)
//bgImage!.bringSubviewToFront(blurEffect)
view.bringSubviewToFront(blurEffect)
mealTableView.layer.cornerRadius = 5.0
mealTableView.layer.borderColor = UIColor.whiteColor().CGColor
mealTableView.layer.borderWidth = 0.5
let ref = Firebase(url: "https://order-template.firebaseio.com/grocery-items")
mealTableView.delegate = self
mealTableView.dataSource = self
// MARK: UIViewController Lifecycle
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
print(items.count)
return items.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> MealsCellTableViewCell { //issue occurs here
let groceryItem = items[indexPath.row]
if let cell = mealTableView.dequeueReusableCellWithIdentifier("ItemCell") as? MealsCellTableViewCell {
cell.configureCell(groceryItem)
// Determine whether the cell is checked
self.mealTableView.reloadData()
return cell
}
}
func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
// [1] Call the queryOrderedByChild function to return a reference that queries by the "completed" property
ref.observeEventType(.Value, withBlock: { snapshot in
var newItems = [MealItem]()
for item in snapshot.children {
let mealItem = MealItem(snapshot: item as! FDataSnapshot)
newItems.append(mealItem)
}
self.items = newItems
self.mealTableView.reloadData()
})
}
func viewDidDisappear(animated: Bool) {
super.viewDidDisappear(animated)
}
func willAnimateRotationToInterfaceOrientation(toInterfaceOrientation: UIInterfaceOrientation, duration: NSTimeInterval) {
}
}
override func willAnimateRotationToInterfaceOrientation(toInterfaceOrientation: UIInterfaceOrientation, duration: NSTimeInterval) {
bgImage = UIImageView(image: image)
bgImage?.contentMode = .ScaleAspectFill
bgImage!.frame = view.layer.bounds
self.view.addSubview(bgImage!)
view.bringSubviewToFront(blurEffect)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: UITableView Delegate methods
}
The cellForRowAtIndexPath should look like this:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cellIdentifier = "ItemCell"
let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! MealsCellTableViewCell
let groceryItem = self.items[indexPath.row]
cell.configureCell(groceryItem)
return cell
}
Note that the returned cell is a MealsCellTableViewCell which is a subclass of UITableViewCell so it conforms to that class.
Don't change the function definition as that will make it not conform to what the delegate protocol specifies.
Here's a link to the Apple documentation for the specific implementation of custom tableView cells for reference.
The problem is that your view controller's conformance to UITableViewDatasource cellForRowAtIndexPath
method is not right. You should refactor your implementation of cellForRowAtIndexPath
method like so:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let groceryItem = items[indexPath.row]
guard let cell = tableView.dequeueReusableCellWithIdentifier("ItemCell") as? MealsCellTableViewCell else {
fatalError("No cell with identifier: ItemCell")
}
cell.configureCell(groceryItem)
return cell
}
You also need to move the datasource methods out of viewDidLoad
method.
这是您在cellForRowAtIndexPath
方法中返回MealsCellTableViewCell
而不是UITableViewCell
的原因。
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.