I'm trying to use BIND framework to bind a UITableView with UITextfield's which can edit the content.
I'm trying to achieve something very similar to how binding is done in Mac OSX. Bind a datasource with view, let the user make changes, on save the data is saved after validations.
Typically this is done by subscribing the delegate or observing the valueChanged event from textfield. I wanted to try out a new way to reduce this, that's how I came across BIND framework.
It encourages to use an MVVM framework, usually seen in .NET. Binding is as simple as mapping the keypath of model with the view component. But I'm finding it difficult to achieve to two way binding, from model to component and back.
BINDINGS(MHPersonNameViewModel,
BINDViewModel(name, ~>, textLabel.text),
BINDViewModel(ID, ~>, detailTextLabel.text),
nil);
Could anyone point me in the right direction.
This is a late answer, and not even really an answer to your question, but I hope it's still useful.
Take a look at https://github.com/mutech/aka-ios-beacon. This is a binding framework that integrates into Interface Builder and (by default) uses the view controller as root view model.
You don't have to write any code to initialize bindings. In your example, assuming that the view controller has (KVO compliant) properties "name" and "ID", you would just need to set the UILabel "text binding" properties to name and ID (you find the in the property panel in interface builder and enable bindings for the view controller (also in the properties panel).
And that should be all you have to do to establish bindings.
In versions up to 0.1.1 of AKABeacon, "enable bindings" is not yet there. In this case your view controller would have to inherit from AKAFormViewController.
Related
I've been playing around with a button in my storyboard, and had a hard time getting a border around it, until I found a page where it showed how to add a User Defined Runtime Attribute. I was able to make the button look as I wanted, but I wanted to know if there was a way for me to view the list of available attributes for a particular Object.
Clicking the "+" to add a new attribute doesn't provide any kind of auto-complete to show the available ones, and looking through my project code doesn't seem to reveal anything either, not surprisingly. Is there somewhere I can find all of the available attributes for all/any Objects in Xcode? Searches here on SO and in general have not shown any useful results so far.
You can achieve the same thing from code, so just check the properties of UIButton (which is available in the documentation and with autocomplete) and you're good.
You also have to make sure you are checking the properties on an UIButton instance and not the class properties.
User defined runtime attribute is a list of key paths that NIB loading subsystem uses through unarchived process. After initialisation message -setValue:forKeyPath: will be send to your unarchiving object for each key path from this list. So available attributes are not more than set union of all methods with selector sort of -setAttribute: and ivars with "_attribute" or "attribute" name.
All that public attributes you may find at public headers or documentation.
There's also possible to set private attributes, but it's not good practice. For instance, you may find all ivars by breakpoint execution inside any method and look inside "self".
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.
I got a url http://www.asp.net/mvc/overview/views/dynamic-v-strongly-typed-views
they create a not strongly typed view but at they refer #model dynamic at top of the view.
but rest of the code looks like normal strongly typed view. anyone can tell me what is the difference between Dynamic and Strongly Typed Views in MVC.
When one should use dynamic view. discuss with example when dynamic view is required ?
The difference is that a dynamic view won't enforce compile-time type-checking (binding to properties etc). You can name and bind any property you want. At run time, if it can't find it in the model, that's when you'll get an error. It's the same as the dynamic keyword in the language.
As to why or when to use it, generally speaking, don't. It's a workaround. Write a wrapper class, write the DTO, write an adapter, there's plenty of ways to make a strongly typed object to bind to. Implement an interface or something.
Rarely you might come across a situation where it's just not feasible (legacy code, 3rd party libraries?) to do it the "right" way. That's when you might be stuck with it. Run time errors are not fun to try to recover from - try to never use dynamic views.
The only time I personally have used it was to mock up test layouts and I didn't want to actually create full models yet. I'd not use it for production code.
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.
I don't really see the need for element to element binding in Silverlight 3 if using MVVM. Won't having one property directly affect another proper cause that property to be untestable?
To me, it makes more sense to do a two way binding to a explicit property defined in the ViewModel.
I agree that the use of MVVM severely deflates the usefulness of element to element binding.
Still, if all you are doing is binding two elements using a ViewModel property... what can you test? You can test that setting a property in the ViewModel sends a PropertyChanged event... but thats about it. Only when something else cares about that value is it useful to test a property like that.
In the simple cases, I can see element2element binding being more efficient and less code.