Giter Site home page Giter Site logo

Comments (19)

nathanvogel avatar nathanvogel commented on June 5, 2024 3

@yougot is right. This doesn't work :

self.dataSource = FirebaseTableViewDataSource(ref: ref_categoryList, prototypeReuseIdentifier: self.IdentifierCategoryTableViewCell, view: categoriesTableView)

But this works :

self.dataSource = FirebaseTableViewDataSource(query: ref_categoryList.queryOrderedByKey(), prototypeReuseIdentifier: self.IdentifierCategoryTableViewCell, view: categoriesTableView)

The difference is precisely this line :
self.hasPrototypeCell = YES;

Present with query argument : https://github.com/firebase/FirebaseUI-iOS/blob/master/FirebaseDatabaseUI/FirebaseTableViewDataSource.m#L135
and absent with ref argument : https://github.com/firebase/FirebaseUI-iOS/blob/master/FirebaseDatabaseUI/FirebaseTableViewDataSource.m#L47

It works with CollectionViews though (everything setup accordingly)
self.dataSource = FirebaseCollectionViewDataSource(ref: ref_categoryList, prototypeReuseIdentifier:self.IdentifierPackTableViewCell, view: self.packCollectionView)

because FirebaseCollectionViewDataSource passes down the identifier as a prototypeReuseIdentifier, not a cell one like FirebaseTableViewDataSource :
https://github.com/firebase/FirebaseUI-iOS/blob/master/FirebaseDatabaseUI/FirebaseCollectionViewDataSource.m#L47

from firebaseui-ios.

cslosiu avatar cslosiu commented on June 5, 2024 2

OK, to get the cell in right custom class, we need to call registerClass after created the DataSource:

