How do I use Xamarin iOS PickView to get the value? - ios

I just started messing around with Xamarin and I'm confused on two things. How to use it and if I'm searching the right keywords for help.
If I want to look up something can I look up the native iOS controls as an equivalent? I feel if I search "how to get value from ios picker" the answers are specific to objc-c. Even trying to look at the same properties I have no luck. The Xamarin Tutorials/ documentation I feel are disorganized and lacking. PickView isn't in the list of UI controls that have documentation.
I don't see any events for this PickViewer either in Xamarin Studio. I even try debug mode in Xamarin iOs but almost every property I try and check that seems it might be the answer gives me an "unknown member".
In this example, I have a Xamarin iOs pickviewer and can't figure out how to retrieve the value or even alert on a row selected which doesn't seem to work. I assume I can apply this to a list table as well?
Setting up the PickView list
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
pvBankRollAmounts.Model = new UIPickViewBetAmountOptions ();
}
So how can I get the value of what was selected in the UI? and what's the best way to find these answers on my own? Better Documentation somewhere?

Xamarin iOS sticks pretty closely to the Apple iOS model of doing things. It is actually beneficial to be able to read Obj-C (or Swift) so you can look at Apple's documentation and samples.
Xamarin has a PickerView sample as part of their sample app.
To get the Selected item, you need to override the Selected method in the Model class. This seems strange from a C# perspective, but it is a fairly common pattern in iOS, which commonly uses a Delegate pattern. You could create a custom event and raise it to be handled in your parent class.
public override void Selected (UIPickerView picker, int row, int component)
{
// row is the selected row
}

Related

iOS: When to use delegate/dataSource (protocols) vs. properties

Many CocoaPod and native iOS libraries use protocols that they name either CustomClassDelegate or CustomClassDataSource as a means to do some setup or customization. I was wondering when I should use this programming model, because it seems like I could accomplish much of this with properties.
Example
If I define a custom class called SmurfViewController that has a SmurfLabel, is it better practice to store the smurfLabel as a private property and have a public computed property called smurf that looks like this:
private var smurfLabel = UILabel()
public var smurf: String {
get {
return smurfLabel.text
}
set(text) {
smurfLabel.text = text
}
}
or should I define a SmurfDataSource that has a public function that looks like this:
func textForSmurfLabel() -> String {
return "smurfText"
}
When should I use what here?
You should just use a property for that. Delegates and Datasources are for different controllers/Objects to speak to one another when the alternative is to instantiate the controller/object from the navigationStack/view hierarchy. A Delegate forms a specific communication between the two that allows for clear knowledge in what their relationship is while keeping them decoupled (assuming you try to keep it that way). I disagree with the article that says callbacks are "better". They are amazing and I advise using them often, but just understand that most options that swift provides you with have a place where they work best.
I might be slightly bias, but Swift is an amazing language with OOP being a backbone and everything it has was well put together in order to provide the correct tools for each situation you find yourself in.
I often find myself using both of those tools and one other more customizable option in my more advanced setups where I have an overseeing viewController that manages many child controllers. It has direct access to all of them that are active but if any of its children communicate with it, it is through delegates. Its main job is just to handle their place on the screen though, so I keep everything manageable.
Delegates and data sources are more appropriate for offloading behaviors to other entities, not simple values. In other words, if your type just needs a value for something, you are correct that it makes more sense to expose that as a property that can be set from the client code.
But what should happen (for example) when a user taps a specific table view cell is a behavior that shouldn't be hard coded into UITableView. Instead, for flexibility, any implementation of that behavior can be created in a delegate and called by the UITableView when appropriate.
In general, think of delegation as a way to make subclassing unnecessary, because the methods you would normally override in a subclass are instead moved into a protocol that can be implemented by ANY type, not just a subclass of the base type. And instead of calling internally implemented methods to get certain behaviors, your type is simply calling those behaviors on an external collaborating class (the delegate).
So perhaps the best guideline for when to use a data source or delegate is the question: "Would I need to subclass this class in order to change this value or behavior in the future". If the answer is no, because you can just set a property from client code, then don't use delegation. If the answer is yes, then offload that behavior to a delegate or data source instead of forcing future programmers to subclass your class to make it work for their use case.
Delegate is an interface for the undefined activities.
so when you make a SDK or framework, you must provide an interface so that users can write a proper code for the interfaces' expecting activity.
i.e, Table View needs a datasource to show it's contents, but the apple's library developers doesn't know the content whatever contents their library users will use. so they provided an interface like datasource, delegate.
and in the library, they just call this methods. that's the way the library should be made.
But in your code, the label is defined very explicitly as well as it's in the current view, and you don't need to make an interface for an undefined activity.
if you want know more about this kind of coding style, you need to do some researches on Software Design Pattern.
https://en.wikipedia.org/wiki/Observer_pattern
https://en.wikipedia.org/wiki/Delegation_pattern
https://en.wikipedia.org/wiki/Software_design_pattern
I love apple's sdk very much, because they used all the needed design patterns very properly.

Drag&Drop in vaadin with clientSideCriteria

