UIPopoverController without arrows? - iphone

I would like to know to make an UIPopoverController without arrows
In fact I would like to simulate something like this:
See that
There is no arrows
There is a title that is somehow inside of a expanded top border of the UIPopoverController and not inside of it like in the normal UIPopoverController.
I assume this is not really an UIPopoverController object but I would appreciate advices on how can I make the same effect (using CoreGraphics? -> specially the translucent degrade effect of the 3D outstanding border) and/or links to some sources if anyone has done this before.
Thanks in advance.
Ignacio
EDIT:
I am still looking for this stuff and realized that even in third party apps is being used
an example is: twitterrific for iPad as seen in this picture.
Anyone please? Putting the title inside the popovercontroller is just ugly.

The below method works fine for me (include iOS7)
[popoverController presentPopoverFromRect:CGRectMake(0, 0, 20, 20)
inView:self.view
permittedArrowDirections:NULL
animated:YES];

Pass 0 to permittedArrowDirections attribute.
[popoverController presentPopoverFromRect:YOUR_RECT
inView:self.view
permittedArrowDirections:0
animated:YES];

While there is some question about whether Apple will approve apps that create a popover without an arrow, you might want to check out this post regarding arrows and this post regarding modal views.

To create a popover with a title you need to create a separate view like you would make a separate window and then load that view in the popover.

The top border is produced by placing a navigation controller between the popover and the presented view controller.
In other words, the popover presents a navigation controller and the navigation controller's root view controller is set to your view controller. This produces the title bar and allows you to set the title with [self setTitle:#"My Title"] and add navigation buttons.

You can add a title by using a UINavigationController, and adding UIViewControllers to the navigation controller. Set the 'title' attribute of the UIViewController to make the title appear.
Setting the arrow direction to NULL, as some have suggested, can result in unpredictable behavior, since the method uses this variable to figure out how to orient the popup relative to your bar button item or rectangle.
It is better to subclass UIPopoverBackgroundView, and set the various arrow return methods to return 0 for the arrows (iOS5 and up only). See this example for how to subclass this properly:
http://blog.teamtreehouse.com/customizing-the-design-of-uipopovercontroller
Simple implementation example (MyCustomPopoverBGView is the subclass of UIPopoverBackgroundView in this example):
UIViewController *vCtrlr = [[UIViewController alloc] initWithNibName:nil bundle:nil];
vCtrlr.title = #"My Title";
self.navCtrlr = [[UINavigationController alloc] initWithRootViewController:vCtrlr];
self.popCtrlr = [[UIPopoverController alloc] initWithContentViewController:_navCtrlr];
_popCtrlr.popoverBackgroundViewClass = [MyCustomPopoverBGView class];
[_popCtrlr presentPopoverFromRect:CGRectMake(0,
0,
320,
150)
inView:self permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];

Just copy & Paste the below code
UIViewController *popovercontroller=[[UIViewController alloc] init];
UIView *popoverView=[[UIView alloc] initWithFrame:CGRectMake(312,390, 400, 344)];
popoverView.backgroundColor=[UIColor whiteColor];
popovercontroller.contentSizeForViewInPopover=CGSizeMake(400, 300);
UIDatePicker *pickerView = [[UIDatePicker alloc] initWithFrame:CGRectMake(0, 44, 400, 0)];
[pickerView setTintColor:[UIColor blackColor]];
[pickerView addTarget:self action:#selector(dueDateChanged:) forControlEvents:UIControlEventValueChanged];
pickerView.datePickerMode = UIDatePickerModeDate;
pickerView.hidden = NO;
NSString *bs ; //= [NSString alloc];
// //NSDate *newDate = [NSData alloc];
bs = CurrentSelectedDate;
if (bs.length >= 1) {
NSDateFormatter* dateFormatter = [[NSDateFormatter alloc] init] ;
// //[dateFormatter setDateStyle:NSDateFormatterLongStyle];
// [dateFormatter setTimeStyle:NSDateFormatterNoStyle];
[dateFormatter setDateFormat:#"dd-MMM-yyyy"];
// NSDate *myDate = [dateFormatter dateFromString: txtText.text];
pickerView.date = [dateFormatter dateFromString: CurrentSelectedDate];
}
else
{
pickerView.date = [NSDate date];
}
[popoverView addSubview:pickerView];
// pickerView.date = [dateFormatter dateFromString:txtText.text];
UIToolbar *pickerToolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, 400, 44)];
pickerToolbar.barStyle = UIBarStyleDefault;
pickerToolbar.barTintColor=[UIColor colorWithRed:150.0f/255.0f green:91.0f/255.0f blue:129.0f/255.0f alpha:1.0f];
[pickerToolbar sizeToFit];
self.navigationController.toolbar.barTintColor = [UIColor colorWithRed:150.0f/255.0f green:91.0f/255.0f blue:129.0f/255.0f alpha:1.0f];
NSMutableArray *barItems = [[NSMutableArray alloc] init];
UIBarButtonItem *flexSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:self action:nil];
[barItems addObject:flexSpace];
UIBarButtonItem *doneBtn = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(doneButtonPressed:)];
doneBtn.tintColor=[UIColor whiteColor];
[barItems addObject:doneBtn];
UIBarButtonItem *cancelBtn = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:#selector(cancelButtonPressed:)];
cancelBtn.tintColor=[UIColor whiteColor];
[barItems addObject:cancelBtn];
[pickerToolbar setItems:barItems animated:YES];
[popoverView addSubview:pickerToolbar];
popovercontroller.view=popoverView;
pickerViewPopup = [[UIPopoverController alloc] initWithContentViewController:popovercontroller];
[pickerViewPopup presentPopoverFromRect:CGRectMake(312, 212, 400, 344) inView:self.view permittedArrowDirections:0 animated:YES];

