MonoTouch.Dialog: Dismissing a Keyboard - xamarin.ios

Using the Reflection API to auto generate a UI.
How can I dismiss the keyboard when the user selects a new field, or if they choose a field which generates a new view to pick from. In the later case, when the user returns to the first screen, the old keyboard is still there.

UIView.EndEditing(bool force);
The above will hide the keyboard for you without needing to know who the first responder is. I haven't done much with the reflection API but you should be able to call that on the view when an element is selected.
Apple Docs -- endEditing:

Clarification for those initially struggling with the MonoDialog portion of the question:
The EndEditing method is not available on DialogViewControllers objects directly (who inherit from UITableViewControllers). You should be calling EndEditing(bool) on the View of a DialogViewController and not trying to call EndEditing(bool) on the actual DialogViewController itself.
For clarification:
DialogViewController dc;
dc.View.EndEditing(true);
Note:
UIView objects include the EndEditing(bool) method, but UITableViewControllers do not inherit from UIView so the EndEditing method is not available on the controller itself. UITableViewControllers contain a view object, call EndEditing on that view object.

Check the ResignFirstResponder method. This one should help you I guess.

Related

Xamarin iOS : How to detect the tableview scroll

I want to detect the scroll of tableview in my class. I used decelerationEnded method of UITableViewDelegate but it got crashed.
Ideally you should be using a UITableViewSource assigned to your UITableView.Source property. You no longer require a delegate class, you can override all of the necessary methods within the source, which is the currently preferred method of achieving the result your after. You are most likely looking to override the method called 'Scrolled' within the UITableViewSource. However I would suggest making use of 'DecelerationEnded' as well if you're trying to do something depending on if your scroll view is at the 'bottom' or 'top' of the UITableViews content (That's just a little tip based off of some experience with this in a recent project.)

Passing an object from a tabbarController to its subviews

I am trying to pass a simple core data objects info from a tabBarController to its subviews so that they each reference a different attribute of that object. As a newbie, I'm not sure even where to start. It doesn't seem to be as simple as passing the data from one tableView to another...
Thank you for any help.
If you are sharing the same object between (most of the) the view controllers of your tab bar controller, maybe the best architecture for this would be to have one central data object.
A typical pattern is a singleton, some kind of data manager that provides the object, but maybe that is overkill. Another is to keep references to all view controllers and update them one by one when something changes - also not very elegant.
What you really want is something like a global variable. You could (ab)use your app delegate (just give it a property that points to the object) or if you prefer even your tab bar controller (make a subclass, give it a property). In the latter case, every view controller could then get the object like this:
NSManagedObject *object = [(MyCustomTabBarController*)self.tabBarController object];
For example, you can check for changes and refresh your views in viewWillAppear.
A UITabBarController should be handling other view controllers, not handling data objects. How does the tab bar controller get the object reference in the first place? And what is the object you're sharing?
Let each of your subordinate VC's keep a pointer to the object, and then they can each follow the appropriate keypath to get to the entities they're designed to handle.
Tim Roadley's book Learning Core Data for iOS, in chapters 5 and 6, shows how to pass an object from one view controller (a table view) to a detail view. It doesn't sound like that's what you're asking, but just in case...
In response to comment:
I'm looking at a tableview, tap a cell, and then a tab bar controller slides in? That's not the usual visual metaphor for a tab bar; it's meant for changing modes for the entire program. See the Music app for a typical example: songs, playlists, artists.
But if you really need to do it that way, try this (I'm assuming you're using storyboards):
In prepareForSegue: in your tableview controller, tell the destination (tab bar controller) what object it's working with.
In the tab bar controller's -viewWillAppear, tell each of its tabs about the attribute: self.frobisherViewController.frobisher = self.myWidget.frobisher.
You could instead tell each of the component tabs about the top level object: self.frobisherViewController.widget = self.myWidget. But I like the first approach better because there is less linkage. The frobisherViewController now would need to know about both widgets and frobishers.
This ended up being very simple. I was trying to call the object in the child views initWithNibName which doesn't work. I ended up creating a setObject function and calling the properties I wanted in viewWillAppear.
Hope this helps someone.

Wrong View shown (Catel)

