Adding Bar Button Item - objective-c

problem
I cannot for the life of me get it to show.
Here's the implementation of the nav bar
_navBar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 50)];
[_navBar setDelegate:self];
[self.view addSubview:_navBar];
_navBar is a UINavigationBar property.
Here's where I add the button.
UIBarButtonItem *button = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd
target:self
action:#selector(flipView:)];
self.navigationItem.rightBarButtonItem = button;
However, nothing shows. Any help?

self.navigationItem is read automatically by a parent UINavigationController. But you don't have one.
Thus, you have two choices:
Instead of a loose nav bar that you create and put into the interface yourself (as you are doing in your first code), be the child of a UINavigationController. Now setting self.navigationItem will work.
Or, create a navigation item, configure it, and push it manually onto your loose nav bar. Your code will then have this structure:
UINavigationItem* ni = [[UINavigationItem alloc] initWithTitle:// ...];
UIBarButtonItem* b = // ...;
ni.rightBarButtonItem = b;
_navbar.items = #[ni];

Related

Right bar button item not aligned vertically

I am setting a rightbarbuttonitem in from a viewController using the following code:
UIBarButtonItem *item = [[UIBarButtonItem alloc]initWithTitle:#"Save" style:UIBarButtonItemStylePlain target:self action:#selector(saveDetails)];
self.navigationItem.rightBarButtonItem = item;
It is appearing as shown in the image:
As you can see, the button which appears is not vertically aligned with either th leftbuttonitem or the title.
I also tried adjusting the alignment using the code mentioned here:
[self.navigationItem.rightBarButtonItem setTitlePositionAdjustment:UIOffsetMake(0, -10) forBarMetrics:UIBarMetricsDefault];
But this removes the custom font and moves the button even higher.
How can I set a rightbarbuttonitem which is aligned AND maintains the custom font set using the UIAppearance proxy?
EDIT:
I even tried using
[[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemSave target:self action:#selector(saveDetails)];
but the result is exactly as shown in the first image.
UPDATE (Sep 20):
It seems that I will have to go with Alexander's answer, anybody with a cleaner solution?
You can use the next variant:
UIButton *saveButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 80, 20)];
[saveButton addTarget:self action:#selector(saveDetails) forControlEvents:UIControlEventTouchUpInside];
[saveButton setTitle: #"Save" forState:UIControlStateNormal];
[saveButton setTitleEdgeInsets:UIEdgeInsetsMake(5, 0, 0, 0)];
UIBarButtonItem *item =[[UIBarButtonItem alloc] initWithCustomView:saveButton];
self.navigationItem.rightBarButtonItem = item;
I tried the answer but didn't seem to work.
The solution for me was adding UIButton as UIBarButtonItem. If it sounds confusing, just drag a UIButton from Interface Builder to the position of Left or RightBarButtonItem on the navigationBar in your storyboard.
Hope it helps.

How to make a UIActivityIndicatorView in a UIToolbar tappable

I'm using this code to insert an UIActivityIndicatorView to my toolbar
-(void)addActivityIndicatorToToolbar {
UIActivityIndicatorView *activityIndicator = [[UIActivityIndicatorView alloc] initWithFrame:CGRectMake(0, 0, 20, 20)];
activityIndicator.userInteractionEnabled = YES;
activityIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyleWhite;
[activityIndicator startAnimating];
UIBarButtonItem *barButton = [[UIBarButtonItem alloc] initWithCustomView:activityIndicator];
barButton.target = self;
barButton.action = #selector(playButtonPressed:);
NSMutableArray *toolbarItemsMutable = [self.toolbar.items mutableCopy];
[toolbarItemsMutable replaceObjectAtIndex:0 withObject:barButton];
self.toolbar.items = toolbarItemsMutable;
}
However, when I tap the UIActivityIndicatorView the action (playButtonPressed) is not performed.
How can I correct this?
It seems more likely that you want a button with an activity indicator inside it. You can do this by creating a button with a custom view as described in this post. Then you can set the action of this button as normal, and you'll probably want to retain a reference to the activity indicator to start and stop it.
I ended up implementing a poor man's solution by adding an extra view on top of the activityIndicatorView with a gestureRecognizer.
This is a quite old question but why don't you directly add a UITapGestureRecognizer instance to your UIActivityIndicatorView instance ? (works fine on iOS 8.2, I didn't test yet on previous versions).

Method called if UIBarButtonItem:initWithImage: is used but not UIBarButtonItem:initWithCustomView:

I have a method that I want to get called when the user clicks on a button in the navigation bar. If I add the button like this then my method gets called:
UIBarButtonItem *editButton = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:#"myEditButton"]
style:UIBarButtonItemStyleBordered
target:self
action: #selector(enterEditMode:)];
editButton.title = #"Edit";
[self.navigationItem setRightBarButtonItem:editButton animated:YES];
When the user clicks on the button then my enterEditMode: method gets called.
However using this code the result looks like as in the attachment - there's no text but worse my image is lying on top of a blue button. I can't use the standard system edit button because there is a requirement for it to be colored black not blue and AFAIA I'm unable to change the color of the standard edit bar button to black?
So in a xib I created a parent UIView which contains a UIImageView which is the button image and a UILabel for the text.
Then I create the button item like this:
UIBarButtonItem *editButton = [[UIBarButtonItem alloc] initWithCustomView:self.editButtonParentView];
[editButton setTarget:self];
[editButton setAction: #selector(enterEditMode:)];
editButton.style = UIBarButtonItemStyleBordered;
editButton.target = self;
self.editButtonLabel.text = #"Edit"
[self.navigationItem setRightBarButtonItem:editButton animated:YES];
Where editButtonParentView is an IBOutlet to the partent view in the nib.
This displays perfectly, however the problem is that enterEditMode: does not get called when the user clicks on it.
Why does it not get called?
Thanks
This link is where I found out how you can get the same look as the system 'Edit' button but get any background color you want. Try this code:
// From:
#import "UIBarButtomItem+Tinted.h"
#implementation UIBarButtonItem (Tinted)
+ (UIBarButtonItem *)newBarButtonItemWithTint:(UIColor*)color andTitle:(NSString*)itemTitle andTarget:(id)theTarget andSelector:(SEL)selector
{
UISegmentedControl *button = [[UISegmentedControl alloc] initWithItems:#[itemTitle]];
button.momentary = YES;
button.segmentedControlStyle = UISegmentedControlStyleBar;
button.tintColor = color;
[button addTarget:theTarget action:selector forControlEvents:UIControlEventValueChanged];
return [[UIBarButtonItem alloc] initWithCustomView:button];
}
#end

Position a UIBarButtonItem in a UIToolBar with PhoneGap

I'm using PhoneGap 1.3 and am trying to create an iOS add button on the right side of my toolbar; however, the createToolBarItem method does not have any option to set the position of the item. How can I do this? Here is a snippet of code from NativeControls.h:
//create the toolbar in `createToolBar` method://
toolBar = [[UIToolbar alloc] initWithFrame:toolBarBounds];
//....set some toolbar options like .hidden, .barStyle, etc.//
[toolBar setFrame:toolBarBounds];
[self.webView setFrame:webViewBounds];
//add the toolbar to the webview
[self.webView.superview addSubView:toolBar];
//create the button item in `createToolBarItem` method:
item = [[UIBarButtonItem alloc] initWithBarButtonSystemItem: UIBarButtonSystemItemAdd target:self action:#selector(toolBarButtonTapped:)];
[toolBarItems insertObject:item atIndex:[tagId intValue]];
[item release];
//then in `showToolBar` method//
[toolBar setItems:toolBarItems animated:NO];
You probably found out by now, but you have to add a UIBarButtonSystemItemFlexibleSpace to the left of your button to have it right-aligned.
In Phonegap, from JS do:
nativeControls.createToolBarItem("spacer", "", "UIBarButtonSystemItemFlexibleSpace", "");

Resizing UITabBarController Child Views

I'm sure this is a matter of me not knowing how to phrase my question, but I'm at a loss.
I'm working on an app with 2 subviews that will be on the top of the screen at all times (taking up a total of 114 pixels including the status bar). I want the rest of the space to be taken up with a UITabBar and it's child views.
The closest I've been able to get is a tab view that is sized correctly but is positioned at 0,0 so it's under my persistent subviews.
// Create the main toolbar
toolbar = [[UIToolbar alloc] init];
[toolbar sizeToFit];
toolbar.frame = CGRectMake(0.0, 20, 768, 44);
UILabel *textLabel = [[UILabel alloc] init];
textLabel.frame = CGRectMake(240, 20, 300, 40);
textLabel.textAlignment = UITextAlignmentCenter;
textLabel.backgroundColor = [UIColor clearColor];
textLabel.text = #"Character Name";
[self.window addSubview:textLabel];
[textLabel release];
...
// Create the stats bar
StatsViewController *statsView = [[StatsViewController alloc] init];
statsView.view.frame = CGRectMake(0.0, 64, 768, 50);
[self.window addSubview:statsView.view];
// Create Tab Bar Controller and Tab View Controllers
tabBarController = [[UITabBarController alloc] init];
...
[self.window setRootViewController:tabBarController];
[tabBarController release];
[self.window addSubview:toolbar];
[self.window bringSubviewToFront:statsView.view];
[self.window bringSubviewToFront:textLabel];
[self.window makeKeyAndVisible];
return YES;
A tab bar controller (or any view controller, for that matter) will always try to resize its view so that it takes up the entire bounds of its superview. So if you want the tab bar controller to not do that, I would create another plain view controller that becomes your new root view controller.
In that view controller's view, you create 2 container subviews, one for your statsView and one for the tab bar controller. Now you add the tab bar controller's view to the one container view and the StatsViewController's view to the other.
(Note: I did not test this.)