I just started learning developing an application (primarily) for iPad using MonoTouch. Maybe because of my many years experience in C# world, it makes my switch very difficult, and I feel stupid sometimes. This is very simple thing in C#, but it make me scratch my head...
Popup dialog?
For iPhone, you rarely have this requirement, because whatever you show will occupy the whole screen, so you just create a controller for each popup.
For iPad, I have much more space, and I don't want the whole screen to be occupied with a few controls (e.g. login screen). That's why I want to show it as a popup. I have seen this in other iPad apps.
From what I learned, I need to use UIAlertView or UIActionSheet to do this. But what I don't understand is that, as shown by all the examples I have read, you have to create all the controls from the code.
What I would like to do is to create the UI using IB, and plug it into UIActionSheet. Is it possible? How do I do it?
If this is an iPad-only application, you will want to use a UIPopoverController. This is a popup "window" that contains a view and is linked to an area on the screen, such as a toolbar button or a rectangle (such as the Frame of a UIButton).
To use this, create a new instance of UIPopoverController, using the constructor that accepts a UIViewController and pass the view that you want to show.
Due to garbage collection considerations, make sure that you store the UIPopoverController in a class-level property.
You will probably also want to clean up this property when the popover is closed. To support this, we subclassed the UIPopoverController, added an event that can be hooked by the caller, then overrode the Dismiss method and fire the hooked event, if any, in the overridden method.
Once you instantiate the popover, you will want to show it. You can do this through one of the PresentFromxxx methods. If you are presenting this from a button (not toolbar) you can call PresentFromRect using the button's frame as the rectangle.
The view that is presented can control its size by setting the ContentSizeForViewInPopover property in its ViewDidLoad method.
You can't edit a UIActionSheet or UIAlertView from Interface Builder.
What you can do is create a view in Interface Builder and display it modally over top of your other views, however it sounds like you don't want to occupy the entire screen and this is what would happen. Here is an example of a modal view controller: http://pastebin.com/h221BQdK
I think you should just follow the examples you mention and create a UIAlertView from code, maybe put it a static utility class. I created a MessageBox class to be more like windows, but you can also put text boxes on there for login. Look at the login box on the app store, it is a decent example of what it would look like.
Create a viewcontroller named extraviewcontroller set its height width to 300 * 215 .
and write the code below
inviewdidload
pickerviewTitle = [[UIPickerView alloc] initWithFrame:CGRectMake(0,0, 383, 250)];
pickerviewTitle.delegate = self;
pickerviewTitle.tag = 0;
pickerviewTitle.showsSelectionIndicator = YES;
controller = [self.storyboard instantiateViewControllerWithIdentifier:#"ExtraViewController"];
popovercontroller = [[UIPopoverController alloc] initWithContentViewController:controller];
popovercontroller.delegate = self;
then
UIActionSheet *actionSheet1 = [[UIActionSheet alloc] initWithTitle:#"Title" delegate:self cancelButtonTitle:#"Done" destructiveButtonTitle:nil otherButtonTitles:nil];
actionSheet1.tag = 0;
actionSheet1.actionSheetStyle = UIActionSheetStyleDefault;
[actionSheet1 addSubview:pickerviewTitle];
[actionSheet1 setFrame:CGRectMake(0, 0, 600, 400)];
[controller.view addSubview:actionSheet1];
if ([popovercontroller isPopoverVisible]) {
[popovercontroller dismissPopoverAnimated:YES];
} else {
//the rectangle here is the frame of the object that presents the popover,
//in this case, the UIButton…
CGRect convertedFrame = yourclickbutton.frame;
[popovercontroller presentPopoverFromRect:convertedFrame
inView:self.view
permittedArrowDirections:UIPopoverArrowDirectionRight
animated:YES];
}
Related
I have a Navigation Controller that at times I need to present a subview for entering a password. The issue is that when I do this, it covers up the navigation bar, making going back in the hierarchy impossible to do. I use XIB for this, but it doesn't give me the option of resizing the UIView that adds on it.
if ([student isEqualToString:#"No"]) {
[self.navigationController.view addSubview:password];
[self.navigationController.view bringSubviewToFront:password];
}
Here are a few suggestions (assuming I understand your issue). Given that you are prompting for a password, I'm assuming you would want the user to either a) provide the password or b) cancel entering the password (not simply ignore it). If they do the latter, then the cancel button could be used to dismiss the password subview.
Suggestions:
Add a cancel button to your subview to dismiss the subview
Use a UIAlertView to present a modal dialog to capture the password with cancel button (see below)
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Password" message:#"Enter your password:" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"Ok", nil];
alertView.alertViewStyle = UIAlertViewStyleLoginAndPasswordInput; // masks pwd text
If you're set on your current approach then define the subview similar to the following so that it is offset from the nav bar (or use constraints)
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 200, tableView.frame.size.width, 100)];
It'd be helpful if you could provide a screenshot of what you're seeing and an image of the interface design you're trying to build.
The code above looks a little weird. Using addSubview: to add this type of view to your navigationController will likely have unintended consequences.
I would recommend either:
Building your password-entry UI in a new UIViewController subclass and using pushViewController:animated: to add this new viewController to the view hierarchy.
or
Use an alertView to capture the password entry, by either using the system UIAlertView or by building a custom alertView using a UIWindow.
Let me know if you need further explanation / clarification.
I have designed two ViewControllers - VCLarge and VCSmall. VCSmall is freeform.
When I display VCSmall on top of VCLarge - I shows full screen.
So I play tricks and change the formSize in ViewWillAppear - The VCLarge still does show (I see black)
FYI - I do this when the ViewControllers are in a storyboard and have no problem.
IF you want to present your viewcontroller like UIPopover controller like below...
Please see this OpenSource FPPopver.
It is perfect and works fine.
Very easy to implement.
https://github.com/50pixels/FPPopover
YourViewController *controller = [[YourViewController alloc] init];
//our popover
FPPopoverController *popover = [[FPPopoverController alloc] initWithViewController:controller];
[popover presentPopoverFromView:okButton];
That's all.
If you want to get rid off that ARROW tip, you can do that too!
you use [UIView addSubview] to show it on top of VCLarge.
For example, if you're within VCLarge, you would do something like this:
UIView *smallView = [VCSmall alloc] init...
[self.view addSubview:smallView];
You can adjust the size and or position of smallView using appropriate CGRects for smallView.
I am looking for a way to implement this kind of popover.
Are there basic iOS commands to generate this style instead of the usual Arrow + Border popover that we see in XCode? Or is there an API to do this kind of thing.
The popover is coming up from the bottom of the screen, just like in the App Store animation sometimes.
Thank you
What you want to do is create a custom UIVIewController with the modal presentation style set to UIModalPresentationFormSheet:
YourCustomViewController *customVC = [[YourCustomViewController alloc] initWithNib:#"YourCustomViewController" bundle:nil];
customVC.modalPresentationStyle = UIModalPresentationFormSheet;
[self self presentViewController:customVC animated:YES completion:nil];
You will also have to create a toolbar and format it correctly with a "close" or "done" button that will dismiss the view controller
I have a UIPopoverController with two view controllers inside of it. I'm building it like so:
CommentsPopoverController *commentsPopoverController = [[CommentsPopoverController alloc] init];
self.delegate = commentsPopoverController;
commentsPopoverController.navigationItem.title = #"Comments";
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:commentsPopoverController];
popover = [[UIPopoverController alloc] initWithContentViewController:navController];
Inside my commentsPopoverController I have this:
commentsViewController = [[CommentsViewController alloc] init];
commentsViewController.view.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
addCommentsViewController = [[AddCommentViewController alloc] init];
addCommentsViewController.view.frame = CGRectMake(0, commentsViewController.view.bounds.size.height - 200, 320, 346);
addCommentsViewController.view.backgroundColor = [UIColor darkGrayColor];
[self.view addSubview:addCommentsViewController.view];
[self.view addSubview:commentsViewController.view];
So when I first load the popover, the addCommentsViewController is hidden by the commentsViewController. When I reveal it, it looks like this:
So far so good. The problem I'm having is that from here, when the user rotates the device or shows the keyboard or shows the keyboard THEN rotates the device things start to get out of whack. The top view controller (commentsViewController) which is a UITableView always does the right thing no matter what the orientation is or whether or not the keyboard is showing. But the bottom view controller (addCommentsViewController) doesn't automatically change it's origin.y to stay directly under the top view controller.
So I've basically had to hack the crap out of my code to keep the addCommentsViewController directly under the commentsViewController by constantly calculating the height of the top view controller so that I could adjust the bottom view controller's origin.y. This involved dropping in NSNotifications for the keyboard's show/hide state and for the device's orientation and constantly recalculating. Very hackish and ugly.
So my question (finally) is: Is there an easier way of controlling these views or am I stuck hacking it the way I did?
To handle rotation, there are two appropriate techniques. One is that you make CommentsPopoverController's view a subclass of UIView that overrides layoutSubviews to lay out your two views properly. The other is that you define viewDidLayoutSubviews on CommentsPopoverController to lay out your views. If you lay out your views in either of these methods, you shouldn't have to subscribe to rotation notifications.
As for moving your view out from under the keyboard, that is discussed in the Text, Web, and Editing Programming Guide for iOS. Part of the technique involves subscribing to keyboard will show/did hide notifications.
I assume your CommentsViewController is a subclass of UITableViewController, because UITableViewController takes care of adjusting the table view when the keyboard is hidden or shown.
I am writing an iPad app that requires the user to enter names and addresses and would like to use ABNewPersonViewController as the interface. The documentation says that this view controller should only be used from within a navigation controller. Is there anyway I can use just the ABNewPersonViewController in a subview (with a navigation controller) without it taking over my whole screen? I assume I can do this easily enough in a popover but I would prefer to have it integrated into my interface... Thanks for any help you can provide!
Consider presenting your UINavigationViewController by presentModalViewController:animated: and change modalViewPresentationStyle to UIModalPresentationPageSheet.
See the reference : http://developer.apple.com/library/ios/#documentation/uikit/reference/UIViewController_Class/Reference/Reference.html
Well, after much looking into this, it does not see that there is any way to use the address book UIs in a subview but they do work quite well in a popover view. However, this popover needs to be exactly 320x460 pixels or some other number with the same aspect ratio for the "add photo" to work correctly (otherwise the photo is stretched). In the popover's view controller viewDidLoad method I added:
self.picker = [[[ABNewPersonViewController alloc] init] autorelease];
self.picker.newPersonViewDelegate = self;
self.navigationController = [[[UINavigationController alloc] initWithRootViewController:self.picker] autorelease];
self.navigationController.view.frame = CGRectMake(0.0, 0.0, self.view.frame.size.width, self.view.frame.size.height);
[self.view addSubview:self.navigationController.view];
This seems to work fine. Let me know if you know of something better.