Related

Make a date picker appear when a user taps a text field

Im trying to follow this post Display datepicker on tapping on textfield and when I get to the point where it says "In the XIB, Pull out a UIToolbar and a UIDatePicker but don't attach it to the view" i get lost. Im using storyboards and he's using xib's. Is that the problem? xib's aren't an option for me. So is there a way to drag a date picker out, but not attach to the view?
The difference with storyboard is that you would use a XIB file (also called NIB) for each view.
But you should be able to follow any instructions.
In the XIB, Pull out a UIToolbar and a UIDatePicker but don't attach
it to the view.
I believe he means not to connect to the ViewController like you would do with a button (IBAction for example)
Since you are showing when you tap the textfield then you have to do it programmatically.
You don't need to add it to your view really.
You can create a viewcontroller that has a date picker at the bottom and a close button at the top.
When tapping the textfield you can just present that viewcontroller modally.
Set delegate methods to the viewcontroller for:
closeButtonClicked: , and dateSelected: ,
and implemet these delegate merhod in the main controller.
In addition, you can "block" the screen by adding the datePicker's viewcontroller background color with certain alpha for a nice affect.
I found that to be the easiest way to do that. No need for a nib
May be it will helpful to you..
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
dateActionSheet = [[UIActionSheet alloc]initWithTitle:#"Select Your Date of Birth" delegate:self cancelButtonTitle:nil destructiveButtonTitle:nil otherButtonTitles:nil , nil];
dateActionSheet.actionSheetStyle = UIActionSheetStyleBlackOpaque;
UIDatePicker *datePicker = [[UIDatePicker alloc] init];
datePicker.datePickerMode = UIDatePickerModeDate;
[datePicker addTarget:self action:#selector(datePickerValueChangedd:) forControlEvents:UIControlEventValueChanged ];
NSDateFormatter *df = [[NSDateFormatter alloc] init];
df.dateStyle = NSDateFormatterMediumStyle;
[dateActionSheet addSubview:datePicker];
[dateActionSheet addSubview:self.datePickerView];
UIToolbar *tools=[[UIToolbar alloc]initWithFrame:CGRectMake(0, 0,320,40)];
tools.barStyle=UIBarStyleBlackOpaque;
[dateActionSheet addSubview:tools];
UIBarButtonItem *doneButton=[[UIBarButtonItem alloc]initWithTitle:#"Done" style:UIBarButtonItemStyleBordered target:self action:#selector(btnActinDoneClicked)];
doneButton.imageInsets=UIEdgeInsetsMake(200, 6, 50, 25);
UIBarButtonItem *flexSpace= [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
NSArray *array = [[NSArray alloc]initWithObjects:flexSpace,flexSpace,doneButton,nil];
[tools setItems:array];
//picker title
UILabel *lblPickerTitle=[[UILabel alloc]initWithFrame:CGRectMake(60,8, 200, 25)];
lblPickerTitle.text=#"Select Date of Birth";
lblPickerTitle.backgroundColor=[UIColor clearColor];
lblPickerTitle.textColor=[UIColor whiteColor];
lblPickerTitle.textAlignment = NSTextAlignmentCenter;
lblPickerTitle.font=[UIFont boldSystemFontOfSize:15];
[tools addSubview:lblPickerTitle];
//cell.detailTextLabel.text = [self datePickerValueChangedd:datePicker];
[dateActionSheet showFromRect:CGRectMake(0,480, 320,215) inView:self.view animated:YES];
[dateActionSheet setBounds:CGRectMake(0,0, 320, 411)];
}
-(void)btnActinDoneClicked {
[dateActionSheet dismissWithClickedButtonIndex:1 animated:YES];
[dateActionSheet removeFromSuperview];
}
-(void)datePickerValueChangedd:(UIDatePicker*) datePicker
{
Youytextfield.text = (NSString *)datePicker.date;
}

How to design an iOS program with custom inputViews

Note, this is a DESIGN question, NOT a functionality question. I already know how to implement the following, I'm just trying to figure out the best way to design it.
I have an iOS app where a few UIViewControllers throughout the app have UITextFields with UIDatePicker input views. The code for this is below:
- (void) viewDidLoad
{
self.dateField.inputView = [self createDatePicker];
}
- (UIView *) createDatePicker
{
UIView *pickerView = [[UIView alloc] initWithFrame:CGRectMake(0, self.view.frame.size.height, self.view.frame.size.width, TOOLBAR_HEIGHT + KEYBOARD_HEIGHT)];
UIDatePicker *picker = [[UIDatePicker alloc] init];
[picker sizeToFit];
picker.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
picker.datePickerMode = UIDatePickerModeDate;
[picker addTarget:self action:#selector(updateDateField:) forControlEvents:UIControlEventValueChanged];
[pickerView addSubview:picker];
// Create done button
UIToolbar* toolBar = [[UIToolbar alloc] init];
toolBar.barStyle = UIBarStyleBlackTranslucent;
toolBar.translucent = YES;
toolBar.tintColor = nil;
[toolBar sizeToFit];
UIBarButtonItem *flexibleSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
UIBarButtonItem* doneButton = [[UIBarButtonItem alloc] initWithTitle:#"Done"
style:UIBarButtonItemStyleDone target:self
action:#selector(doneUsingPicker)];
[toolBar setItems:[NSArray arrayWithObjects:flexibleSpace, doneButton, nil]];
[pickerView addSubview:toolBar];
picker.frame = CGRectMake(0, toolBar.frame.size.height, self.view.frame.size.width, pickerView.frame.size.height - TOOLBAR_HEIGHT);
toolBar.frame = CGRectMake(0, 0, self.view.frame.size.width, TOOLBAR_HEIGHT);
return pickerView;
}
- (void) doneUsingPicker
{
[self.dateField resignFirstResponder];
}
- (void) updateDateField: (UIDatePicker *) datePicker
{
self.dateField.text = [self.formatter stringFromDate:datePicker.date];
}
The problem is, I keep on having to paste this code throughout the app in different classes that have UITextFields with UIDatePicker inputviews. What would be the best way to design this so as to minimize duplicated code. I've thought about having a UIDatePickerableViewController superclass that contains this code, but this doesn't seem extensible. For instance, what if I soon have other types of input views that could be attached to text fields. How should I design this?
You can refactor code/methods shared between the classes in a common superclass, and inherit subclasses inside which you only modify the parts that are needed to be different.
Or, if you approach the problem from a different point of view: create a custom InputWiewWithDatePicker class and move the (self-)configuration and -initialization code inside the - init method of that class. This way you don't have to paste all this everywhere, and only a single line will be duplicated:
customControl = [[InputViewWithDatePicker alloc] init];
My first thought would be to create a new UIView subclass that contains a date picker and text field with the layout you desire. This can be done with a nib or in code. Anyplace you want to add this new kind of view, it's either a one-liner in viewDidLoad, or paint a UIView into a nib and change it's class to your new view class.
Subclass your desired layout, then when you allocate it, it will come with all the options you have defined.

How do i pop up a window when a user taps on the particular row in my application?

How to show a pop up window when the user clicks on the particular field in my table view.
It should pop a window ant it should display the user contact information.
I do not want to use navigationbar controller here.
Kindly help me
I have written code of UIPopOverController with DatePicker as a example for you. just refer this example and set according your need
-(IBAction)tDriveBtnPressed:(id)sender
{
NSDateFormatter *df = [[NSDateFormatter alloc] init];
df.dateStyle = NSDateFormatterMediumStyle;
txtDate.text = [NSString stringWithFormat:#"%#",
[df stringFromDate:[NSDate date]]];
[df release];
UIToolbar *pickerToolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, 300, 44)];
pickerToolbar.barStyle = UIBarStyleBlackOpaque;
[pickerToolbar sizeToFit];
NSMutableArray *barItems = [[NSMutableArray alloc] init];
UIBarButtonItem *doneBtn = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(pickerDone:)];
[barItems addObject:doneBtn];
[doneBtn release];
[pickerToolbar setItems:barItems animated:YES];
[barItems release];
datePicker = [[UIDatePicker alloc] init];
datePicker.datePickerMode = UIDatePickerModeDate;
CGRect pickerRect = datePicker.bounds;
datePicker.bounds = pickerRect;
UIViewController* popoverContent = [[UIViewController alloc] init];
UIView* popoverView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 344)];
popoverView.backgroundColor = [UIColor whiteColor];
datePicker.frame = CGRectMake(0, 44, 320, 300);
[datePicker addTarget:self action:#selector(dateChange:) forControlEvents:UIControlEventValueChanged];
[popoverView addSubview:pickerToolbar];
[popoverView addSubview:datePicker];
popoverContent.view = popoverView;
//resize the popover view shown
//in the current view to the view's size
popoverContent.contentSizeForViewInPopover = CGSizeMake(320, 244);
//create a popover controller
popoverController = [[UIPopoverController alloc] initWithContentViewController:popoverContent];
CGRect popoverRect = [self.view convertRect:[tDriveBtn frame]
fromView:[tDriveBtn superview]];
popoverRect.size.width = MIN(popoverRect.size.width, 100) ;
popoverRect.origin.x = popoverRect.origin.x;
// popoverRect.size.height = ;
[popoverController
presentPopoverFromRect:popoverRect
inView:self.view
permittedArrowDirections:UIPopoverArrowDirectionAny
animated:YES];
//release the popover content
[popoverView release];
[popoverContent release];
}
-(void)dateChange:(id)sender
{
NSDateFormatter *df = [[NSDateFormatter alloc] init];
df.dateStyle = NSDateFormatterMediumStyle;
txtDate.text= [NSString stringWithFormat:#"%#",
[df stringFromDate:datePicker.date]];
[df release];
}
- (void)pickerDone:(id)sender
{
NSDateFormatter *df = [[NSDateFormatter alloc] init];
df.dateStyle = NSDateFormatterMediumStyle;
txtDate.text= [NSString stringWithFormat:#"%#",
[df stringFromDate:datePicker.date]];
[df release];
if (popoverController != nil) {
[popoverController dismissPopoverAnimated:YES];
self.popoverController=nil;
}
}
You can display your new viewController using presentModalViewController method. I use it like this way:
- (IBAction)addNewBuidling:(id)sender
{
NewBuilding *new=[[NewBuilding alloc]initWithNibName:#"NewBuilding" bundle:nil];
new.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
new.modalPresentationStyle=UIModalPresentationFormSheet;
[self.navigationController presentModalViewController:new animated:YES];
new.view.superview.frame = CGRectMake(0, 0, 357 ,117);//it's important to do this after. Take a frame size exactly of your new viewController's size.
new.view.superview.center = self.view.center;
[new release];
}
This is how my NewBuilding viewController will appear on screen.
Edit 1:
In this written in presentModalViewController reference: "On iPhone and iPod touch devices, the view of modalViewController is always presented full screen." so for iPhone it may not serve your purpose.
if you want to display less details then you can use following option.
declare below code in .h file
UIWindow *alertWindow;
Write following code in .m file.
alertWindow = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; // you must release the window somewhere, when you do not need it anymore
alertWindow.windowLevel = UIWindowLevelAlert; // puts it above the status bar
alertWindow.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.5];
/*CUSTOM VIEW obj*/.center = CGPointMake(alertWindow.frame.size.width/2, alertWindow.frame.size.height/2);
[alertWindow addSubview:/*PUT YOUR CUSTOM VIEW HERE*/];
[alertWindow setHidden:NO];
this code is display you custom view like UIAlertView.
you put above code in UITableView Delegate method.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {}
For hide window
[alertWindow setHidden:YES];
[alertWindow release]; alertWindow = nil;

Transitionstyle of UIViewController presented modally

I am using the below statement to define the transitionstyle
_viewController.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
in the below code but the above statement is not flipping horizontally while presenting it modally
#property (nonatomic, assign) UIModalTransitionStyle *modalTransitionStyle;
#synthesize modalTransitionStyle;
self.view = [[[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]]autorelease];
[self.view setFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
_viewController = [[ModalViewController alloc] init];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:_viewController];
UIBarButtonItem * button = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem: UIBarButtonSystemItemDone target:self action:#selector(dismissView:)] autorelease];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:_viewController];
UIBarButtonItem * button = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem: UIBarButtonSystemItemDone target:self action:#selector(dismissView:)] autorelease];
[_viewController.navigationItem setLeftBarButtonItem:button animated:YES];
navigationController.navigationBar.tintColor = [UIColor brownColor];
_viewController.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self.navigationController presentModalViewController:_viewController animated:YES];
Anyone knows that why it is so. When everthing is coded programmtically.
Thanks for help though.
There's a lot of confusing naming going on here.
AFAICT, _viewController is the root view controller of your navigationController. But you reference self.viewController... is this the same view controller? If so, why are you not consistently using accessor methods? If not, it's not clear to me that you setting the modal transition style on the correct view controller ([self viewController] vs. _viewController).
(Btw, please work on formatting your code so that it displays in a more reasonable way when you paste it in.)
Wrong way to approach the problem. I suggest you to review your code in order to improve readability and maintainability.
Supposing that you've a viewcontroller with a target action associated with a button, something like this:
...
[aButton addTarget:self
action:#selector(dismissView:)
forControlEvents:UIControlEventTouchUpInside];
...
You can write a selector method, in order to display your new viewcontroller as follow:
- (void)dismissView:(id)sender {
SecondViewController *secondVC = [[SecondViewController alloc] init];
secondVC.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:secondVC animated:YES];
[secondVC release];
}

