I want to do something like the keyboard show/hide so I want to set up picker as a first responder. Is this possible. If not how can i show/hide UIPicker in a view by a button click. On other topic how can i format the DatePicker output, now i get "2011-12-8 23:00 000000"
You could have your UIPicker below your sceen (say, y = 480 for iPhone), and then when you tap your button move it to 480 - picker.frame.size.height so that it shows right above the bottom of your screen.
You can achieve the animated effect by using UIView animations as:
// Pre OS4 way
[UIView beginAnimations:#"animName" context:NULL];
[UIView setAnimationDuration:0.2];
CGRect f = picker.frame;
if (showingPicker) {
f.origin.y = 480;
}
else {
f.origin.y = 480 - picker.frame.size.height;
}
picker.frame = f;
[UIView commitAnimations];
// Post OS4 way - Block based
[UIView animateWithDuration:0.2 animations:^{
if (showingPicker) {
f.origin.y = 480;
}
else {
f.origin.y = 480 - picker.frame.size.height;
}
picker.frame = f;
}
And for the DatePicker output you can use an NSDateFormatter. You can use predefined date and time styles or use setDateFormat:(NSString *)format to specify the format yourself.
After that all you do is call your [formatter stringFromDate:datePicker.date];
You can find a complete source code how to use UIDataPicker here.
Related
I'm having a peculiar problem. I have a view with two UITextFields that start out 280px wide. On focus, I want them to shorten to reveal a button - I'm doing that with the following code:
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
CGRect revealButton = CGRectMake(textField.frame.origin.x, textField.frame.origin.y, 221, textField.frame.size.height);
[UIView beginAnimations:nil context:nil];
textField.frame = revealButton;
[UIView commitAnimations];
NSLog(#"%f",textField.frame.size.width);
}
Once editing has ended, they should go back to their original frame:
- (void)textFieldDidEndEditing:(UITextField *)textField
{
CGRect hideButton = CGRectMake(textField.frame.origin.x, textField.frame.origin.y, 280, textField.frame.size.height);
[UIView beginAnimations:nil context:nil];
textField.frame = hideButton;
[UIView commitAnimations];
}
The first time I focus a text field, it works perfectly. However, if I focus the first text field after focusing something else (for example, if I focus the first text field initially, focus the second, and then refocus the first, or if I initially focus the second and then focus the first), it simply won't change its frame. Even more puzzling is the fact that it will log 221 as its width - it just won't show that on the screen. Furthermore, this problem doesn't apply to the second text field.
Any ideas? Thanks in advance...
That's strange, I ran a quick test using two text fields with the exact same code and works every time.
I'd suggest deleting the text fields and connections and rebuild them. Clean all targets and try again.
Edit according to your comments:
If you're using Auto Layout you must not modify the frame of the text fields directly. The actual frames of UI elements are calculated by the system.
For your purpose I'd suggest to set up a width constraint for every text field. Make sure that you only have a left or right spacing constraint not both in addition to the width constraint. To animate it use the following code:
- (NSLayoutConstraint *)widthConstraintForView:(UIView *)view
{
NSLayoutConstraint *widthConstraint = nil;
for (NSLayoutConstraint *constraint in textField.constraints)
{
if (constraint.firstAttribute == NSLayoutAttributeWidth)
widthConstraint = constraint;
}
return widthConstraint;
}
- (void)animateConstraint:(NSLayoutConstraint *)constraint toNewConstant:(float)newConstant withDuration:(float)duration
{
[self.view layoutIfNeeded];
[UIView animateWithDuration:duration animations:^{
constraint.constant = newConstant;
[self.view layoutIfNeeded];
}];
}
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
float newWidth = 221.0f;
NSLayoutConstraint *widthConstraint = [self widthConstraintForView:textField];
[self animateConstraint:widthConstraint toNewConstant:newWidth withDuration:0.5f];
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
float newWidth = 280.0f;
NSLayoutConstraint *widthConstraint = [self widthConstraintForView:textField];
[self animateConstraint:widthConstraint toNewConstant:newWidth withDuration:0.5f];
}
In the Comcast Xfinity iPad app, there is a small button called "Filter by" at the bottom of the screen.
When a user touch the button, a overlay menu will slide up (like the menu UI in Android).
Can anyone give me some hints about how to create this kind of overlay menu?
Thanks.
For this you can create a UIView in your nib and make it look like the menu you need, then in viewdidload you can set its origin to be just off the screen and when you want it to appear just use an animation to slide it up into view and then slide it back off the screen when you're done.
In viewDidLoad:
CGRect frame = [your_menu_view].frame;
frame.origin.y += frame.size.height;
[your_menu_view].frame = frame;
When you are ready to show it:
NSTimeInterval animationDuration = 0.3;//play around with the animation length here
CGRect frame = [your_menu_view].frame;
[UIView beginAnimations:#"MenuSlideIn" context:nil];
[UIView setAnimationDuration:animationDuration];
frame.origin -= frame.size.height;
[your_menu_view].frame = frame;
[UIView commitAnimations];
Then use the same to get rid of it except subtract add its height.
haven't tested it but it should work.
I have a UISegmentedControl on one of my pages. I want an editbox to appear when a segment is clicked right below the clicked segment. I would like it to be animated (slide in or something)
Is this possible? What would be the best way to do this?
Damn.I forgot to mention all this action is going to occur within a cell and not a simple view.
You may try UIView animation.
Firstly set your editbox (UITextView I guess ??) to x coordinate 320 (so it will not appear).
Secondly when user hit the segmented control just translate your UITextView using UIView animation :
[UIView beginAnimation:nil context:nil];
[UIView setAnimationDuration: 1.0];
CGAffineTransform trans = CGAffineTransformMakeTranslation(-320, 0);
self.view.transform = trans;
[UIView commitAnimations];
Hope it will help you ;) .
Ok, so I will try to be more precise, I guess you are using Interface Builder ?
So you have to "link" an action to you UISegmentedController, so in your class write this method :
-(IBAction) translateMyView
{
//If the first segment is selected do translation of the cellView
if(yourSegmentedController.selectedSegmentIndex == 0)
{
[UIView beginAnimation:nil context:nil];
[UIView setAnimationDuration: 1.0];
//This will translate the view to its position from its position -320 px
CGAffineTransform trans = CGAffineTransformMakeTranslation(-320, 0);
//Replace self.view with the view you want to translate.
self.view.transform = trans;
[UIView commitAnimations];
}
else if(yourSegementedController.selectedSegmentIndex ==1)
{
//Do same thing that above but with another view
}
}
So this is the action that occure when you select an index in your segmentedController.
What you have to do is linking this action to your UISegmentedController in Interface Builder.
Hope it will be helpfull ;-)
Heey,
In my iPad application I have a UIPopoverController with a UIViewController containing some textfields.
When the keyboard comes up, the Popover gets animated to fit. Does anybody know how to disable this?
Thanks
I dont think you can except make the popovers smaller in height...Its done like that so when your keyboard pops up none of the popover gets covered by it (thus it shrinks back), however i have found it to be annoying at times since it messed with table views (not making them able to scroll all the way and having to resize them)
It would be great if it did actually animate to better part of the screen, I think you mean it actually shrinks the popUp which is mostly not good.(which i see during rotation in my case). You can not keep the popUp from squishing, UNLESS you move a view. The best way to handle this is to temporarily move your entire main UIView of the whole screen up with the keyBoard by the difference between the size of your pop up, and how much that pop up would shrink if you did not move it up... you can't just move it up by the size of your keyboard, because popUps up high would then also be effected. This code below is for when the keyboard rotated, similar code for when it is first introduced. easy to do, EXCept for when you rotate the screen, then things get tricky...
in otherwords, sometimes your UIView will not move at all, sometimes it will move up by a good 170 points.
//-----------------finding the keyboard top (also used on "didRotate")----very handy,
// took me hours to figure out an absolute always work topOfKeyboard, so here you go.-------
//--------------------------------------------------------------------------------
- (void)keyboardWillShow:(NSNotification*)notification
{
NSLog(#" keyboardWillShow");
UIWindow *keyWindow = [UIApplication sharedApplication].keyWindow;
NSDictionary* info = [notification userInfo];
keyboardRect = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
keyboardRect = [(UIView*)keyWindow convertRect:keyboardRect toView:mainViewController.view];
keyboardIsVisible = TRUE;
topOfKeyboard = keyboardRect.origin.y;
the tricky part is finding the PopUp bottom, because there appears to be code in the popup itself or the convertRect:toView: code that makes the origin flaky , (if you try to "view" origin after a "convertRect:toView:" code), it wants to move and be in different spots during rotation,(or one of it's super views) so bottom calc comes out different some times,(not predicable) because of async process of the rotation of different elements possibly because the popUp itself has many superviews down in the pop up. (to see problem in action with pop up and, must have keyboard effecting popup, move the whole view up then log the "origin" and "size" of popUp after the "convertRect:toView:" code)... the "origin" i'm talking about is the origin of the frame after it is translated to the main view (or atleast a couple views up) with the "convertRect:toView:" code....
update:(it appears if you move down about 3 superviews from the popUp, the flakiness goes away... (this code below was in a "didRotate" ipad type of code. That is that the popUp has several superviews before you can get to the one that is projected ontop of the proper frame
UIPopoverController probably should have a property that has the origin that is predicted after a rotation in it, in a type of "will rotate" kind of code, (because of the keyboard problem), instead of just the "popoverContentSize", (also should include the popoverContentSize that would have been without the keyboard as another variable, ".. anyway This is how I had to do it, see code below.
//--------------------------------------------------------------------------------
- (void) checkRotation
{
NSLog(#" ");
NSLog(#"checkRotation");
if (wasOffset)
{
wasOffset = false;
[UIImageView beginAnimations:nil context:NULL];
[UIImageView setAnimationDuration:0.2f];
CGRect frame = carousel.frame;
frame.origin.y += offset;
carousel.frame = frame;
[UIImageView commitAnimations];
[popPickerController presentPopoverFromRect:zoneButton.frame inView:[zoneButton superview] permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}
if (popPickerController.popoverVisible)
{
if (keyboardIsVisible)
{
wasOffset = false;
[popPickerController presentPopoverFromRect:zoneButton.frame inView:[zoneButton superview]
permittedArrowDirections:UIPopoverArrowDirectionAny animated:NO];
upView3 = [[[popPickerController.contentViewController.view superview] superview] superview]; //hey it works... :o)
//NSLog(#" ");
//NSLog(#"upView3.frame.origin.x = %f",upView3.frame.origin.x);
//NSLog(#"upView3.frame.origin.y = %f",upView3.frame.origin.y);
//NSLog(#"upView3.frame.size.height = %f",upView3.frame.size.height);
//NSLog(#"upView3.frame.size.width = %f",upView3.frame.size.width);
//NSLog(#" ");
popUpRect.origin.x = upView3.frame.origin.x;
popUpRect.origin.y = upView3.frame.origin.y;
popUpRect.size.height = popUpSize.height;
popUpRect.size.width = popUpSize.width; //you must save the size because the keyboard destroys it before you can use it. very tricky....
//NSLog(#" ");
//NSLog(#"popUpRect.origin.x = %f",popUpRect.origin.x);
//NSLog(#"popUpRect.origin.y = %f",popUpRect.origin.y);
//NSLog(#"popUpRect.size.height = %f",popUpRect.size.height);
//NSLog(#"popUpRect.size.width = %f",popUpRect.size.width);
//NSLog(#" ");
//NSLog(#" ");
//NSLog(#"keyboardIsVisible = %d", keyboardIsVisible);
//NSLog(#" ");
//NSLog(#"keyboardRect.origin.x = %f",keyboardRect.origin.x);
//NSLog(#"keyboardRect.origin.y = %f",keyboardRect.origin.y);
//NSLog(#"keyboardRect.size.height = %f",keyboardRect.size.height);
//NSLog(#"keyboardRect.size.width = %f",keyboardRect.size.width);
//NSLog(#"topOfKeyboard = %f",topOfKeyboard);
CGFloat bottomOfPicker = popUpRect.origin.y + popUpRect.size.height - amountShadowCanEncroach;
//NSLog(#" ");
//NSLog(#"bottomOfPicker = %f",bottomOfPicker);
//NSLog(#"topOfKeyboard = %f",topOfKeyboard);
//NSLog(#" ");
if (bottomOfPicker > topOfKeyboard)
{
wasOffset = true;
offset = bottomOfPicker - topOfKeyboard;
NSLog(#"offset = %f",offset);
[UIImageView beginAnimations:nil context:NULL];
[UIImageView setAnimationDuration:0.2f];
CGRect frame = carousel.frame;
frame.origin.y -= offset;
carousel.frame = frame;
[UIImageView commitAnimations];
}
}
[popPickerController presentPopoverFromRect:zoneButton.frame inView:[zoneButton superview] permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}
}
and moving the main UIView back
//-----------------------------------------------------------------------------
- (void) searchDidEndEditing
{
NSLog(#"searchDidEndEditing");
keyboardIsVisible = false;
if (wasOffset)
{
wasOffset = false;
[UIImageView beginAnimations:nil context:NULL];
[UIImageView setAnimationDuration:0.2f];
CGRect frame = mainView.frame;
frame.origin.y += offset;
mainView.frame = frame;
[UIImageView commitAnimations];
if (zoneButton.selected)
[popPickerController presentPopoverFromRect:zoneButton.frame inView:[zoneButton superview] permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}
}
Is there a way to make a keyboard disappear without resignFirstResponder? I have a UITextField, and I'd like it to be able to accept new text and still have the insertion point (flashing cursor) visible without the keyboard being on screen.
When I perform a [textField resignFirstResponder] I can still insert text, by appending to the textField.text, but I can't see the insertion point anymore.
Is there a standard way to make the keyboard animate out, while having my textField remain first responder?
Thanks.
Found an answer to this question. It's not standard though, and like Dave says, may be taboo for the app reviewers. Using the code from this page as a starting point:
http://unsolicitedfeedback.com/2009/02/06/how-to-customize-uikeyboard-by-adding-subviews/
I added in an animation block. You can dismiss the keyboards view with a standard looking animation, but whatever is first responder will retain that status. Really, the keyboard is just hidden off screen.
- (void)hideKeyboard
{
for (UIWindow *keyboardWindow in [[UIApplication sharedApplication] windows]) {
// Now iterating over each subview of the available windows
for (UIView *keyboard in [keyboardWindow subviews]) {
// Check to see if the view we have referenced is UIKeyboard.
// If so then we found the keyboard view that we were looking for.
if([[keyboard description] hasPrefix:#"<UIKeyboard"] == YES) {
// animate the keyboard moving
CGContextRef context = UIGraphicsGetCurrentContext();
[UIView beginAnimations:nil context:context];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationDuration:0.4];
// remove the keyboard
CGRect frame = keyboard.frame;
// if (keyboard.frame.origin.x >= 0) {
if (keyboard.frame.origin.y < 480) {
// slide the keyboard onscreen
//frame.origin.x = (keyboard.frame.origin.x - 320);
// slide the keyboard onscreen
frame.origin.y = (keyboard.frame.origin.y + 264);
keyboard.frame = frame;
}
else {
// slide the keyboard off to the side
//frame.origin.x = (keyboard.frame.origin.x + 320);
// slide the keyboard off
frame.origin.y = (keyboard.frame.origin.y - 264);
keyboard.frame = frame;
}
[UIView commitAnimations];
}
}
}
}
I wrote in code to dismiss the keyboard to the left and to the bottom of the screen. I don't know what will happen when you eventually resignFirstResponder, but it might be an idea to reset the keyboard frame when you do that.
If there is, then it's not documented in the iPhone API. Also, what you're asking for does not make sense. You want to have the insertion point in a UITextField. OK, great. But you also want the keyboard to go away? Then what's the point of the textfield having the focus? How are you going to input data into the textfield? If you want to have a custom keyboard, then just display it on top of the keyboard. I can't think of a good reason why you'd want the cursor to be visible but not have some sort of data entry mechanism. That would break UI convention and might even get your app rejected.