Next/Previous Keyboard Toolbar iOS7 - ios

Currently, I am trying to set the next/previous buttons on my keyboard toolbar to the new, sleek iOS 7 back button/forward buttons that get put in navigation controllers to go back. Here is what I am trying. How can I use the system bar button item instead of the boring static text?
[self setToolbar:[[UIToolbar alloc] initWithFrame:self.frame]];
[self.toolbar setBarStyle:UIBarStyleDefault];
[self.toolbar setAutoresizingMask:(UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleWidth)];
[self addSubview:self.toolbar];
[self setSegmentedControl:[[UISegmentedControl alloc] initWithItems:#[ NSLocalizedStringFromTable(#"Previous", #"BSKeyboardControls", #"Previous button title."),
NSLocalizedStringFromTable(#"Next", #"BSKeyboardControls", #"Next button title.") ]]];
Here is what it looks like now:
Here is what I want it to look like:
Any ideas on how to access those system items without actually using images? I know its the exact iOS 7 back bar button item, I just don't know how to access it in a tool bar. I've searched everywhere. If it helps, i'm using BSKeyboardControls.
EDIT: To make it look exactly like the second image, use the images provided by Joshua, and save them as back#2x.png, and forward#2x.png into your xcode proj. Use Chun's code, but make sure to call the method for getting the images like this: imageNamed:#"back", and not #"back#2x". You now have iOS 7 back and forward buttons :)
EDIT2: To get it to look exactly like the next/previous arrow buttons use the following customizations in the correct implementation methods:
[self.segmentedControl setWidth:50 forSegmentAtIndex:0];
[self.segmentedControl setWidth:38 forSegmentAtIndex:1];
negativeSeparator.width = -19;
EDIT3: The toolbar with the < > arrows comes by default with all UIWebViews, and it appears when you tap a textfield.
If anyone is interested in a sample project, let me know, and i'll upload a link!
EDIT4: As of May 24, 2014, BSKeyboardControls now has this functionality by default.

These are the images used in toolbar, e.g. the back and forward button images:

Use the icons shared by Joshua and then try with below piece of code and you will be good to go. I have not added the done button here.
UIImage *backImage = [[UIImage imageNamed:#"backImage"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
UIImage *forwardImage = [[UIImage imageNamed:#"forward"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
self.segmentedControl = [[UISegmentedControl alloc] initWithItems:#[backImage, forwardImage]];
[self.segmentedControl addTarget:self action:#selector(segmentedControlChangedState:) forControlEvents:UIControlEventValueChanged];
self.segmentedControl.segmentedControlStyle = UISegmentedControlStyleBar;
self.segmentedControl.tintColor = [UIColor clearColor];
UIBarButtonItem *aSegmentedControlBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:self.segmentedControl];
[self setItems:#[aSegmentedControlBarButtonItem, self.flexibleSpace]];

1) Download latest files from: https://github.com/simonbs/BSKeyboardControls
2) Import the images for back/next buttons. These can be whatever you want and you can set the appropriate sizes so that they look good. Joshua has a good set. I have mine saved as "keyboardBack.png" and "keyboardForward.png"
3) In BSKeyboardControls.m, update initWithFields:fields. Here you can do some customization like setting the width of your back/next buttons. I removed the Done button here too to follow your screenshot but you can add it back.
- (id)initWithFields:(NSArray *)fields
{
if (self = [super initWithFrame:CGRectMake(0.0f, 0.0f, 320.0f, 44.0f)])
{
// Creates toolbar
[self setToolbar:[[UIToolbar alloc] initWithFrame:self.frame]];
[self.toolbar setBarStyle:UIBarStyleDefault];
[self.toolbar setAutoresizingMask:(UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleWidth)];
[self addSubview:self.toolbar];
// Import images
UIImage *backImage = [[UIImage imageNamed:#"keyboardBack"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
UIImage *forwardImage = [[UIImage imageNamed:#"keyboardForward"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
// Create segmentedcontrol
self.segmentedControl = [[UISegmentedControl alloc] initWithItems:#[backImage, forwardImage]];
self.segmentedControl.tintColor = [UIColor clearColor];
// Set button widths
[self.segmentedControl setWidth:50 forSegmentAtIndex:0];
[self.segmentedControl setWidth:50 forSegmentAtIndex:1];
// Other BSKeyboardControls stuff
[self.segmentedControl addTarget:self action:#selector(segmentedControlValueChanged:) forControlEvents:UIControlEventValueChanged];
[self.segmentedControl setMomentary:YES];
[self.segmentedControl setEnabled:NO forSegmentAtIndex:BSKeyboardControlsDirectionPrevious];
[self.segmentedControl setEnabled:NO forSegmentAtIndex:BSKeyboardControlsDirectionNext];
[self setSegmentedControlItem:[[UIBarButtonItem alloc] initWithCustomView:self.segmentedControl]];
[self setVisibleControls:(BSKeyboardControlPreviousNext)];
[self setFields:fields];
}
return self;
}
4) The left padding on the toolbar is a bit too much, so you can fix it by adding a negative separator in toolbarItems: in BSKeyboardControls.m:
- (NSArray *)toolbarItems
{
NSMutableArray *items = [NSMutableArray arrayWithCapacity:3];
if (self.visibleControls & BSKeyboardControlPreviousNext)
{
UIBarButtonItem *negativeSeperator = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace
target:nil
action:nil];
negativeSeperator.width = -12;
[items addObject:negativeSeperator];
[items addObject:self.segmentedControlItem];
}
if (self.visibleControls & BSKeyboardControlDone)
{
[items addObject:[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil]];
[items addObject:self.doneButton];
}
return items;
}
Note: I probably don't have the button widths and paddings to the exact specs, but you can tweak it to your liking!

If you don't mind living on the edge you could use Apple's undocumented system items to achieve the iOS 7 look. Here are left and right bar button items.
[self setDoneButton:[[UIBarButtonItem alloc] initWithBarButtonSystemItem:105 target:nil action:nil]];
[self setDoneButton:[[UIBarButtonItem alloc] initWithBarButtonSystemItem:106 target:nil action:nil]];
Source: http://iphonedevwiki.net/index.php/UIBarButtonItem

You can use this great tool by #iftekhar and customise IQSegmentedNextPrevious according to your need for giving images instead of next previous button.

Using Xcode 7.3, you can also just enter a symbol as the title for the Bar Item. This works both in code and in Interface Builder:
Place your cursor where you want the symbol to appear (eg, title box in IB or within quotes in code).
In Xcode's menu, click Edit, then Emoji & Symbols. (Alternatively, press control-command-space to bring up the list of characters.)
In the search box, type less or greater.
Then, select the symbol you want.
The less-than and greater-than symbols are colored blue in the toolbar by default.
In code:
backButton.title = "<"
In IB:

Use this: https://github.com/simonbs/BSKeyboardControls
But it uses the segmented control which got flattened in iOS 7.
Edit:
Just change the text of the segments:
[self setSegmentedControl:[[UISegmentedControl alloc] initWithItems:#[#"<",#">") ]]];
This may not be the most elegant. (Not even sure this exact code compiles, but you see the point)

Related

UIbarbutton blue instead of background image

i'm trying to add a back button using a custom png file for the background, but every time i add the background using the storyboard it just become blue like this:
How can i add a background image on a UIbarbutton?
the back button look like this:
This is the standard behavior in iOS 7 for an image in a button. The image is rendered as a template image, with opaque areas colored the current tint color, and transparent areas, transparent. If you want to see the image, you need to create the image with imageWithRenderingMode: and pass UIImageRenderingModeAlwaysOriginal as the argument.
You will need to do it grammatically.
I have tried doing it in storyboard, and it looks like there is a really strange bug, that causes the developer to decide - either use text or use an image, not both....
- (void)viewDidLoad
{
[super viewDidLoad];
[self addButtonsToNavigationBar];
}
- (void)addButtonsToNavigationBar
{
UIButton *regularButton = [[UIButton alloc] initWithFrame: CGRectMake(0, 0, 100.0f, 30.0f)];
UIImage *historyButtonImage = [UIImage imageNamed:#"image_name.png"];
// can set the background color instead of setting an image.
[regularButton setBackgroundImage:historyButtonImage forState:UIControlStateNormal];
[regularButton setTitle:#"Some button name" forState:UIControlStateNormal];
[regularButton addTarget:self action:#selector(historyButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *navigationBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:regularButton];
self.navigationItem.leftBarButtonItem = navigationBarButtonItem;
}

Issue with custom number pad in iOS app

I have an app with a custom number pad. I need the custom number pad for some, but not all of the text fields on a preferences view. I have written this method to set up the number pad for certain text fields:
-(void)setNumberPadFor:(UITextField*)textField andNibName:(NSString *)nibNamed{
textField.inputView = [[[NSBundle mainBundle] loadNibNamed:nibNamed
owner:self
options:nil] lastObject];
UIBarButtonItem *btnDone = [[UIBarButtonItem alloc] initWithTitle:#"Done"
style:UIBarButtonItemStyleDone
target:textField
action:#selector(resignFirstResponder)];
UIToolbar *tips = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
tips.barStyle = UIBarStyleBlackOpaque;
[tips setBackgroundColor:[UIColor blueColor]];
[tips setTintColor:[UIColor whiteColor]];
UIBarButtonItem *spacer = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace
target:nil
action:nil];
[tips sizeToFit];
tips.items = [NSArray arrayWithObjects:spacer, btnDone, nil];
textField.inputAccessoryView = tips;
}
I am calling the setup method as follows (in viewDidLoad for the ViewController):
[self setNumberPadFor:txtMinFeet andNibName:#"PosNegNumberPad"];
[self setNumberPadFor:txtMaxFeet andNibName:#"PosNegNumberPad"];
So, in my button click events, how do I access the text field that initiated the number pad?
-(IBAction)btnNum1:(id)sender{
[[UIDevice currentDevice] playInputClick];
// update text field
}
-(IBAction)btnNum2:(id)sender{
[[UIDevice currentDevice] playInputClick];
// update text field
}
Eventually I will have two custom number pads to cover the requirements, but for now there is just one (hence one nib currently passed as a parameter).
My button actions are set up and working, that is, I can set a break point inside them and verify the app is responding to the events.
What I am unclear about is how to identify which text field initiated the number pad so I can update it accordingly.
Obviously I'm leaving something out. Any suggestions? Thanks!
One way is to use an ivar and every time you get the delegate method textFieldDidBeginEditing: you set the ivar. Later, you query the ivar to get the current text field.
The other way to do is is to find the first responder. This means traversing the subviews of your primary view to find it. This is common enough that you can find code to do that here for sure. The other way is the easiest to do.

weird background behind navigation bar button item created from image

Just trying to add a button to a navigation bar from an image.
code:
UIBarButtonItem *newConvoButton = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:#"convos_new.png"] style:UIBarButtonItemStyleBordered target:self action:#selector(newConvoInit:)];
self.navigationItem.rightBarButtonItem = newConvoButton;
result:
(It should be just the dark image without the blue button in the background.)
This is likely overkill for what you want. But I have a good feeling that this will make your life a whole lot easier. The following will give you just an image without any UIBarButtonItem attributes.
UIImage *menuImage = [UIImage imageNamed:#"navBarMenuButton.png"];
UIButton *leftButton = [UIButton buttonWithType:UIButtonTypeCustom];
leftButton.frame = CGRectMake(0, 0, menuImage.size.width, menuImage.size.height);
[leftButton setBackgroundImage:menuImage forState:UIControlStateNormal];
aController.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:leftButton];
This method implements a custom UIButton, which given the frame of the UIImage you're using, will give you nothing else but the image of your choice added to your UINavigationBar.
A bonus is that you don't have to worry about re-sizing anything in case the image ever changes in the future because the frame inherits from the UIImage.
Best of luck!

ToolTips in iOS through native UI Controls?

How do I create tooltips or something similar in iOS, without using any third party classes? I have a UIButton that I'd like to have a tooltip popup for a few seconds or until it's cleared. I have seen third party classes and libraries, but want to know if natively it's supported. I also want to show an arrow popping up from where the tooltip is coming from. I've seen some UIActionSheet Popups have this arrow.
Cheers,
Amit
Well I ended up using the third party tooltip CMTopTipView afterall. It's relatively low overhead, just a header and implementation. Modified it slightly to account for ARC. Here is what I did:
#import "CMPopTipView.h"
CMPopTipView *navBarLeftButtonPopTipView;
- (void) dismissToolTip
{
[navBarLeftButtonPopTipView dismissAnimated:YES];
}
- (void) showDoubleTap
{
navBarLeftButtonPopTipView = [[CMPopTipView alloc]
initWithMessage:#"DOUBLE Tap \n to view details"] ;
navBarLeftButtonPopTipView.delegate = self;
navBarLeftButtonPopTipView.backgroundColor = [UIColor darkGrayColor];
navBarLeftButtonPopTipView.textColor = [UIColor lightTextColor];
navBarLeftButtonPopTipView.opaque = FALSE;
[navBarLeftButtonPopTipView presentPointingAtView:catButton1
inView:self.view animated:YES];
navBarLeftButtonPopTipView.alpha = 0.75f;
NSTimer *timerShowToolTip = [NSTimer scheduledTimerWithTimeInterval:5.0
target:self
selector:#selector(dismissToolTip) userInfo:nil repeats:NO];
}
If you are on iPad you could use UIPopoverView. You also have the UIMenuController to work with for 'popover' like functionality on iPhone or iPad: tutorial. Beyond that you could just make your own UIView subclass to do this but then you'd have to handle the arrow yourrself.
Well what I ended up doing was relatively simple. I ended up using UIActionSheet with no Buttons just a text. Then used a showFromRect from a coordinate plane where the UIButton was in self.view.
UIActionSheet *popup = [[UIActionSheet alloc]
initWithTitle:#"DOUBLE Tap \n to view details."
delegate:self cancelButtonTitle:#"Cancel"
destructiveButtonTitle:nil otherButtonTitles: nil];
[popup sizeToFit];
popup.tag = 9999;
CGRect myImageRect = CGRectMake(240.0f, 605.0f, 30.0f, -40.0f);
[popup showFromRect:myImageRect inView:self.view animated:YES];
I may just suck it up and use CMPopTipView (third party control) to adjust it's size and opacity and fading alpha.
I saw that some of you is using CMPopTip, great "library".
Cool way!
Just a few things, if you use that in iOS7, you have some deprecation.
New use of the text deprecated part (this is an example)
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping;
paragraphStyle.alignment = self.titleAlignment;
[self.title drawInRect:titleFrame withAttributes:#{NSFontAttributeName:self.titleFont,NSParagraphStyleAttributeName:paragraphStyle}];
Bye!

A UIButton above a UIPickerView

I have a UIPickerView which works correctly, now I want to add a button above it so that I can dismiss it.
and here is my code where I initiate a UIPickerView as well as its dismiss button:
- (UIPickerView *)creatPickerView {
UIPickerView *tempPickerView = [[[UIPickerView alloc]
initWithFrame:CGRectMake(kPickerViewX, kPickerViewY, kPickerViewWidth, kPickerViewHeight)] autorelease];
tempPickerView.showsSelectionIndicator = YES;
tempPickerView.delegate = self;
tempPickerView.dataSource = self;
UIButton *pickerButton = [[UIButton alloc] initWithFrame:CGRectMake(270, -32, 50, 32)];
[pickerButton setBackgroundImage:[UIImage imageNamed:#"hidePicker.png"]
forState:UIControlStateNormal];
[pickerButton addTarget:self action:#selector(hidePicker)
forControlEvents:UIControlEventTouchUpInside];
[tempPickerView addSubview:pickerButton];
[pickerButton release];
[self.view addSubview:tempPickerView];
return tempPickerView;
}
and it works well on my iPhone 4.3 Simulator, like this:
apparently there is a button on the upper right of the pickerView,
problem is, when I run the app in my device - a 5.0.1 iPhone4 and a 4.2.1 iTouch, the button is missed like it has never been added to the pickerView.
Can anyone help me with this?
Thanks a lot and a lot!
I found the reason, it seems the png has some problem,
after I change another png, it comes up in the screen!
but the real problem is that I place the button outside of the pickerView which results in the button's untouchableness.
But anyway the pickure is only a small problem.

Resources