I want to bind programmatically my NSTableView to an NSArrayController.
Everything works fine with Cell-Based Table using:
[[table tableColumns][0] bind:NSValueBinding toObject:board.dataSource withKeyPath:#"arrangedObjects.name" options:nil];
but when I try to bind to a view based table….how it should work?
I suppose to bind "arrangedObjects" to the column and then each property of my arrangedObjects's nth element to an object of my NSTableCellView…but how can I make it programmatically?
I've tried to access at NSTableColumn's view's class but the only method I've found is .dataCell and it returns an NSTextFieldCell not the class I would to use for my table (an NSTableCellView).
Any idea?
For a View-based TableView you need to bind the NSArrayController arrangedObjects to the tableView content.
Ignore the column, which is very different to cell-based TableViews.
Bind the Table Cell View to the NSArrayController selection and then use a model key of observationInfo.
Finally bind the views, eg Text View to the NSCell View with model key objectValue.name, where name is some property of the entity being represented in the table.
If you are using core data then set up the NSArrayController parameter to be the managedObjectContext, set it to type entity and provide the entity name and tick the prepares content check box.
Related
I am making an iPhone app.
In this application I have to make a look like below.
I am not allowed to use collection view.
I am using tableview, and custom cells. Which I am easily able to incorporate. Means taking 3 subviews in Custom cells. And making a look.
Here the problem is In a cell, how do I distinguish each object. so that I can call each object, to set an image on image view.
Is there any Object oriented mechanism to distinguish all 3 objects in a cell ?
Try to get the data as NSArray of NSDictionary containing an array of 3 objects that you want to display on cell.
Assign tag to UImageView in the custom cell.
In cellForRowAtIndexPath, get the 3 objects and apply image using switch case.
Well everything depends on how you get the data from the server
You can use outlet collections which will give you an array of UIImageView and you can assign different tags to the imageview so you can assign to them.
You can use these guides to understand how outlet collections works:
http://nshipster.com/ibaction-iboutlet-iboutletcollection/
http://useyourloaf.com/blog/interface-builder-outlet-collections/
All the standard procedures should work to achieve this but then it only depends on how nice you want to do this.
The straight forward procedure is to expose the outlets of the image views and labels in the cell and assign the correct values to those when dequeuing/creating table view cell.
The first upgrade would be to rather expose 3 setters on the cell to simply set your model to each of them which will then internally set the images and texts inside the cell.
The next thing you may do is to rather insert an array of objects (always sending up to 3 in your case) instead of having 3 setters.
At this point you may actually rather use a collection view INSIDE the cell and make the cell a data source for the collection view. But this is totally optional.
Now since you may still dislike the table view data source you may create another model which contains an array of objects (again up to 3 in your case) and make a system that will distribute your original array of objects into the array of these containers.
If then you need to handle buttons or other touch events they may be handled with collection view delegate or 3 buttons and in both cases I advise you to handle those in the cell and create a custom delegate for the cell which will report the event with the appropriate model.
This together generates the following:
When you receive the data call a container class to distribute your array of objects (into groups of 3) and assign it to your table view data source (view controller usually)
Number of rows is the same as number of containers in the array
Cell for row assigns the container with row index to the cell. It assigns self as a delegate
Cell internally handles the object distribution either via collection view, separated outlets or outlet collections.
Cell handles actions and reports them back to the delegate (- (void)myCell:(MyCell *)cell selectedItem:(MyObject *)item;)
The cell delegate can again handle what to do upon reported actions
Also if you want to avoid a collection view inside the cell you can create a custom view using xib so you do not copy the labels, image views and such. Then simply create 3 of these custom views inside the cell. Also by using inspectable and designable these views will be visible inside the storyboard.
First I'll say that a restriction against using UICollectionView is silly. Are you still targeting ios5?
I'd look at it like this.
make your own view class for the 'subcell' let's use this term for any single instance of the 3 views per cell. I'd subclass UIImageView, adding the label for the name down the bottom and a 'setSelected:' kind of method to highlight when selected via user interaction by drawing differently.
make a UITableViewCell subclass to host and layout up to three of these subcells. I say up to 3 because the last cell may contain 1 or 2 subcells and not 3 if the total people to represent is not divisible by three.
Selection Logic: You'll need to override 'setSelected:' because you want to deselect and select only subcells, you don't want the whole cell to highlight on selection, only a third of it.
You'll also want to implement touchesEnded: in this cell so that you can figure out which of the three subcells was last touched, and you'll need to be able to query or communicate this back to the controller, probably using delegation. If the cell can communicate back whether selection was in subcell 0,1 or 2 then this together with the UITableViewDelegate didSelectAtIndexPath should map to your model nicely - selectedPerson = myArrayOfPeople[ (indexPath.row * 3) + subcellIndex ]
You'll be able to decorate your cells in cellForRowAtIndexPath: in similar fashion..
personOne = model.arrayOfPeople[indexPath.row*3]
personTwo = model.arrayOfPeople[indexPath.row*3 +1 ]
personThree = model.arrayOfPeople[indexPath.row*3 + 2 ]
In my app I am using scrollable segment controller on header view of tableview and put dynamic data in it.
When click on segment index path, the particular id is get. Match this id with other entity data base change table view data.
My problem is, I cannot use segment index path in cellForRowAtIndexPath.
I am using different methods for this but it not work.
I have a UILabel and need to reference its initial indexPath.row in another view controller? I have already used the tag of the UILabel for a different purpose, but is there a way I can set an associated value of some sort with the UILabel in swift.
Your UILabel should not be acting as a store for data, that's what data structures are for. One simple possibility to start out with is to have the tag be the index of that label's data in an array or use the tag value as the key of a dictionary and store the data you need in those data structures.
If you are using custom view for your TableViewCell (which I assume you are ), I would just create new custom view (inherited from UILabel) and add another property to it for indexPath and assign this property with the original indexPath, I would use this custom label view instead of UILabel. Please let me know if you have questions about this approach.
As the title describes, I've got a tableview inside each of my collection view cells. For me, it makes sense that the superview's controller should control the view, but since in this case each tableview contains different data, I have made each superview (collection view cell) the controller for its tableview. I hope that makes sense. I know making a view to also be a controller violates the MVC paradigm, but I'm not sure what the proper way is achieve MVC compliance in this case. I also need to send messages to the table view based on what happens in the CollectionViewController. Do I need to subclass UITableViewController and make a reference to it in my collectionviewcell.h file?
Sorry if that was confusing. Thanks for the help.
I think your instinct is correct that having a view object serve as a data source is a violation of MVC. I would suggest having the owning view controller either serve as the data source for all the table views, or set up a separate model object for each table view that serves up the cells for that table view.
If you use a single data source you'll have to have a switch statement that figures out which table view is asking and fills the cells with the appropriate data.
My gut would be to create a thin table view data source class who's only job is to serve up the cells for the table view inside a collection cell (and respond to the other collection view data source protocol methods). Use a custom subclass of UICollectionViewCell that has a strong property that points to the data source object. You could make your custom cell class create an empty data source object at init time and hook up it's outlet to the table view.
Then in your cellForItemAtIndexPath method, pass the appropriate data to the cell's data source object. If you reuse a cell, it would already have a data source object, so you'd just replace the data with new data and trigger the reloadData method.
Your controller object would mediate between the model and the view, like it should. It would set up the model data for each cell, and then the data source object for each cell would act as the model for that cells table view.
If you later come up with several different types of collection cells that display different data, using separate data source objects for each cell would keep the code simple. You'd just subclass your data source object based on the cell type.
I have a UITableView that is populated with table view cells from an NSFetchedResultsController. Each table view cell is linked to an entity object under Core Data.
I recently performed a lightweight migration and added an attribute that every entity object should have. The problem is, I am not sure how to apply it to the existing table view cells.
To be more specific, I want to add an orderingValue attribute to each object (task) that is linked to a table view cell. How would I make this orderingValue equal to the indexPath.row of the tableviewcell?