self.dataSource = [[FirebaseTableViewDataSource alloc] initWithRef:self.firebaseRef cellReuseIdentifier:@"TOP_POST_CELL" view:self.tableView];
[self.tableView registerClass:[TopPostSummaryCell class] forCellReuseIdentifier:@"TOP_POST_CELL"];`

But then all the UI things on the custom cell would be Nil. Seems the author did not setup them... or not restored from the Storyboard... how come...

from firebaseui-ios.

yougot avatar yougot commented on June 5, 2024 1

I think it cause by missing code
self.hasPrototypeCell = YES;
at there
https://github.com/firebase/FirebaseUI-iOS/blob/master/FirebaseDatabaseUI/FirebaseTableViewDataSource.m#L47
https://github.com/firebase/FirebaseUI-iOS/blob/master/FirebaseDatabaseUI/FirebaseTableViewDataSource.m#L91

from firebaseui-ios.

morganchen12 avatar morganchen12 commented on June 5, 2024 1

In the future I'd like the data sources to know less about the views they populate so that our initializers can be simpler and less confusing (and we can follow the designated init pattern).

For now, feel free to send over a PR with those changes ✨

from firebaseui-ios.

asciimike avatar asciimike commented on June 5, 2024

@jagonzalr Hey, sorry for the delay. I feel like I've encountered this problem, though I don't remember exactly what the resolution was. I think you may actually have to initialze the cell in -initWithFrame for it to work, though I'll have to check my samples.

from firebaseui-ios.

cslosiu avatar cslosiu commented on June 5, 2024

Meet this problem too. I think you should solve it. Maybe just let me pass the custom cell class into the initializer? Otherwise this data source is simply not useful.

from firebaseui-ios.

Spyryl avatar Spyryl commented on June 5, 2024

all the controls being Nil on the UI is exactly the issue I'm experiencing doing this with swift. is there a way around this?

from firebaseui-ios.

Spyryl avatar Spyryl commented on June 5, 2024

incidently - the same issue "all the UI things on the custom cell would be Nil" also exists when trying to use custom cells with
FirebaseCollectionViewDataSource

from firebaseui-ios.

asciimike avatar asciimike commented on June 5, 2024

Hey guys,

In order to use prototype cells, you should be using the version of the constructor with prototypeReuseIdentifier instead of cellReuseIdentifier. Note that there is also a version of the constructor with a cellClass parameter, which you can pass in [YourCustomCell class] which will do all the reuse identifier magic appropriately, behind the scenes :)

The issue is "all things nil" is not a FirebaseUI issue, but rather a "developer isn't configuring their cell correctly, thus things are nil" issue that FirebaseUI can't really solve--this issue would exist if you did the same thing without FirebaseUI (we basically just forward methods).

from firebaseui-ios.

jagonzalr avatar jagonzalr commented on June 5, 2024

With my initial post of the issue I use the prototypeReuseIdentifier not the cellReuseIdentifier so why is that not working?

Also I really don't get the "all things nil"
If I use this method self.dataSource = [[FirebaseTableViewDataSource alloc] initWithRef:self.firebaseRef cellClass:[Story_TVCell class] cellReuseIdentifier:@"storyCell" view:self.tableView];
it returns the Custom Table View cell class but it's always nil

If I use "as your documentation" self.dataSource = [[FirebaseTableViewDataSource alloc] initWithRef:self.firebaseRef prototypeReuseIdentifier:@"storyCell" view:self.tableView];
it returns UITableViewCell instead of the Custom class. The purpose of FirebaseUI is to work as it says in the documentation which doesn't so maybe it would be nice to have an example (in code) with custom table view cell class which uses the prototypeReuseIdentifier @mcdonamp

from firebaseui-ios.

asciimike avatar asciimike commented on June 5, 2024

Can you please clearly define, "not working"? Is the cell not the right type, is the cell the right type but all UI elements are nil, is it something else?

Is your .m file still empty? I think you may need to call initWithFrame to ensure a cell is initialized correctly.

Also, looks like I didn't provide a prototypeReuseIdentifier with a cellClass likely because it's autopopulated from the storyboard (Apple magic) in dequeueCellWithReusableIdentifier: indexPath, which Apple guarantees will return a cell of the correct type.

from firebaseui-ios.

cslosiu avatar cslosiu commented on June 5, 2024

The problem of all controls are nil: it's not the users of the library. If you restore the cell from the storyboard, the controls are there. It's pointless to return me a cell with all nil controls and say: here is your custom cell! If I have already designed my cell on storyboard why I need to write the initializer again?

from firebaseui-ios.

jagonzalr avatar jagonzalr commented on June 5, 2024

Using self.dataSource = [[FirebaseTableViewDataSource alloc] initWithRef:self.firebaseRef prototypeReuseIdentifier:@"storyCell" view:self.tableView]; with empty .m in the custom cell class returns UITableViewCell instead of the CustomCell. The thing is why I need to call the initWithFrame if it is not in the Documentation, and if it is really necessary then please update the Documentation with proper examples. I'm gonna try to do the initWithFrame but it would be awesome to provide a clear example on how to use prototypeReuseIdentifier @mcdonamp

from firebaseui-ios.

asciimike avatar asciimike commented on June 5, 2024

@cslosiu The code passes through exactly what the developers have created (see here), so I'm not really sure how FirebaseUI could be getting in the way, unless we're not wiring up the storyboard section correctly (which we can't do, as that falls squarely in the hands of the developer to use correctly). I'd love a second set of eyes on that to make sure I'm not missing anything.

@jagonzalr that's super strange--per the same snippet of code as above, if the class was registered in the storyboard as your custom cell, the dequeueCellWithReusableIdentifier... method should return a correctly initialized cell. Again, I think it's an issue with the storyboard configuration and/or custom cell initialization, as FirebaseUI does nothing extraordinary when it comes to this initialization. Take a look at this Ray Wenderlich tutorial (near the bottom) for some more color on how to do that--note that the only thing one should have to do is hook up dequeueCellWithReusableIdentifier... to get that automagically working.

Also agree that the docs should be more clear on this point. TBH, I've basically given up on trying to use storyboards given the fact that errors like these are super difficult to debug because Apple hides so much of the configuration. I highly recommend using XIBs and custom cells (which is a minor change from prototype cells--basically you just don't drag the cell in to the tableview and you change the constructor), which ends up in cleaner, more understandable, more sharable code.

Also, long story short, but I think that we need to rethink the public API significantly since those constructors are pretty gnarly, and they don't really promote sectioning. I think I want something like:

FirebaseTableViewDataSource *dataSource = [FirebaseTableViewDataSource dataSourceWithReuseIdenfitifer:@"foo" tableView:self.tableView];
dataSource.isPrototypeCell = YES;
dataSource.modelClass = [YourClass class];

[dataSource addSectionNamed:@"section 1" withReference:myFirebaseReference populateCell:^(Cell *c, Snapshot *s){
  // Populate cells for that section
}];

Maybe separate the add section from the populate cell for each section, but generally we need to make the configuration easier and add support for sectioning--I think it will also clean up the documentation issues (currently they are pretty unintelligible due to trying to handle all the edge cases).

from firebaseui-ios.

kutakmir avatar kutakmir commented on June 5, 2024

still an issue @jagonzalr how did you eventually solve it?

EDIT:
working solution using XIB:

override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
    super.init(style: style, reuseIdentifier: reuseIdentifier)

    let view = UINib(nibName: "ConversationTableViewCell", bundle: nil).instantiateWithOwner(self, options: nil)[0] as! UIView
    view.translatesAutoresizingMaskIntoConstraints = false
    self.addSubview(view)
    self.addConstraint(NSLayoutConstraint(item: view, attribute: .Top, relatedBy: .Equal, toItem: self, attribute: .Top, multiplier: 1, constant: 0))
    self.addConstraint(NSLayoutConstraint(item: view, attribute: .Bottom, relatedBy: .Equal, toItem: self, attribute: .Bottom, multiplier: 1, constant: 0))
    self.addConstraint(NSLayoutConstraint(item: view, attribute: .Leading, relatedBy: .Equal, toItem: self, attribute: .Leading, multiplier: 1, constant: 0))
    self.addConstraint(NSLayoutConstraint(item: view, attribute: .Trailing, relatedBy: .Equal, toItem: self, attribute: .Trailing, multiplier: 1, constant: 0))

    self.commonInit()
}

make sure you correctly setup the file owner as this class and connect the outlets and actions

from firebaseui-ios.

callam avatar callam commented on June 5, 2024

I made a FIRDataObject class that can be initialised with a FIRDataSnapshot. The snapshot is set on the object and its values are automatically mapped to the object's keys.

class FIRDataObject: NSObject {

    var snapshot: FIRDataSnapshot
    var ref: FIRDatabaseReference {
        return snapshot.ref
    }
    var key: String {
        return snapshot.key
    }

    required init(_ snapshot: FIRDataSnapshot) {
        self.snapshot = snapshot
        super.init()
        if let values = snapshot.value as? [String:AnyObject] {
            setValuesForKeysWithDictionary(values)
        }
    }
}

I have also made a FIRCollectionViewDataSource as a generic type that takes two arguments, a custom cell and model class.

class FIRCollectionViewDataSource<Cell: UICollectionViewCell, Model: FIRDataObject>: FirebaseCollectionViewDataSource {

    override init(ref: FIRDatabaseReference, cellReuseIdentifier identifier: String, view collectionView: UICollectionView) {
        super.init(ref: ref, modelClass: Model.self, cellClass: Cell.self, cellReuseIdentifier: identifier, view: collectionView)
    }

    func populateCellWithBlock(callback: (Cell, Model) -> Void) {
        self.populateCell = { (cell, object) in
            callback(cell as! Cell, Model(object as! FIRDataSnapshot))
        }
        self.collectionView.dataSource = self
    }

    override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as! Cell
        let object = objectAtIndex(UInt(indexPath.row)) as! FIRDataSnapshot

        populateCell(cell, object)

        return cell
    }
}

Here is an example of a custom FIRDataObject and FIRCollectionViewDataSource and how it can be used.

class Object: FIRDataObject {

    var foo: String = ""
    var bar: String = ""
}
class ObjectsDataSource: FIRCollectionViewDataSource<ObjectCell, Object> {
    init(_collectionView: UICollectionView) {
        super.init(
            ref: FIRDatabase.database().referenceWithPath("objects"),
            cellReuseIdentifier: "ObjectCell",
            view: collectionView
        )
    }
}

The populateCell block now provides the cast cell and object you specified in the DataSource's generic arguments. Also once the populateCell block has been set using populateCellWithBlock, the DataSource automatically sets itself as the collectionView's dataSource.

var dataSource: ObjectsDataSource?

override func viewWillAppear(animated: Bool) {

    super.viewWillAppear(animated)

    dataSource = ObjectsDataSource(collectionView)
    dataSource?.populateCellWithBlock { (cell, object) in
        cell.object = object
    }
}

So just to recap, once you have copied the FIRDataObject and FIRCollectionViewDataSource classes and created your custom implementations of them, it's as simple as the above block of code.

from firebaseui-ios.

danielpassos avatar danielpassos commented on June 5, 2024

I totally agree it's a bug and I also have this problem, but seems it does not make sense anymore after @morganchen12 refactor FirebaseTableViewDataSource

Only if you have a plan to release a path version.

from firebaseui-ios.

morganchen12 avatar morganchen12 commented on June 5, 2024

We probably won't release a patch version, as these changes are already in master. Expect them to be released in a week or less.

from firebaseui-ios.

morganchen12 avatar morganchen12 commented on June 5, 2024

Resolved in the 0.7.0 release.

from firebaseui-ios.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.