I'm trying to open a View with a ViewModel from my MainWindowViewModel.
It works, but all I get is a blank window. It binds the correct title but every other control is missing.
Did anyone have the same problem and found a solution?
You forgot the call to InitializeComponent in your code-behind. Just a tip: create a base class with the Catel behaviors, then use that as a base view. It will keep your actual window code-behind much cleaner.

MVC basics: Should I add a UIViewController, a Delegate or a Source to my custom view?

my question is about view controllers, delegates and all that in general. I feel perfectly comfortable with UIView, UIViewController, Delegates and Sources, like UITableView does for instance. It all makes sense.
Now I have implemented my first real custom view. No XIBs involved. It is an autocomplete address picker very much like in the Mail application. It creates those blue buttons whenever a recipient is added and has all the keyboard support like the original.
It subclasses UIView. There is no controller, no delegate, no source. I wonder if I should have either one of those? Or all, to make it a clean implementation.
I just cannot put my finger on the sense a view controller would make in my case. My custom view acts much like a control and a UIButton doesn't have a controller either.
What would it control in my view's case?
Some of my thoughts:
For the source: currently the view has a property "PossibleAutocompleteRecipients" which contains the addresses it autocompletes. I guess this would be a candidate for a "source" implementation. But is that really worth it? I would rather pass the controller to the view and put the property into the controller.
The selected recipients can be retrieved using a "SelectedRecipients" property. But views should not store values, I learned. Where would that go? Into the controller?
What about all the properties like "AllowSelectionFromAddressBook"? Again, if I compare with UIButton, these properties are similar to the button's "Secure" property. So they are allowed to be in the view.
The delegate could have methods like "WillAddRecipient", "WillRemoveRecipient" and so on and the user could return TRUE/FALSE to prevent the action from happening. Correct?
Should I maybe inherit from UIControl in the first place and not from UIView?
And last but not least: my custom view rotates perfectly if the device is rotated. Why don't all views? Why do some need a controller which implements ShouldAutoRotateToDeviceOrientation()?
Does it make sense what I wrote above? In the end I will provide the source on my website because it took me some time to implement it and I would like to share it as I have not found a similar implementaion of the Mail-App-like autocomplete control in MonoTouch.
I just want to learn and understand as much as possible and include it in the source.
René
I can answer part of your question.
I just cannot put my finger on the
sense a view controller would make in
my case
The ViewController is responsible for handling the View's state transitions (load, appear, rotate, etc) These transitions are used mainly when you use a navigation component (UINavigationViewController, UITabBarController). These components needs to received a ViewController that will handles the view's transitions.
For exemple, when you push a ViewController on a UINavigationViewController, it will cause the ViewDidLoad, ViewWillAppear, ViewDidAppear. It will also cause the ViewWillDisappear, ViewDidDisappear of the current ViewController.
So, if your application has only one portrait view, you don't need a ViewController. You can add your custom view as a subview of the main window.

Updating an AnnotationView Callout after details entered in View Controller that was pushed form the map view

I have a simple maps app with multiple pins on a map view. My intention is to tap a pin, show a callout with an accessory view, push to a Detail View Controller where you can edit that pin/locations details. This all works fine, but once i pop the Detail View Controller the callout on the map view is still there, which i want, but it still has the old uneditied values. How can i refresh/update the callout view once the Detail View Controller is popped?
I am using Core Data with a simple database. I have tried using controllerdidchangecontent, Map View Controller Will Display methods etc but my main problem is identifying which object has been added/updated/deleted and which is the corresponding callout/selected pin.
Any help appreciated...
Not sure if you had find your answer but the way to do it is to extend MKAnnotation class and creating custom annotation and passing them while creating placemarks. Later you can get them from MKAnnotationView's annotation property.
See a good implementation here
http://www.slideshare.net/360conferences/getting-oriented-with-mapkit-everything-you-need-to-get-started-with-the-new-mapping-framework
The only way I could find to update the callout info was to mess directly with the subviews of the callout.
The callout view is the first subview of the annotation view.
In the following example, I update the subtitle.The title label is the 6th and the subtitle is the 7th subview of the callout:
if (myAnnotationView.subviews.count > 0)
((UILabel*)[((UIView*)[myAnnotationView.subviews objectAtIndex:0]).subviews objectAtIndex:7]).text = #"Some example";

Resources