UIPopover not displaying correctly from UIButton

I have a UIButton that when clicked, displays a UIPopover with a UIDatePicker in it.
It is supposed to display under button for date of birth, but it is covering it instead.
This is the code I have:
- (IBAction)dateOfBirthButtonPressed:(id)sender{
UIViewController* popoverContent = [[UIViewController alloc] init];
UIView *popoverView = [[UIView alloc] init];
popoverView.backgroundColor = [UIColor blackColor];
UIDatePicker *datePickerTemp = [[UIDatePicker alloc]init];
datePickerTemp.frame=CGRectMake(0,44,320, 216);
datePickerTemp.datePickerMode = UIDatePickerModeDate;
datePickerTemp.maximumDate = [NSDate date];
self.datePicker = datePickerTemp;
[popoverView addSubview:self.datePicker];
UIToolbar *toolbar = [[UIToolbar alloc] init];
toolbar.frame=CGRectMake(0,0 ,320, 40);
toolbar.barStyle = UIBarStyleBlackOpaque;
NSMutableArray *toolbarItems = [NSMutableArray array];
UIBarButtonItem *cancelButton1 = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:#selector(datePickerCancelButtonClicked)];
UIBarButtonItem *doneButton1 = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(datePickerSaveButtonClicked)];
UIBarButtonItem *space = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
[toolbarItems addObject:cancelButton1];
[toolbarItems addObject:space];
[toolbarItems addObject:doneButton1];
toolbar.items = toolbarItems;
[popoverView addSubview:toolbar];
[cancelButton1 release];
[space release];
[toolbar release];
popoverContent.view = popoverView;
UIPopoverController *popoverController = [[UIPopoverController alloc] initWithContentViewController:popoverContent];
popoverController.delegate=self;
self.datePopoverController = popoverController;
[popoverContent release];
[popoverView release];
[self.datePopoverController setPopoverContentSize:CGSizeMake(320, 264) animated:NO];
[self.datePopoverController presentPopoverFromRect:self.dateOfBirthButton.frame inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}
NSLog for frame:
DOB button: {{160, 129}, {329, 37}}
Last name label: {{160, 77}, {329, 31}}
Is your button a subview of your view, or buried within another subview? If it is not a direct subview of your view then your coordinate space is off. Try changing your code to:
CGRect buttonRect = [self.dateOfBirthButton convertRect:self.dateOfBirthButton.frame toView:self.view];
[self.datePopoverController presentPopoverFromRect:buttonRect inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
You can try either one of these to see that fix the problem. The second one fix my problem that is similar to yours.
[self.datePopoverController presentPopoverFromRect:self.dateOfBirthButton.frame inView:self.dateOfBirthButton permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
or
[self.datePopoverController presentPopoverFromRect:self.dateOfBirthButton.frame inView:self.dateOfBirthButton.superview permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];