I have several types of components which are dragable. I have to ensure that the currently dragged component can only be dropped on a drop-target with the same type.
The ClientSideCriterion ContainsDataFlavor seems apropriate for this task. But i found no way to mark my draggable components of which type they are.
With this i can formulate that only components of type x are allowed drop-targets:
#Override
public AcceptCriterion getAcceptCriterion()
{
return new ContainsDataFlavor("ComponentType_ONE");
}
But how can i mark a DragAndDropWrapper with the tested type?
Well, the criterion ContainsDataFlavor is unfortunately not appropriate for my use-case.
After a lot of research and debugging i decided to implement my own ClientSideCriterion. This is not really hard, you only need two classes with basically only one method, thats it.

How to bind data in View

Actually someone asked me this question and I'm also interested to know, that how to bind data to a UI element directly. I know UITableview have Datasource property but it doesn't bind data directly. We have to use its protocol methods to bind data in code.
Is there any other way from which we can bind data to the View or is this possible or not? In .Net gridview we can bind data from database to gridview directly.
Update: If you mean synchronizing backing data with UI elements then read the last paragraph.
It would be against the recommended MVC pattern to bind data directly to the view if I understand your question correctly. Check the below links for more info.
Why MVC?
[Why MVC instead of good old ASP.NET? Still not grasping why I should go this route?][2]
However if you do want to bind data directly, there is nothing stopping you from it, even though it might be a bad idea unless the use case is trivial. For e.g. UITableViews are available with static cells. And if a pre-built UI element doesn't have a provision to bind data (don't know of any) to it directly, you could make a similar UI element that serves the purpose.
However it would take way more effort to build such and element than to supply data to it the existing one through preferred methods.
By binding data directly, if you mean supplying the data through interface builder, then you are out of luck. In Cocoa (for OS X application development), there is something called Bindings that help you synchronize your UI elements with the backing data. However in iOS there isn't such a thing. But you could use Key - Value - Observing to achieve this to some extent.
Also why iOS might not have such bindings may be partially answered here:
Is there any technical/conceptual reason why iOS does not support Cocoa Bindings?.
And check this if you have a need on such functionality: Is there any data binding mechanism available for iOS?
While it isn't exactly binding, I have used didSet property observers to update UI elements like this:
var label: UILabel?
var labelText = "Change me." {
didSet {
label?.text = labelText
}
}
That assumes you have initialized label somewhere appropriately. I believe that is the closest you can get in iOS.

MvvmCross iOS similar to IMvxAndroidCurrentTopActivity

I'm trying to create a Plugin in MvvmCross that uses the UIActionSheet. But to use it I need to have the top View in iOS. I found in Android the IMvxAndroidCurrentTopActivity but i could not find a similar in iOS. Is there anything that i can use like this in iOS?
var activity = Mvx.Resolve<IMvxAndroidCurrentTopActivity>().Activity;
if (activity == null)
{
throw new Exception("Cannot get current top activity");
}
I don't think there is an exact equivalent.
Plugins like PictureChooser work around this by using IModalHost from the presenter - e.g. see https://github.com/MvvmCross/MvvmCross/blob/v3.1/Plugins/Cirrious/PictureChooser/Cirrious.MvvmCross.Plugins.PictureChooser.Touch/MvxImagePickerTask.cs
Other plugins rely on statics or globals - e.g. see https://github.com/brianchance/MvvmCross-UserInteraction/blob/master/Chance.MvvmCross.Plugins.UserInteraction.Touch/UserInteraction.cs
For your plugin, you could require that users provide a custom interface in their app (e.g. in the presenter) or you could add something to IModalHost as a pull request.

Binding to TableLayout in Mvvmcross

Is there any example of binding any sort of collection to a TableLayout in android? I keep receiving the message/warning that binding failed for attribute ItemSource LocationQuantities. All of the other bindings to the view model work as normal, but the list doesn't bind to the TableLayout. At first I thought my problem was binding to a dictionary but I was able to bind to a dictionary with other Mvx layouts (listview etcs.)
I can't seem to find in any of the N+ code examples or anywhere else on the web where a TableLayout is actually used in an mvvmcross app. I'm sure I'm just doing something stupid simple wrong here.
<Mvx.MvxTableLayout
p1:id="#+id/PartLocationQtyTable"
p1:layout_width="fill_parent"
p1:layout_height="wrap_content"
p1:layout_below="#id/PartDetailPriceLayout"
p1:padding="5.0dp"
local:MvxBind="ItemSource LocationQuantities"
/>
I've tried the above as well as with a custom template. The above example just uses a list of strings.
Any help would be appreciated
The only obvious problem I can see with your code is that it uses ItemSource whereas all the list-based layouts use ItemsSource - see MvxTableLayout.cs#L89
Beyond that, I guess you'll also want to make sure that your templates for TableLayout are TableRows - so that they can be loaded as rows. Obviously we can't see your item templates currently as you've not included them in the question.
I've got to admit TableLayout isn't something I've ever personally used in a production project - just not something I've yet needed to use.

Resources