2016-04-23 10 views
-1

Firebaseからデータを取得しているアプリケーションを作成しています。私の 'MealViewController'では、ViewControllerを持つTableViewをデリゲートとデータソースとして持っています。 "Type 'MealViewController"という問題がプロトコル' UITableViewDataSource 'に準拠していません。なぜなら、numberOfRowsInSection:と:cellForRowAtIndexPath:の両方が必要なためです。しかし、両方を追加すると、「以前の値との定義の競合」という別の問題が発生します。私はこれに関連するすべてのスタックオーバーフローの問題を見てきました。cellForRowAtIndexPathとnumberOfRowsInSectionがtableViewで競合しています

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 






} 
+0

このエラーがどの行に表示されるのかを示してください。たぶんテーブルビューとは無関係かもしれません。 –

+0

最初の問題はclassステートメントであり、編集してマークした2番目のものはcellForRowAtIndexPathにあります –

+0

ああ、ちょうどあなたのdataSourceメソッドが実際にネストされていることに気づきました:)したがって、 'cellForRowAtIndexPath'はローカル関数です。 'viewDidLoad'の外側にあります。 'viewDidLoad'からネストされた関数をすべて移動する必要があります。 –

答えて

2

cellForRowAtIndexPathは次のようになります。返されたセルは、それがそのクラスに準拠してのUITableViewCellのサブクラスであるMealsCellTableViewCellであることを

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 
} 

注意。

関数定義を変更しないでください。関数定義は、デリゲートプロトコルで指定されているものと一致しないため、変更しないでください。

参考のために、カスタムtableViewセルの特定の実装に関するAppleのマニュアルへのリンクがあります。

Create a Table View

1

問題はあなたのビューコントローラの適合がcellForRowAtIndexPath方法は適切ではないUITableViewDatasourceするということである。ここに私のビューコントローラです。あなたはそのようcellForRowAtIndexPathメソッドの実装をリファクタリングする必要があります

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 
} 

ます。またviewDidLoad方法のうち、データソースのメソッドを移動する必要があります。

+0

mealTableViewデリゲートがviewDidLoad()から "Expected declaration"の問題よりも移動された場合。実装を変更した後でも、プロトコルのdataSourceに準拠していないという問題があります。また、「 'MealsCellTableViewCell'型の戻り式を 'UITableView'型に変換できません」という新しい問題があります。 –

0

UITableViewCellの代わりにMealsCellTableViewCellを返すのは、その理由です。その理由は、cellForRowAtIndexPathです。

+0

「 ' 'であり、クラスとの不適合がまだ存在しています –

+0

@JohnHarding MealsCellTableViewCellがUITableViewCellである限り、UITableViewCellの型であるため、メソッドから返すことは問題ありません。これは一般的な方法です。しかし、あなたの関数定義は、MealsCellTableViewCellの代わりにUITableViewCellを返す必要があります。 – Jay

関連する問題