0

I am attempting to use CoreData variables for most of my app code but have not been able to use them for the names of custom classes. Here is an example of my code:

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> CREWWorkCell {
    let cell = tableView.dequeueReusableCellWithIdentifier(cellName) as! CREWWorkCell

I want to use a string for CREWWorkCell. Is this possible?

holex
  • 23,961
  • 7
  • 62
  • 76
PatriciaW
  • 893
  • 1
  • 12
  • 30

1 Answers1

1

UITableViewController doesn't have a function that returns CREWWorkCell that you could override. Use the default UITableViewCell as a return value and everything would work fine with custom cells.

In your UITableViewController class use the following function:

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { // Note that the return value is UITableViewCell and not CREWWorkCell

        //get the class name from the database and put it in a variable called myClassName. Then 

        if myClassName == "CREWWorkCell" {
            let cell : CREWWorkCell = tableView.dequeueReusableCellWithIdentifier("cell identifier 1", forIndexPath: indexPath) as! CREWWorkCell //of course you should cast to your custom class to be able to use it
            return cell
        } else if myClassName == "AnotherCellClass" {
            let cell : AnotherCellClass = tableView.dequeueReusableCellWithIdentifier("cell identifier 2", forIndexPath: indexPath) as! AnotherCellClass
            return cell
        }

        //do the same if you have other custom classes etc...

        return UITableViewCell()
    }

With Swift you can't cast to a dynamic type (have a look here). Therefore, you can't cast to a Type that you put in a variable using for example :

var myClassName = CREWWorkCell.self

or

var myClassName = CREWWorkCell().dynamicType

because myClassName would be evaluated at runtime, in other words it is a dynamic type. But the casting operator expects a its right hand side a static type, a type that is already known and doesn't need to be evaluated at runtime. This feature allows Swift to enforce type safety.

I would suggest you to rethink the way you create custom cells, in a much simpler way.

Community
  • 1
  • 1
ielyamani
  • 17,807
  • 10
  • 55
  • 90
  • Since I need to use custom classes for the cells I don't see how I can do that. – PatriciaW Aug 08 '15 at 16:20
  • CREWWorkCell is already a subclass of UITableViewCell. it works just fine – ielyamani Aug 08 '15 at 16:23
  • If I have multiple subclasses how do I specify which one to use? The objects in each cell are specified in them. – PatriciaW Aug 08 '15 at 16:28
  • you'll have to rely on `indexPath.row` to set the class – ielyamani Aug 08 '15 at 16:30
  • I still do not understand ... I'd really appreciate it if you would provide an example. – PatriciaW Aug 08 '15 at 17:02
  • you can have a look here https://www.weheartswift.com/swifting-around/ , here https://youtu.be/adP2dG_C1XU , here https://youtu.be/JG_AMY_gSDQ – ielyamani Aug 08 '15 at 17:48
  • I've looked there but the statement "var cell:CustomTableViewCell = self.tableView.dequeueReusableCellWithIdentifier("customCell") as CustomTableViewCell' uses the Custom cell class name and I can't find an example where it doesn't. Am I missing something? – PatriciaW Aug 08 '15 at 18:31
  • Casting to your custom class is the way to go. But don't use your custom class name as the return value of that function. – ielyamani Aug 08 '15 at 18:34
  • I am not an expert in this area so are you disagreeing with my understanding that I MUST use my custom cell class name when I dequeue ...? I don't see any way to use a variable. Should we move this to chat? – PatriciaW Aug 08 '15 at 18:42
  • I am able to use it without having to cast it to anything. But even if I did that does not address my original question. Thanks for your help. – PatriciaW Aug 08 '15 at 20:33
  • what I want to do is have a var className = "CREWWorkCell" and then use something like this: let cell : className = tableView.dequeueReusableCellWithIdentifier("cell identifier 1", forIndexPath: indexPath) as! className – PatriciaW Aug 11 '15 at 18:53
  • I really appreciate the effort you have put into this but I don't think that you have addressed my question. I want to be able to store the name of the class into the database and then use that value for the custom cell class name. What I want is to store all of the values that control the view in the database - get them when the view is loaded (using the viewname as the key). As far as I can see, your solution doesn't use a string to store the class name which is what I want. – PatriciaW Aug 12 '15 at 03:23
  • I see, I've added some lines that could be of help. – ielyamani Aug 12 '15 at 20:16
  • @Carpens90 We are on the same wavelength now. Since I haven't used a dictionary before, I have some testing to do but many, many thanks. I'll let you know if/when I get it working. – PatriciaW Aug 12 '15 at 21:27
  • Ok .... tried this out but, unless I misunderstand what you are saying, all that happens is that I get an error that className is not a type. – PatriciaW Aug 12 '15 at 22:36
  • Yes that was complicated. Try the simpler solution given above – ielyamani Aug 13 '15 at 00:40
  • Let's agree that it is not possible to do what I want to do. I understand now that it is not the way that classes work and that my original question was based on the wrong premise. Your solutions all involve hard coding the class name ... which is not what I want to do. – PatriciaW Aug 13 '15 at 01:41
  • My definitive answer is up. I hope it's clear enough. – ielyamani Aug 13 '15 at 13:40