I know how to show keyboard accessory with UITextField.
textField.inputAccessoryView = keyboardToolBar;
But what if I don't have a UITextField but a button. How do I show a keyboard that has a toolbar?
The toolbar itself will contain a UITextField, which I will have to be first responder programmatically.
But how would that work?
Update
-(void)createKeyboardToolBar
{
self.keyboardToolBar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, 320, 42)];
self.textField = [[UITextField alloc] initWithFrame:CGRectMake(8, 6, 250, 30)];
UIBarButtonItem *textBtn = [[UIBarButtonItem alloc] initWithCustomView:self.textField ];
UIBarButtonItem *postBtn = [[UIBarButtonItem alloc]initWithTitle:#"Post" style:UIBarButtonItemStyleBordered target:self action:#selector(postComment)];
[self.keyboardToolBar setItems: [NSArray arrayWithObjects:textBtn,postBtn,nil]];
self.textField.inputAccessoryView = self.keyboardToolBar;
}
So following the suggestions, I come up with the code above. But when I click the button that is supposed to make self.textField the first responder, the call is made, but the keyboard or the toolbar does not appear. (I use NSLog)
for your button add action as buttonClicked. so when you click on the button show keyboard by using becomeFirstResponder for your textfield.
- (void)buttonClicked {
[myTextField becomeFirstResponder];
}
Alloc the textfield,toolbar globally, and add it to the toolbar.
In the button action write the 'become firstresponder' for the textfield.
Here is the solution
- (IBAction)keyboardaction:(id)sender {
self.keyToolbar_.hidden=NO;
CGRect lframe = self.keyToolbar_.frame;
lframe.origin.y = [[UIScreen mainScreen] bounds].size.height-<keyboardheight>;
[self.entryTxfld_ becomeFirstResponder];
[UIView animateWithDuration:0.3
delay:0
options:UIViewAnimationOptionCurveEaseInOut
animations:^ {
self.keyToolbar_.frame = lframe;
}completion:^(BOOL finished) {
}];
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
CGRect lframe = self.keyToolbar_.frame;
lframe.origin.y = [[UIScreen mainScreen] bounds].size.height;
[UIView animateWithDuration:0.6
delay:0
options:UIViewAnimationOptionCurveEaseInOut
animations:^ {
self.keyToolbar_.frame = lframe;
}completion:^(BOOL finished) {
}];
[textField resignFirstResponder];
return YES;
}
In the XIB for View add toolbar the bottom and to the toolbar added the textfield.For reference find the image.
Related
I'm having a problem with reading taps on navigation bar (I need to open dropdown menu by tapping on title field, just like in telegram and etc. but not in swift)
I know that basically its unreadable, and already've tried with taprecognizer, but it didn't work for me any good.
Now my menu opens with rightbarbutton - that's ugly.
How can I deal with it?
Now string that drops menu (placed in viewDidLoad) looks like:
navbar = [[UIBarButtonItem alloc]initWithTitle:#"navbar" style:UIBarButtonItemStylePlain target:self action:#selector(navigationTitleTapGestureAction:)];
and a part that declares button:
NSArray *buttons = #[navbar <<...a few more buttons...>>];
self.navigationItem.rightBarButtonItems = buttons;
EDIT: additional code from the comments:
- (IBAction)navigationTitleTapGestureAction:(id)sender {
automaticDisappearanceCanceled_ = YES;
if (menuToolbarVisible_) {
[self hideMenuAnimated:YES];
}
else {
[self showMenuAnimated:YES];
}
}
- (void)showMenuAnimated:(BOOL)animated {
[self.view layoutIfNeeded];
self.toolbarTopLayoutConstraint.constant = 0.f;
self.menuToolbar.hidden = NO;
[UIView animateWithDuration:animated ? ToolbarMenuAnimationDuration : 0.f animations:^{
[self.view layoutIfNeeded];
} completion: ^(BOOL finished) {
}];
menuToolbarVisible_ = YES;
}
- (void)hideMenuAnimated:(BOOL)animated {
[self.view layoutIfNeeded];
self.toolbarTopLayoutConstraint.constant = -ToolbarMenuHeight;
[UIView animateWithDuration:animated ? ToolbarMenuAnimationDuration : 0.f animations: ^{
[self.view layoutIfNeeded];
} completion:^(BOOL finished) {
self.menuToolbar.hidden = YES;
}];
menuToolbarVisible_ = NO;
}
As far is I know you just want to get taps on the text on the center of navigation bar you can do this by adding a UIButton in the titleView like this :-
UIButton *centerButton=[[UIButton alloc]initWithFrame:CGRectMake(0, 0, 44.0, 44.0)];
[centerButton setTitle:#"Center" forState:UIControlStateNormal];
[centerButton addTarget:self action:#selector(action) forControlEvents:UIControlEventTouchDown];
self.navigationItem.titleView=centerButton;
I am having one UIButton on navigation bar as right bar button item.
I want to show one view when I click on the UIButton,
and that view should appear animating from right to left and stops to perform some operations for user.
when user is done from his work on the view he will click on same button and view will hide animating from right to left.
I tried to load view normally I get succeed in it,
when I apply animation
view animates from right to left and disappears.
I am new to this animation scenario.
So can anyone please guide me to animate view and show hide action on same button.
Here is the code that I tried,
-(IBAction)showView :(id)sender
{
CGRect screen = [[UIScreen mainScreen]applicationFrame];
UIView *quizInfoViewObj;
quizInfoViewObj = [[UIView alloc]init];
quizInfoViewObj.frame = CGRectMake(70, 0, 250, 480);
quizInfoViewObj.backgroundColor = [UIColor orangeColor];
[UIView beginAnimations: nil context: NULL];
[UIView setAnimationDelegate: self];
[UIView setAnimationDidStopSelector: #selector(pushAnimationDidStop:finished:context:)];
quizInfoViewObj.center = self.view.center;
quizInfoViewObj.center = CGPointMake(self.view.center.x - CGRectGetWidth(self.view.frame), self.view.center.y);
[UIView commitAnimations];
[self.view addSubview:quizInfoViewObj];
}
here how I want...
This code might help you.
-(IBAction)showView :(id)sender
{
UIButton *button = (UIButton *)sender;
if ([button isSelected] == NO) {
CGRect screen = [[UIScreen mainScreen]applicationFrame];
// UIView *quizInfoViewObj; // use this line in .h file variables declaration
quizInfoViewObj = [[UIView alloc]init];
quizInfoViewObj.frame = CGRectMake(self.view.frame.width, 0, 250, 480);
quizInfoViewObj.backgroundColor = [UIColor orangeColor];
[self.view addSubview:quizInfoViewObj];
[UIView beginAnimations: nil context: NULL];
quizInfoViewObj.frame = CGRectMake(70, 0, 250, 480);
[UIView commitAnimations];
}
else {
[UIView beginAnimations: nil context: NULL];
[UIView setAnimationDelegate: self];
[UIView setAnimationDidStopSelector: #selector(pushAnimationDidStop:finished:context:)];
// In pushAnimationDidStop:finished:context method remove quizInfoViewObj from superview
quizInfoViewObj.frame = CGRectMake(self.view.frame.width, 0, 250, 480);
[UIView commitAnimations];
}
[button setSelected: ![button isSelected]];
}
I have a mapView which has a size of (320, 182). Once the UIBarButtonItem is pressed, I would like to show this mapView sliding down from top of the screen. To achieve this, I have written a code like this.
UIBarButtonItem *mapButton = [[UIBarButtonItem alloc]
initWithImage:[UIImage imageNamed:#"map_1.png"]
style:UIBarButtonItemStylePlain
target:self
action:#selector(showMap:)
];
self.navigationItem.rightBarButtonItem = mapButton;
-(void)showMap:(id)sender{
self._mapView = [[MKMapView alloc] initWithFrame:CGRectMake(0,-182,320,182)];
[self.scrollView addSubview:self._mapView];
//show view
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:1.0];
CGRect rect = [self._mapView frame];
rect.origin.y = 0;
[self._mapView setFrame:rect];
[UIView commitAnimations];
}
This will show the map view which slides down from top of the screen. However, how do I make the mapView dismiss when the UIBarButtonItem been pressed on the second time? Moreover, I also would like to dismiss the mapView when tapped outside the mapView.
This is a vary basic implementation of what you are asking for. But it will do the trick.
#import "ViewController.h"
#import "MKMapView.h"
#interface ViewController () {
MKMapView *mapView;
BOOL showingMap;
}
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
//
UIBarButtonItem *mapButton = [[UIBarButtonItem alloc]
initWithTitle:#"Map"
style:UIBarButtonItemStylePlain
target:self
action:#selector(toggleMap:)
];
self.navigationItem.rightBarButtonItem = mapButton;
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(dismissView:)];
[self.view addGestureRecognizer:tapRecognizer];
}
-(void)toggleMap:(id)sender{
if (!mapView) {
mapView = [[MKMapView alloc] initWithFrame:CGRectMake(0,-182,320,182)];
mapView.backgroundColor = [UIColor redColor]; // red background for testing
[self.view addSubview:mapView];
}
CGRect rect = mapView.frame;
rect.origin.y = showingMap ? -rect.size.height : 0;
showingMap = !showingMap;
[UIView animateWithDuration:1.0 delay:0.0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
mapView.frame = rect;
} completion:^(BOOL finished) {
}];
}
- (void)dismissView:(UITapGestureRecognizer*)recognizer {
// bail out since map isn't showing
if (!showingMap) return;
CGPoint pt = [recognizer locationInView:self.view];
UIView *v = [self.view hitTest:pt withEvent:nil];
if (![v isKindOfClass:[MKMapView class]]) {
NSLog(#"dismiss");
[self toggleMap:nil];
return;
}
}
#end
Just reverse the animation (which you should do in the more modern block methods):
rect.origin.y = -182;
[UIView animateWithDuration:1.0 animations^{
self.mapView.frame = rect;
}
Im trying (struggling) to implement a snapchat like error message display for my app (snapchat error messages slide down over the status bar somehow) in iOS7. I cannot for the life of me get my animation to work right. Here is my method that does the animation
- (void)animateHeaderViewWithText:(NSString *)text {
//add header views
[self.headerView addSubview:self.headerLabel];
[self.navigationController.view addSubview:self.headerView];
//Hide the Status Bar
statusBarHidden = TRUE;
[self setNeedsStatusBarAppearanceUpdate];
self.headerLabel.text = text;
[UIView animateWithDuration:.5 delay:0.0 options:UIViewAnimationOptionCurveEaseIn animations:^{
self.headerLabel.frame = CGRectMake(0, 0, 320, 20);
self.headerView.frame = CGRectMake(0, 0, 320, 20);
} completion:^(BOOL finished) {
[UIView animateWithDuration:.5 delay:5.0 options:UIViewAnimationOptionCurveEaseIn animations:^{
//UnHide the Status Bar
statusBarHidden = FALSE;
[self setNeedsStatusBarAppearanceUpdate];
self.headerLabel.frame = CGRectMake(0, -20, 320, 20);
self.headerView.frame = CGRectMake(0, -20, 320, 20);
} completion:^(BOOL finished) {
[self.headerView removeFromSuperview];
[self.headerLabel removeFromSuperview];
}];
}];
}
Only the second half of the animation really works right, the message slides back up fine and the status bar appears underneath it. However, the first half of the animation, when the view slides down, the status bar disappears causing my navigation bar to move up, screwing up my animation. How can I get my navigation bar to stay where it is initially placed, even when the status bar is gone
This code worked in portrait, but would need to be modified to work properly in both orientations. It uses a separate UIWindow as the overlay, so there's no need to hide or unhide the status bar.
#interface ViewController ()
#property (strong,nonatomic) UIWindow *dropdown;
#property (strong,nonatomic) UILabel *label;
#property (strong,nonatomic) UIWindow *win;
#end
#implementation ViewController
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
self.dropdown = [[UIWindow alloc] initWithFrame:CGRectMake(0, -20, 320, 20)];
self.dropdown.backgroundColor = [UIColor redColor];
self.label = [[UILabel alloc] initWithFrame:self.dropdown.bounds];
self.label.textAlignment = NSTextAlignmentCenter;
self.label.font = [UIFont systemFontOfSize:12];
self.label.backgroundColor = [UIColor clearColor];
[self.dropdown addSubview:self.label];
self.dropdown.windowLevel = UIWindowLevelStatusBar;
[self.dropdown makeKeyAndVisible];
[self.dropdown resignKeyWindow];
}
- (IBAction)dropDown:(UIButton *)sender {
[self animateHeaderViewWithText:#"This is my test string"];
}
-(void)animateHeaderViewWithText:(NSString *) text {
self.label.text = text;
CGRect frame = self.dropdown.frame;
frame.origin.y = 0;
[UIView animateWithDuration:.6 delay:0 options:0 animations:^{
self.dropdown.frame = frame;
}completion:^(BOOL finished) {
;
}];
}
In my xib i have set one text box ...when user edit in it i am moving that view little up...but when i return back it to its original postion it not come to its original postion it remain little up then original postion.
Here is viewDidLoad
- (void)viewDidLoad
{
[super viewDidLoad];
if ([self respondsToSelector:#selector(edgesForExtendedLayout)])self.edgesForExtendedLayout = UIRectEdgeNone;
search=FALSE;
UIButton *btnOther = [UIButton buttonWithType:UIButtonTypeSystem]; //UIButtonTypeCustom for image button
[btnOther setTitle:#"Save" forState:UIControlStateNormal];
btnOther.titleLabel.font = [UIFont fontWithName:GZFont size:12.0f];
// [btnSave setImage:[UIImage imageNamed:#"save.png"] forState:UIControlStateNormal];
[btnOther addTarget:self action:#selector(btnSaveAction:) forControlEvents:UIControlEventTouchUpInside];
[btnOther setFrame:CGRectMake(0, 0, 55, 29)];
dataArray=[[NSMutableArray alloc]init];
nameSearchArray=[[NSMutableArray alloc]init];
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:btnOther];
txtCharityName.hidden=YES;
txtCharityMail.hidden=YES;
originalCenter=self.view.center;
}
here is textfield delegate methods.:
- (void)textFieldDidBeginEditing:(UITextField *)textField {
if(textField==txtGratuity){
self.view.center=CGPointMake(originalCenter.x, originalCenter.y-30);
}
}
- (void)textFieldDidEndEditing:(UITextField *)textField {
self.view.center=CGPointMake(originalCenter.x, originalCenter.y);
charityId=#"";
NSLog(#"charityID%#",charityId);
}
and here is screenshot.:
as per this equation
frame.origin = center - (bounds.size / 2.0)
center = frame.origin + (bounds.size / 2.0)
you should add 30 points for textfield to get to correct position.
- (void)textFieldDidEndEditing:(UITextField *)textField {
self.view.center=CGPointMake(originalCenter.x, originalCenter.y+30);
charityId=#"";
NSLog(#"charityID%#",charityId);
}
Edit:
try this in your
- (void)textFieldDidBeginEditing:(UITextField *)textField {
[UIView animateWithDuration:0.25
delay:0.0
options: UIViewAnimationOptionCurveEaseInOut
animations:^{
CGRect frame;
// let's move our textField
frame = textField.frame;
frame.origin.y = frame.origin.y-30;
textField.frame=frame;
}
completion:^(BOOL finished){
if(finished) NSLog(#"Finished !!!!!);
}];
}
and move textfield down after edit
- (void)textFieldDidEndEditing:(UITextField *)textField {
[UIView animateWithDuration:0.25
delay:0.0
options: UIViewAnimationOptionCurveEaseInOut
animations:^{
CGRect frame;
// let's move our textField
frame = textField.frame;
frame.origin.y = frame.origin.y+30;
textField.frame=frame;
}
completion:^(BOOL finished){
if(finished) NSLog(#"Finished !!!!!);
}];
}
Set the textfield frames in viewWillAppear instead of viewDidLoad method.