I'll be using a datePicker several places in my app. I don't want to "clutter" up each and every viewController with the delegation methods for the UIPickerViewDelegate and UIPickerDatasource, plus I would be doing the same delegation methods over and over again.
Every time the datePicker is in play it's sole purpose is to slide halfway up the screen, let the user select a date and then disappear again.
I was contemplating a wrapper viewController (DatePickerViewController) that implemented the datePicker delegate methods, then did a NSNotification with the value which the user selected, which again was caught by the viewController instantiating the DatePickerViewController.
This would make me a decoupled datePicker and let the viewController instantiating the datePicker know nothing of a DatePickerDelegate, but just know that there would potentially come a notification containing an NSDate. Seems rational to me, like something I would do in other languages. But please correct me if Im digging myself a hole here:)
As I started breaking this down I ran into some difficulties, Im not very experienced in Objective C and Cocoa.
I can build a viewController that in it's viewDidLoad presents a datePicker, running just this will result in a blank white screen with a datePicker in the bottom half of the screen. If I use "presentModalViewController" from the viewController that instantiates the (custom) DatePickerViewController, it of course slides up and covers the whole screen. I would like for the user to still have half the view visible. Much like setting the time in an event in the iCal app. (except they push a new viewController onto the stack). Ahh just realized that what I mean is exactly like the keyboard when it slides in and covers half the screen.
So I guess my main problem is: can you build a viewController that behaves like the keyboard when added to a view. But do all this in the ViewController that is added instead of in the controller instantiating the view.
Hope it makes sense:)
Thank you
(1) Put the picker in a model (edit: should be modal) view. This is how the keyboard is implemented.
(2) The picker controller/delegate should only control the model view and the picker.
(3) In the delegate create two properties such as:
id *target;
Selector theSelector;
and a method like:
-(void) sendPickerResultsTo:(id) theTarget forSelector:(SEl) theSelector;
(4) Before displaying the picker model view, set the target to the calling controller and the theSelector to a method in the calling controller. You can configure the selector method to pass an arbitrary amount of data. It would look something like:
-(void) pickerResults:(NSArray *) pickerResults; //could pass any value as long as it's an object
[Note: this is kind of thing you define a protocol for if you use it a lot]
(5) When you have the picker value just have the picker delegate call:
[self.target performSelector:theSelector withObject:anArrayOfPickerResults];
(5) Add the appropriate method to any controller that needs to evoke the model picker view and set the controller as the target before you display the model picker view.
This will give you a self-contained model picker view that you can attach to any view and which can send its results to any arbitrary object that implements a method with the right signature i.e. implements the protocol.
This is basically a do it yourself version of UIControls addTarget:action:forControlEvents:
Related
I am looking at Apple's Date Cell (Date Cell Link) example project and I have a question about the Scene Dock in MyTableViewController. How come there are items extra items in the scene (Like Picker and Done) that are next to First Responder, Exit, and My Table View Controller? How can this be done? Also, how is this helpful?
This image shows the Scene Dock that I am referring to. Don't mind the titles, I renamed the project.
This image shows the Scene Outline for MyTableViewController, where the Picker and Done Button are shown next to the My Table View Controller, First Responder, and Exit and not within My Table View Controller.
This image shows an expanded outline for My Table View Controller where the Picker object is found also. But not Done Button is nowhere to be found inside My Table View Controller.
This image shows the code to connect to Picker and Done Button There is nothing special to this.
When I delete UIDatePicker in the scene of the controller (not in the cell), the inline DatePicker still works.
I think this sample is meant to support iOS 6.1 or earlier, to reveal the UIDatePicker as an external slide-in view, so it needs to be in the controller for IBOutlet connection.
Hope this will help.
Normally, the MyTableViewController should not be of type UITableViewController but its superclass UIViewController. This is normally necessary because UITableViewController has by definition its main view property set to the table view. It is then difficult to place other views into this view.
With a UIViewController, however, you can add any number of views. This is necessary in this case to accommodate the button and picker. The table view controller functionality can still be achieved by manually adding the UITableViewDataSource and UITableViewDelegate protocols and overriding the appropriate methods.
However, Apple here shows that it is possible by placing the other views on the same level as the main view, the table view. This is admittedly quite confusing. I usually prefer adding non-standard views as subviews to the view of a plain UIViewController.
You can drag things like picker views from the library to the scene dock to add them there.
As to the utility of doing this, I have no idea what that would be.
In this case I think that the picker and done button are left over from the writers of the code experimenting with ideas and forgetting to delete them. To verify that just delete the picker view and done button and see if everything still works.
This is maybe a simple question, but I don't have a clue the keyword i had to search for this...
I want to create a simple selector (I called it spinner in Android). This is what i want to achieve
Or it will take a whole screen if it's in ipod touch / iphone.
So, I have 3 button that represent filter (category, country, sort) for a ListView... and if I press one of the button, a popover / dialog should be appear to select the filter for each button.
thanks...
Please let me know if I need to add some information to make the question clear.
Its not so much typical that is it appearing.
Create a new UIViewController class with xib and adjust view size you want to display for combo box or popviewControoler. Then put navigation controller over and tableviewController.
And customize your UIViewController using its controller class. Controller class will be reponsible for displaying and selecting data.
Now in your MainViewController From where you want to show ComboBox or popviewcontroller.
declare popViewController instance variable,synthesize it.
implement a userdefined method here alloc your popviewcontroller class and assign it to popviewController instance variable of your class.
Then called it didSelectRowAtIndexPath.
When popover dismiss you set popViewController result in instance variable of this class so it can easily access in MainViewController class.
You can achieve combo box like functionality by adding a UItableView in a UIView and implement all the delegates of UITableView in that custom view.
Now you can add object of that custom UIView where ever you want that combo. Just you have to workout with some Frame setting.
Is it possible to get a double picker to appear from the bottom of a screen when a certain button is selected? And is it possible to remove a value from a picker if it was already selected?
Of course it's possible. I did that for an app just this summer. But you'll have to code the component yourself.
My suggestion is to create a class which has a UIPickerView member; this class, when instantiated and sent a message (like -showInView:), will make the view slide up. You'll need to have a delegate protocol for the class; it will probably make sense to have its delegate also implement UIPickerViewDelegate and UIPickerViewDataSource.
I am experimenting with the splitViewController, introduced for iPads and am stuck at a point. I have a button on my detail view of the splitViewController, clicking on which a modal view opens. Now I want to change the positoning of UI controls on the detail view when the modal view gets dissmissed.
A pretty obvious way of doing this would be to catch the view transition in the ViewWillAppear method of the detailView. But it's not being called in this case. I remember facing the same problem in tabBarController where [tabBarController viewWillAppear:animated] was needed to be set before viewWillAppear of views in each tab item got called. I tried doing this with the splitViewController as well, but this doesn't seem to to work.
Any Ideas??
If the positioning is required due to an action that occurred in the modal view, you should use an explicit delegate callback. That will allow you to clearly specify the control flow and resulting behaviour of your app.
You should then define a protocol that has specific methods that carry pertinent information about the action taken. When the action occurs in the modal, perform the protocol method on the delegate, and it can react to that event (for you it seems to be a re-layout of button positioning).
To get an idea of the methods that are abstract enough to handle generic modal behaviour, look at UIAlertViewDelegate protocol. Here the delegate will get an alertViewCancel: message when the user decides to take no action, or alertView:didDismissWithButtonIndex: when they selected one of the options presented to them.
That is a good start for how to define the protocol.
If you need a many view controllers to react to the action taken in the modal, say a Sign In modal, then a better mechanism is notifications.
I'm a newbie doing Objective-C, coming from Flex/Actionscript development.
I have an iPhone app with an UIApplicationDelegate conforming delegate called MyAppDelegate - it has a UIWindow.
Instead of adding buttons, labels and whatnot directly to the window, I guess I'm supposed to make a child class of UIViewController for every screen I wanna make. When that screen should be displayed, I add the respective controller's view to the window as a subview. When another screen should be displayed, I should pop off any other view from the window and add the new view. Hope I got everything correct so far...
My intent is to make each view controller only know about its own things, so let's say I wanna call view A from view B, in ActionScript I'd add a button in A firing off an event which would be caught in view A's owning object (could be the application), which could take proper action (remove view A, instantiate view B and display it).
How do I do this in Objective-C?
A UIControl, such as UIButton, can have any number of event listeners registered with:
- (void)addTarget:(id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents;
The target would be the view controller you want to receive the method, and the action is the method you want called. For a button, events is usually just UIControlEventTouchUpInside. If the target is nil, the event will pass up the responder chain until a responder implements the action. If you pass #selector(buttonClicked:) then the target should have this method:
-(IBAction) buttonClicked:(id)sender;
The sender will be the button that was clicked. IBAction is equivalent to a void return type. You can bind the action in Interface Builder if you prefer that to doing it programmatically.
When another screen should be
displayed, I should pop off any other
view from the window and add the new
view.
This is basically correct, but usually you use a meta view controller like UINavigationController to manage view controllers. Even if you do not use the UI that a meta controller might present, it is convenient to have view switching managed for you.
If you're coming from Actionscript you may be interested in looking at the PureMVC framwork for objective C. Using PureMVC you'll create a combination of Mediators, Commands, and Models for application interaction.
With PureMVC you register notification with the facade, and you define listeners in your mediators to respond to these. This is pretty close to the event model you're used to in Actionscript. (At my last job we added some categories to the UIResponder to remove some of the cruft in doing this). If you're creating a considerably sized application, then I would recommend you give it a look; it certainly helped us keep everything manageable.
If you don't want to pull in a third party library then you should define your view manipulation code in your MyAppDelegate and use the [UIApplication sharedApplication] class method to access the globally shared instance.