With CNContactPickerViewController in iOS 9.0, how to enable/disable single or multiple selection? - contacts

The delegate CNContactPickerDelegate have methods for single and multiple selections. But how do we specify we want single or multiple selection when we present the view controller?
I guess I miss something that perhaps also causes the problem I have described in: CNUI ERROR Selection predicates are set but the delegate does not implement contactPicker:didSelectContact:

You need to implement ONLY the method you need.
If you want only one contact, implement:
contactPicker:didSelectContact:
If you want multiple selection, implement:
contactPicker:didSelectContacts:
If you want select one property for one contact, implemente:
contactPicker:didSelectContactProperty:
And the last one, don't know how work, looks like a bug, because if I implement it, I get the multiple contact selection UI, but can't select properties.
contactPicker:didSelectContactProperties:
EDIT:
Finally I got some data from didSelectContactProperties, this method required a definition in predicateForSelectionOfProperty. I think the name is incorrect, should be didSelectContactsProperties, because I got the properties for multiple contacts.

Related

How BehaviorRelay.accept works in rxswift

I am drawing a tableview via BehaviorRelay.
Currently, I am using the code below as a way to add data.
viewModel.user.append(Person(name: "king", phoneNumber: "12341234"))
viewModel.personObservable.accept(viewModel.user)
I wonder if this code changes the user itself so that the whole tableView is redrawn.
If so, what method can I use to change only the data I added?
The code presented causes the personObservable (which is actually a BehaviorRelay apparently,) to emit a next event that contains an entire array of Person values, not just the latest Person added. Importantly, it's not emitting the viewModel.user object (at least not conceptually) but an entirely different object that happens to be equal to viewModel.user.
The default dataSource, the one that you get when you call items with anything other than a DataSource object, will call reloadData on the table view. This doesn't cause "the whole tableView" to be redrawn though, but it will cause the table view to query the data source for all of the visible cells, even if they haven't changed.
If you only want the table view to load the new cell, then the data source object needs to be smart enough to compare the new array with the array it's currently displaying so it can figure out which values are different and add/remove/move cells as appropriate, instead of just calling reloadData. As #Sweeper said in the comments, the RxDataSources library contains a set of data source classes that have that logic built in. If you wanted to reinvent the wheel, just write a class that conforms to both RxTableViewDataSourceType & UITableViewDataSource and implement the diffing yourself.

How do I add specific content from a collection view to another one?

I have three elements in my UICollectionViewCell:
Two labels with name and price, and a quantity button.
I would like to add the name and the quantity with "didSelectItemAtIndexPath" to a specific collection view in the previous view controller and the price in another view controller. I may achieve this by using a segue to pass data to any view controller of my choice.
Also, at the same time, I want to keep track of the selections I make adding them to a table view below the collection view.
My guess is to create empty arrays for each item.. one for name, price and quantity.
I may be wrong.. and I tried to append my current selection and I know I am missing something.
To pass information to a previous viewController use a delegate protocol. Suppose a is your first viewController, and b is your second viewController.
You can create a delegate protocol in b (here you specify a func you want to execute inside of a)
Set a as the delegate for b
write a function yourDelegateFunction in a , which your delegate protocol will call to update the viewController with your first collection.
in didSelectItemAtIndexPath call delegate.yourDelegateFunction
Here's a video with an easy guide for how this works:
https://www.youtube.com/watch?v=3BcBu30thIA
If you provide a sample of your code, and highlight where you experienced issues, I can provide a more precise solution.

View-based table bindings in Swift

I'm trying to set up a view-based table in Swift using bindings. All of the examples I've seen use a datasource/delegate setup.
I have an array of Flag objects which has two properties - flagName: String and flagImage: NSImage. I have an NSArrayController managing this array.
If I set up a cell-based table, and bind one column to arrangedObjects.flagImage and the other to arrangedObjects.flagName, I get a table displaying images and names, and I can use the array controller's add and remove methods, so there are no problems with my datasource or my array controller.
I have been following the instructions in Apple's TableView Programming Guide to bind my view-based table to my array controller:
tableView Content binding: FlagController.arrangedObjects
textField Value binding: TableCellView.objectValue.flagName
imageView Value binding: TableCellView.objectValue.flagImage
(IBs autocomplete is not happy with the paths for objectValue.flagName respectively flagImage; it doesn't feel that there should be any completion whatsoever and says it can't resolve the path, so it looks as if the problem is with the tableView's content.)
If I do this, my table has a number of rows that corresponds to the number of elements that my array controller is managing at that moment (I have two simple setups, one object vs. 50 objects, so it's clear that something is bound). What I don't get is a display; and selecting a table row does not seem to send back a message to my flagController.
What am I missing? Has anyone been able to make this work? I've had no problems with other bindings in Swift so far, but I'm starting to think that the sudden reappearance of datasource examples is not unrelated to this.
It sounds like you've failed to implement the delegate method -tableView:viewForTableColumn:row:. That's a common cause of blank tables.
You don't actually have to implement that if you make sure the identifier of the table column and the identifier of the table cell view are the same in IB.
Otherwise, the method can just do this:
- (NSView*) tableView:(NSTableView*)tableView viewForTableColumn:(NSTableColumn*)tableColumn row:(NSInteger)row
{
return [tableView makeViewWithIdentifier:#"TheIdentifierOfYourTableCellView" owner:self];
}
(It could also do more, if desired.)

Access UIView's textview from other view

Hello I have an app with 2 views.
The cybeeview and the moreview.
I use the cybeeview to do some calculations and I want to present them in the second view.
How can pass the data from cybeeviewcontroller.m to the moreviewcontroller??
Good way would be to use delegation. You can either write your own protocol, or implement - textViewDidEndEditing: inside moreviewcontroller. You will also need to set up the delegate:
cybeeviewcontroller.yourTextView.delegate = moreviewcontroller;
//those controllers are instances of their respective classes
Nonetheless it must be said that unless it is a minor and unimportant calculation you're doing, it's fair to say that you are not doing it correctly. You should be setting your model values and pass model around. You can get more information in documentation, look for Model-View-Controller design pattern.

Practical efficient usage of IBOutletColletion

How does look the practical usage of IBOutletCollection? Unfortunately Apple documentation mentions it briefly without giving an wider idea of usage. OK, it maintains one-to-many relation with IB, but how to access and use particular objects efficiently? With TagName? How to ensure the order of objects?
I've recently used this to easily initialize a grid of labels. I have a n by n matrix of labels on a view, and reference each one individually (via an IBOutlet) in order to display relevant data. However when the view first loads I wanted to control the default text that displayed in all the labels. Initially i wanted a dash to display, but since this is for a client I wanted it to be easy to change. The view contents have and continue to change over time, per client requests.
Instead of writing N line of code, I created an IBOutletCollection and accomplished the same results in 4 (#property, #synthesize, and for loop). YMMV but I found it very useful in this situation.
Read again this section in the Interface Builder User Guide.
IBOutletCollections are actually just NSArrays you can connect to more than one object in IB. All the objects you connected end up in this array and can be accessed from code like any other object in an array.
I used it to minimize code. I have a range of UIViews that should react on "touch up inside" events of some UIButtons (custom mode).
I gave all UIButtons a tag (lets say 1005 to 1010) and all UIViews the same tag as the UIButton they shall respond to.
Then I connected the UIViews with the collection in Interface Builder. All UIButton touch up events go to the same function in my controller. This function gets the tag of the sender object, iterates through the NSArray list (of "IBOutletCollection(UIView)") and compares the tag. Everytime it hits, the appropriate action is done.
It is a pity that NSArrays seem not to hold the order...