Beginner and Blocks - iphone

Simple question.
I have a tableViewController that will display a list of search results.
I want to create a block based callback (I think that's what you would call it)
I would present the viewController
[searchResultController showSearchResults //BlockCode here {
//did select this item...
}];
but use a block so that I can detect the selection made from the tableview instead of using a delegate method.
Problem is I have no idea how to implement this. Is there a good tutorial or a simple example on how to do this?

Your search results controller needs to have a block property. This block should be defined with no return type, and should take a parameter of whatever object you are going to use to represent the selected item.
Before presenting your search results controller, set the block property to whatever you wish to do for your callback.
Within the search results controller, when a row is selected, execute the block, passing in the selected object. Either this method, or the block itself, should also dismiss your controller.

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.

remove top left back button

I would like to remove the top left back button.
I tried to check "Full screen" option, but the arrow is still here.
I want to remove the back button because I have a button next to this button, and I don't want the user tap on it by mistake
Thx
According to the Apple Documentation the deprecated method that was in the previous answer (which used to solve this issue) has been replaced with:
reloadRootPageControllers(withNames names: [String],
contexts: [Any]?,
orientation: WKPageOrientation,
pageIndex: Int)
"Parameters
names
An array of NSString objects, each of which contains the identifier of an interface controller in your storyboard file. The order of the identifiers in the array defines the order of the corresponding interface controllers in the page-based interface.
contexts
An array of objects of type id. Use this parameter to pass context objects to each of the interface controllers loaded into the page-based interface. The first object in the array is passed to the first interface controller, the second object is passed to the second interface controller, and so on.
orientation
The scrolling orientation for the page-based interface. For a list of valid values, see WKPageOrientation."
And pageIndex should be pretty simple to figure out. If you only have one element in [names] it will be 0. Otherwise you should select the index of the page you want loaded from [names]
Try:
WKInterfaceController.reloadRootControllersWithNames(["myInterfaceController"], contexts: [])
This removes it by making the controller the root controller. You may have to reload the controller after calling this.

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.

Class method (NSString type) called from viewcontroller returns nil?

I'm a c++ programmer new to objective-c.
I created a calculator app that is working fine using a single view. I have a Calculations class and a ViewController. Every time a button is pressed, an IBAction method in the ViewController calls methods defined in the Calculations class to handle the input and returns the output as an NSString which I then set as the value of the label.text field.
Now I am working on a tab bar app using the same Calculations class. This app has two tabs, each with a unique set of input buttons for the calculator (both views sharing the same input/output data). The first tab is identical to my first app with the single view, so I am trying to do this in a similar fashion.
Here is the problem:
When a button is pressed, the IBAction method that handles the input runs through the calls to the Calculations class methods (shown below) without error:
-(IBAction)readInput:(id)sender {
[_calculations input:[sender titleForState:UIControlStateNormal]];
inputField.text = [_calculations inputDisplay];
outputField.text = [_calculations outputDisplay];
}
however, both the inputDisplay and outputDisplay methods return nil. Using the debugger I noticed that I am unable to "step into" the calls to _calculations methods, instead the line is skipped and the value returned by both is nil. I added the following method:
-(IBAction)setNumber:(id)sender {
NSString *button =(NSString *)[sender titleForState:UIControlStateNormal];
inputField.text = button;
}
and if I attach this to the input buttons I can see the display updated. This seems to be an issue with calling the _calculations member functions and tab bar views (because this issue is not present using a single view).
I realize that I left out a lot of information, but I did it to avoid providing irrelevant information. I will provide all details that are necessary if asked.
Check to make sure _calculations is not nil.
You can send any message (call any method) on nil and it will just return nil, not cause an exception.
Without seeing more code it is going to be a bit difficult to diagnose.
If I was trying to debug this issue I would first make sure _calculations points to the object you want it to point to. If its loaded from a NIB then it might not be getting initialised, and still be nil. You can send messages to nil objects without any issues. If an object receives a message that it cant handle (the method doesn't exist, or the target object is nil) then the return for that call will be nil.
I have in the past put initilization code into the init: method, and spent a few hours why it wasn't being called, until it dawned on me that I needed to put my init code into the viewDidLoad:, or the initWithNibName:bundle: or even the initWithCoder: selector.
HTH, Matt

How can I pass arguments with UIActionSheet?

I have an Action Sheet popping up and I want to pass a certain argument to a button processing method.
For example:
I have a table and I want to pass to a button processing method row number that was selected in a table.
How can I achieve this?
You would have to set this in your delegate ahead of time. You can then use this value when your delegate receives the button press notification.
If it is an integer argument, put it as the tag property of the action sheet. Otherwise, you can subclass the action sheet and put variables there, or use associative references.
if you want to pass an integer, use UIActionSheet.tag.
if you want to pass a NSString, use UIActionSheet.accessibilityValue.
these are simple and easy. no need to create an instance variable.