How to add UISegmentedControl in toolbar on iPad programmatically - ios

I have some weird problem adding UISegmentedControl in toolbar on iPad. I have created a UINavigationController with the root controller which has the following methods:
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
UINavigationController *navigationController = [self navigationController];
navigationController.toolbar.barStyle = UIBarStyleBlackOpaque;
navigationController.toolbarHidden = NO;
}
- (NSArray *)toolbarItems
{
UIBarButtonItem *flexibleSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:NULL];
return [NSArray arrayWithObjects:[self segmentedControlItem], flexibleSpace, nil];
}
- (UISegmentedControl *)segmentedControl
{
if (_segmentedControl) {
return _segmentedControl;
}
NSArray *items = [NSArray arrayWithObjects:#"Segment 1", #"Segment 2", nil];
_segmentedControl = [[UISegmentedControl alloc] initWithItems:items];
_segmentedControl.segmentedControlStyle = UISegmentedControlStyleBar;
return _segmentedControl;
}
- (UIBarButtonItem *)segmentedControlItem
{
UIBarButtonItem *buttonItem = [[UIBarButtonItem alloc] initWithCustomView:self.segmentedControl];
buttonItem.style = UIBarButtonItemStyleBordered;
return buttonItem;
}
But after the controller appears the segmentedControl is not visible on toolbar. How to fix it? I am already checked that the segmentedControl exists in toolbar items, it has size, it is not hidden, but nevertheless I cannot see it.
(lldb) po [[[[[self navigationController] toolbar] items] objectAtIndex:0] customView]
(id) $3 = 0x08e39a10 <UISegmentedControl: 0x8e39a10; frame = (7 8; 300 30); opaque = NO; layer = <CALayer: 0x8e63230>>

I have a workaround. It seems is not safe to overwrite the - (NSArray *)toolbarItems if you want to add UISegmentedControl in the toolbar. It is better to add some method to configure the toolbar somewhere after the controller did load.
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self configureToolbar];
}
- (void)configureToolbar
{
UINavigationController *navigationController = [self navigationController];
navigationController.toolbar.barStyle = UIBarStyleBlackOpaque;
navigationController.toolbarHidden = NO;
// Add toolbar items here
UIBarButtonItem *flexibleSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:NULL];
self.toolbarItems = [NSArray arrayWithObjects:[self segmentedControlItem], flexibleSpace, nil];
}
This approach allows you to get the result

Related

Navigation Bar's Button Item Not Clickable on iPad

In my app, I use the old GKImage library for adding pictures and being able to custom crop them easily. This works pretty well, except when it comes to iPad. On iPhone, everything works great. The main issue is this:
When I use an iPad, none of the barButtonItems are clickable.
Here is my code for this view:
- (void)_actionCancel{
[self.navigationController popViewControllerAnimated:YES];
}
- (void)_actionUse{
NSLog(#"PRESSED");
_croppedImage = [self.imageCropView croppedImage];
[self.delegate imageCropController:self didFinishWithCroppedImage:_croppedImage];
}
- (void)_setupNavigationBar{
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel
target:self
action:#selector(_actionCancel)];
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"Use"
style:UIBarButtonItemStylePlain
target:self
action:#selector(_actionUse)];
}
- (void)_setupCropView{
self.imageCropView = [[GKImageCropView alloc] initWithFrame:self.view.bounds];
[self.imageCropView setImageToCrop:sourceImage];
[self.imageCropView setResizableCropArea:self.resizeableCropArea];
[self.imageCropView setCropSize:cropSize];
[self.view addSubview:self.imageCropView];
}
#pragma mark -
#pragma Super Class Methods
- (id)init{
self = [super init];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad{
[super viewDidLoad];
self.title = #"Choose Photo";
[self _setupNavigationBar];
[self _setupCropView];
[self.navigationController setNavigationBarHidden:NO];
}
- (void)viewWillLayoutSubviews{
[super viewWillLayoutSubviews];
self.imageCropView.frame = self.view.bounds;
}
The code used to present this controller is:
self.imagePicker = [[GKImagePicker alloc] init];
self.imagePicker.cropSize = CGSizeMake(280, 280);
self.imagePicker.delegate = self;
self.imagePicker.imagePickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
[self presentViewController:self.imagePicker.imagePickerController animated:YES completion:nil];
Is it an issue with presenting the view controller?

BarButtonItem on NavigationBar is forced to be transparent if returned with popViewController

I have a problem about UIBarButtonItem on NavigationBar.
Transit from FirstViewController to SeconderViewController by pusuViewController.
Return to FirstViewController with return button on left side of NavigationBar.
[Problem happen] The Color of [next] button on right side of NavigationBar is transparent.
(You can tap [next] button althought the color is transparent )
This problem happen on iPhone8(iOS11.2.1(15C153), not heppen on iPhone6(iOS10.3.3(14G60)).
My code is below,
AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds];
self.window.backgroundColor = UIColor.blackColor;
UIViewController *vc = [[FirstViewController alloc] init];
UINavigationController *nc = [[UINavigationController alloc] initWithRootViewController:vc];
self.window.rootViewController = nc;
[self.window makeKeyAndVisible];
return YES;
}
FirstViewContrtoller.m
- (void)viewDidLoad
{
[super viewDidLoad];
self.navigationItem.title = #"First View";
UIBarButtonItem *nextButton = [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(#"next", nil)
style:UIBarButtonItemStylePlain
target:self
action:#selector(touchUpNextButton:)];
self.navigationItem.rightBarButtonItem = nextButton;
}
- (void)touchUpNextButton:(id)sender
{
UIViewController *vc = [[SecondViewController alloc] init];
[self.navigationController pushViewController:vc animated:YES];
}
SecondViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
self.navigationItem.title = #"Second View";
}
I'd appreciate if you would provide me a good solution.
Thank you.
I think it is the bugs of iOS 11.2.1
You can temporary fix by following solution:
UIBarButtonItem *nextButton = [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(#"next", nil)
style:UIBarButtonItemStylePlain
target:self
action:#selector(touchUpNextButton:)];
[nextButton setTitleTextAttributes:#{NSForegroundColorAttributeName : [self.view tintColor], NSFontAttributeName:[UIFont systemFontOfSize:16.9f]} forState:UIControlStateNormal];
Hope that can help you.

Replace custom back button with default

There is a lot of questions about how to replace the default back button with a custom back button, but none that I know of about how to replace a custom back button with the default.
I have a web view that when [self.webView canGoBack] == YES, a custom back button appears. But after you go back all the way, that custom back button is still there, rather than the default. Is there something I can do to replace my custom back button with the default when [self.webView canGoBack] == NO?
Here is my relevant code:
#interface MerchViewController () <UIWebViewDelegate>
#property UIWebView *webView;
#end
#implementation MerchViewController
- (instancetype)init
{
self = [super init];
if (self) {
self.navigationItem.title = #"Merchandise";
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
UIWebView *webView = [[UIWebView alloc] init];
webView.scalesPageToFit = YES;
self.view = webView;
self.webView = webView;
webView.delegate = self;
[self setURL];
}
- (void)updateBackButton {
if ([self.webView canGoBack]) {
{
[self.navigationItem setHidesBackButton:YES animated:NO];
//UIBarButtonItem *backItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:#"backTickets"] style:UIBarButtonItemStylePlain target:self action:#selector(backWasClicked:)];
UIBarButtonItem *backItem = [[UIBarButtonItem alloc] backButtonWith:#"Back" tintColor:[UIColor orangeColor] target:self andAction:#selector(backWasClicked:)];
backItem.tintColor = [UIColor orangeColor];
[self.navigationItem setLeftBarButtonItem:backItem animated:NO];
}
}
else {
/*
[self.navigationItem setHidesBackButton:YES animated:NO];
//UIBarButtonItem *backItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:#"backTickets"] style:UIBarButtonItemStylePlain target:self action:#selector(backWasClicked:)];
UIBarButtonItem *backItem = [[UIBarButtonItem alloc] backButtonWith:#"Fan Zone" tintColor:[UIColor orangeColor] target:self andAction:#selector(openMenu:)];
backItem.tintColor = [UIColor orangeColor];
[self.navigationItem setLeftBarButtonItem:backItem animated:NO];
*/
}
}
- (void)webViewDidStartLoad:(UIWebView *)webView {
[self updateBackButton];
}
- (void)webViewDidFinishLoad:(UIWebView *)webView {
[self updateBackButton];
[_spinner stopAnimating];
}
- (void)backWasClicked:(id)sender {
if ([self.webView canGoBack]) {
[self.webView goBack];
}
}
- (void)setURL
{
NSURLRequest *req = [NSURLRequest requestWithURL:[NSURL URLWithString:#"https://www.lawlorscustom.com/omaha-lancers-hockey"]];
NSLog(#"loadRequest: %#", req);
[(UIWebView *)self.view loadRequest:req];
}
#end
The "else" portion in "updateBackButton" is commented out because if I don't comment it out, when the view first loads there are two back buttons overlapping.
After struggling for a while, the answer was to do:
[self.navigationItem setHidesBackButton:NO animated:NO];
self.navigationItem.leftBarButtonItem = self.navigationItem.backBarButtonItem;

Can't show popover controller with UIBarButtonItem

i use storyboard for developing UI for my project. There are many issues were solved, but this problem killing me. I have added action for UIBarButtonItem :
- (IBAction)pressAddActionButton:(UIBarButtonItem *)sender {
if (_mode == itemSelect) {
LookUpTableViewController *vc = [self.storyboard instantiateViewControllerWithIdentifier:#"lookupTable"];
vc.key = #"title";
vc.data = [Linesheet MR_findAllSortedBy:#"title" ascending:YES];
vc.lookUpDelegate = self;
self.myPopoverController = [[UIPopoverController alloc] initWithContentViewController:vc];
[self.myPopoverController presentPopoverFromBarButtonItem:sender permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
} else {
self.mode = itemSelect;
}
}
If i using storyBoard segue for showing popover - all good, but if i do it in runtime a popover does not show. I should manually create UIBarButtonItem.
Thanks for help!!!
Update, code for buttons:
- (void)setupNavigationItems {
self.navigationController.navigationBarHidden = NO;
UIBarButtonItem *addItem;
if (_mode == itemSelect) {
addItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd
target:self
action:#selector(pressAddActionButton:)];
} else {
addItem = [[UIBarButtonItem alloc] initWithTitle:#"Done" style:UIBarButtonItemStyleDone
target:self
action:#selector(pressDoneButton:)];
}
[addItem setStyle:UIBarButtonItemStyleBordered];
UIBarButtonItem *separator = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace
target:self
action:nil];
UIBarButtonItem *action = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAction
target:self
action:#selector(pressActionButton:)];
[action setStyle:UIBarButtonItemStyleBordered];
[toolbar setItems:[NSArray arrayWithObjects:separator, addItem, action, nil] animated:YES];
}
Make sure you're hitting the code as you expect using a breakpoint on the presentPopoverFromBarButtonItem line. Also, make sure that the myPopoverController property is declared strong if you're using arc, as otherwise it will be nil before the presenting line.
Did you check if LookUpTableViewController *vc actually gets a proper instance? If not then check that your storyboard does have #"lookupTable" set as your controller's identifier.
The code is right. Try replacing the sender with self.navigationItem.leftBarButtonItem or self.navigationItem.rightBarButtonItem. The sender may not be what you are expecting.
Also remove the if (_mode == itemSelect) clause for testing I'm not sure why you need to access the ivar _mode ivar directly.

How to add a right bar button to a navigation bar in iphone

I want to add a right bar button item to the navigation bar, so that on click, it performs certain a function.
I have created the following code to add the right bar button item, but after it is done, the bar button item is not getting displayed in navigation bar:
-(void)viewDidload{
self.navigationItem.rightBarButtonItem =
[[[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemAdd
target:self
action:#selector(Add:)] autorelease];
}
-(IBAction)Add:(id)sender
{
TAddNewJourney *j=[[TAddNewJourney alloc]init];
[app.navigationController pushViewController:j animated:YES];
[j release];
}
Let assume, you have a UIViewController, like this:
UIViewController *vc = [UIViewController new];
And you added it to navigation controller:
UINavigationController *nc = [[UINavigationController alloc] initWithRootViewController:vc];
In this way rightBarButtonItem will NOT getting displayed:
nc.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"xyz" style:UIBarButtonItemStyleDone target:self action:#selector(xyz)];
BUT this way IT WILL appear:
vc.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"xyz" style:UIBarButtonItemStyleDone target:self action:#selector(xyz)];
Use your own viewcontroller instead of the navigationcontroller to refer navigationItem.
-(void)viewDidLoad
{
[super viewDidLoad];
app.navigationController.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:#selector(Add:)] autorelease];
}
-(IBAction)Add:(id)sender
{
TAddNewJourney *j=[[TAddNewJourney alloc]init];
[app.navigationController pushViewController:j animated:YES];
[j release];
}
Try the other answers. I posted this answer so that it will work if your viewcontroller does not have a navigation controller which i think is the problem.
Add this code in viewdidload
UIBarButtonItem *chkmanuaaly = [[UIBarButtonItem alloc]initWithTitle:#"Calculate" style:UIBarButtonItemStylePlain target:self action:#selector(nextview:)];
self.navigationItem.rightBarButtonItem = chkmanuaaly;
Most of the answers here address setting the UINavigationBar's rightBarButtonItem from within the new VC after it is shown. My need, which was actually answered by János, is to set the UINavigationItem items from the CALLING UIViewController. Hence, the following code (Thanks, János).
// from within self (aka the calling controller):
UIViewController *c = [[[UIViewController alloc] init...] autorelease];
c.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(dismissModalViewControllerAnimated:)] autorelease];
c.navigationItem.title = #"Title Goes Here";
UINavigationController *nav = [[[UINavigationController alloc] initWithRootViewController:c] autorelease];
nav.navigationBarHidden = FALSE;
[self presentModalViewController:nav animated:YES];
Now, granted, this may seem redundant to János' answer, but I need more rep points in order o mark his response up. ;-)
UIBarButtonItem *add=[[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:#selector(addUser)];
self.navigationItem.rightBarButtonItem=add;
[add release];
I guess it will be more complete response and it should help in any situation:
-(void)viewDidLoad{
//Set Navigation Bar
UINavigationBar *navBar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 64)];
//Set title if needed
UINavigationItem * navTitle = [[UINavigationItem alloc] init];
navTitle.title = #"Title";
//Here you create info button and customize it
UIButton * tempButton = [UIButton buttonWithType:UIButtonTypeInfoLight];
//Add selector to info button
[tempButton addTarget:self action:#selector(infoButtonClicked) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem * infoButton = [[UIBarButtonItem alloc] initWithCustomView:tempButton];
//In this case your button will be on the right side
navTitle.rightBarButtonItem = infoButton;
//Add NavigationBar on main view
navBar.items = #[navTitle];
[self.view addSubview:navBar];
}
Use the following code:
UIBarButtonItem *add=[[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:#selector(addUser)];
self.navigationItem.rightBarButtonItem=add;
[add release];
Hope this helps you out.
Enjoy!
Swift:
let rightButton = UIBarButtonItem(image: UIImage(named: "imageName"),
style: .plain,
target: self,
action: #selector(buttonTapped))
navigationItem.setRightBarButton(rightButton, animated: false)
#objc func buttonTapped(sender: UIBarButtonItem!) {
// Implement action
}
UIButton *dButton=[UIButton buttonWithType:0];
dButton.frame=CGRectMake(50,50,50,50);
[dButton addTarget:self action:#selector(clickdButton:)
forControlEvents:UIControlEventTouchUpInside];
[dButton setImage:[UIImage imageNamed:#"iconnavbar.png"]
forState:UIControlStateNormal];
dButton.adjustsImageWhenHighlighted=NO;
dButton.adjustsImageWhenDisabled=NO;
dButton.tag=0;
dButton.backgroundColor=[UIColor clearColor];
UIBarButtonItem *RightButton=[[[UIBarButtonItem alloc] initWithCustomView:dButton]autorelease];
self.navigationItem.rightBarButtonItem=RightButton;
and then:
-(IBAction)clickdButton:(id)sender{
classexample *tempController=[[classexample alloc] init];
[self.navigationController pushViewController:tempController animated:YES];
[tempController autorelease];
}

Resources