UIRightBarButtonItem setting it's button function. What am I doing wrong? - ios

I have the following implemented:
UIImage *rightimage = [UIImage imageNamed:#"notification-new.png"];
UIBarButtonItem *rightbutton = [[UIBarButtonItem alloc] initWithImage:rightimage style:UIBarButtonItemStylePlain target:nil action:#selector(goNotificationNow)];
self.navigationItem.rightBarButtonItem = rightbutton ;
self.navigationItem.rightBarButtonItem.tintColor = [UIColor whiteColor];
Basically, I want the button to push to another ViewController when it is pressed, so I set "goNotificationNow" as :
- (void)goNotificationNow
{NotificationsViewController *ok = [[NotificationsViewController alloc]init];
[self.navigationController pushViewController:ok animated:YES];
}
Now the button can be pressed but it does not do anything. I must be missing something fundamentally just can't seem to find out what it is. I tried using storyboard as well. and changing the function to:
- (void)goNotificationNow
{[self performSegueWithIdentifier:#"notifications" sender:self];}

Your target is nil. You should set it to self. The target is the object that will perform the selector call.

You need to set the target for the action, in this case you're probably wanting to change target:nil to target:self.

Related

ios share extension post button title

I want to change the title of post buttons in SLComposeServiceViewController.
I managed to get the UIButton:
NSArray* subviews =[self.navigationController.navigationBar subviews];
UIButton* postButton =[subviews lastObject];
and i tried to set title like this:
[postButton setTitle:#"Save" forState:UIControlStateNormal];
but the title not changed.
Can anyone help me with this?
I saw Evernote's share extension on my iPad and it looks like this:
UPDATE
My Solution:
I found solution for my question,I removed the original navigation bar and create custom nav bar.
I have two nav bar:
1. with "cancel"\"save" buttons
2. with "back" button
and I change them when navigate to other viewcontroller
(in my case I needed to upload file and user need select location from list)
NOTE: if you not implement configurationItems you need only the first nav bar. (just call to set custom nav bar from viewDidAppear
So my code is here:
#property (strong, nonatomic) UINavigationBar *customNavBar;
-(void) viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
self.customNavBar = [[UINavigationBar alloc] initWithFrame:self.navigationController.navigationBar.bounds];
[self.navigationController.navigationBar removeFromSuperview];
[self.navigationController.view addSubview:self.customNavBar];
[self setCancelSaveNavigationItem];
}
setCancelSaveNavigationItem--> called from viewDidAppear of shareViewController
-(void)setCancelSaveNavigationItem
{
UINavigationItem *newItem = [[UINavigationItem alloc] init];
UIBarButtonItem *cancelBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(#"Cancel",nil) style:UIBarButtonItemStylePlain target:self action:#selector(cancelButtonTapped:)];
UIBarButtonItem *saveBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(#"Done",nil) style:UIBarButtonItemStyleDone target:self action:#selector(saveButtonTapped:)];
newItem.leftBarButtonItem = cancelBarButtonItem;
newItem.rightBarButtonItem = saveBarButtonItem;
[self.customNavBar setItems:#[newItem]];
[self.navigationItem setBackBarButtonItem:cancelBarButtonItem];
[self.navigationItem setRightBarButtonItem:saveBarButtonItem];
if(self.item.value == nil){
saveBarButtonItem.enabled = NO;
}
}
setBackNavigationItem--> called in configurationItems -->in self.item.tapHandler function
-(void)setBackNavigationItem
{
UINavigationItem *newItem = [[UINavigationItem alloc] init];
UIBarButtonItem *selectBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(#"Select",nil) style:UIBarButtonItemStylePlain target:self action:#selector(selectButtonTapped:)];
UIBarButtonItem *backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:[NSString stringWithFormat:#"❮ %#", NSLocalizedString(#"Back",nil)] style:UIBarButtonItemStylePlain target:self action:#selector(backButtonTapped:)];
newItem.leftBarButtonItem = backBarButtonItem;
newItem.rightBarButtonItem = selectBarButtonItem;
[self.customNavBar setItems:#[newItem]];
[self.navigationItem setBackBarButtonItem:backBarButtonItem];
[self.navigationItem setRightBarButtonItem:selectBarButtonItem];
}
Handle buttons tapped:
- (void)backButtonTapped:(id)sender {
if([self.navigationController.viewControllers count] ==2){
[self setCancelSaveNavigationItem];
}
[self.navigationController popViewControllerAnimated:YES];
}
- (void)cancelButtonTapped:(id)sender {
[self cancel];
}
- (void)selectButtonTapped:(id)sender {
...
[self setCancelSaveNavigationItem];
[self popConfigurationViewController];
}
- (void)saveButtonTapped:(id)sender {
...
[self cancel];
}
And it's work for me!!!
The result:
Simply in viewDidAppear
self.navigationController?.navigationBar.topItem?.rightBarButtonItem?.title = "Save"
Your code:
NSArray* subviews =[self.navigationController.navigationBar subviews];
UIButton* postButton =[subviews lastObject];
...is a really bad idea. It only works because the post button is in subviews and is the last item in the array. But the content of subviews is undocumented and might change at any time. Also, since there's no public API for this button, it's entirely possible that there's framework code to prevent or override changes to the button text-- so even if we assume you have the right UI element, you still might not be able to change it.
Evernote's UI is almost certainly a full custom design that only resembles SLComposeServiceViewController. Share extensions are not required to use SLComposeServiceViewController, that's just there for convenience. If it doesn't meet your needs, design your own.
Update: out of curiosity I unzipped the Evernote IPA and had a look at EvernoteShare.appex with nm. There's no reference to SLComposeServiceViewController, which confirms that Evernote is not using that class in their extension.

Unable to change UIBarButtonItem

**Background** When my app loads a UINavigationController is programmatically added and given a leftBarButtonItem and a rightBarButtonItem. During launch a check is made to see if new data is required and if so a method is run to go and get new data from our web server. During this time, the rightBarButtonItem is changed to a UIActivityIndicatorView which will show a spinning activity indicator. When the data download is done, the rightBarButtonItem returns to a UIBarButtonItem. This works fine.
On another UIViewController I need to allow the user to manually get new data and send their data to us. During this time I need the rightBarButtonItem to change to a UIActivityIndicatorView as before. But when I try to do so, the data is downloaded ok but the rightBarButtonItem is never changed.
I think my problem may have something to do with me not being able to reference the UINavigationController and its navigationItems.
**Code** My first UIViewController's implementation where the rightBarButtonItem is changed:
-(void)statusIsLoading{
UIActivityIndicatorView *uiLoading = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
uiLoading.hidesWhenStopped = YES;
NSLog(#"Start animating");
[uiLoading startAnimating];
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:uiLoading];
}
-(void)statusFinishedLoading{
UIActivityIndicatorView *uiLoading = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
uiLoading.hidesWhenStopped = YES;
[uiLoading stopAnimating];
UIBarButtonItem *showSettingsButton = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:#"Settings.png"] style:UIBarButtonItemStylePlain target:self action:#selector(showSettings:)];
self.navigationItem.rightBarButtonItem = showSettingsButton;
}
**What I have tried** I have tried setting the self.navigationItem.rightBarButtonItem in the second UIViewController but this does nothing. I have also tried running the method that calls the above two methods from an instantiated class:
InitViewController *ivcInstance = [[InitViewController alloc] init];
[ivcInstance performUpdate];
This runs the 'performUpdate' code just fine, the 'performUpdate' method called the 'statusIsLoading' and 'statusFinishedLoading' methods but the rightBarButtonItem does not change.
I think there is something very simple I am missing here. Thanks.
**Edit** I have just tried checking for the current value of the rightBarButtonItem on the pageLoad of the second UIViewController and it appears to be nil:
UIBarButtonItem *newItem = self.navigationItem.rightBarButtonItem;
Here newItem = nil. Am I not targeting the correct navigationItem? should it be something other than 'self'?
**Edit 2**
In the second UIViewController I can alter the properties of the navigationBar:
[self.navigationController.navigationBar setBarTintColor:[UIColor colorWithRed:0.6 green:0.01 blue:0.36 alpha:2.0f]];
But if I try the same with the barButtonItem then nothing happens, why is this?
[self.navigationController.navigationItem setRightBarButtonItem:[[UIBarButtonItem alloc] initWithCustomView:uiLoading]];
same with:
[self.navigationItem setRightBarButtonItem:[[UIBarButtonItem alloc] initWithCustomView:uiLoading]];
In your statusFinishedLoading you have some unused codes like below
-(void)statusFinishedLoading
{
/*UIActivityIndicatorView *uiLoading = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
uiLoading.hidesWhenStopped = YES;
[uiLoading stopAnimating];*/ //These are unused codes.
UIBarButtonItem *showSettingsButton = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:#"Settings.png"] style:UIBarButtonItemStylePlain target:self action:#selector(showSettings:)];
self.navigationItem.rightBarButtonItem = showSettingsButton;
}
Also put NSLog in statusFinishedLoading methods and check whether this method called or not.
Thanks!
Try to set the rightBarButtonItem within a main-thread block. Once you have received the response, it should not block the UI.
-(void)statusFinishedLoading
{
UIActivityIndicatorView *uiLoading = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
uiLoading.hidesWhenStopped = YES;
[uiLoading stopAnimating];
UIBarButtonItem *showSettingsButton = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:#"Settings.png"] style:UIBarButtonItemStylePlain target:self action:#selector(showSettings:)];
//Use a block to set the rightBarButton.
dispatch_async(dispatch_get_main_queue(), ^{
self.navigationItem.rightBarButtonItem = showSettingsButton;
});
}
Hope this does the trick.
Edit : You need to create a UINavgationitem in the storyboard, connect the outlet to the .h file and call it statusNavigationItem then reference this navigationItem object to set the rightBarButton.

how to fire back button to in the navigationcontroller modal dialog view

First View has a compose button that calls the composeview as modal dialog. I have added a cancel button to the second view. Where do I add the action for the cancel button?
ComposeTweetVC* composeViewController = [[ComposeTweetVC alloc] initWithNibName:#"ComposeTweetVC" bundle:[NSBundle mainBundle]];
UINavigationController *nvc = [[UINavigationController alloc] initWithRootViewController:composeViewController];
UIBarButtonItem *newBackButton =
[[UIBarButtonItem alloc] initWithTitle:#"Cancel"
style:UIBarButtonItemStyleBordered
target:nil
action:#selector(backPressed:)];
composeViewController.navigationItem.leftBarButtonItem = newBackButton;
[self presentViewController:nvc animated:YES completion:nil];
Where do I add the backPressed method? If I add to the viewcontroller calling the composeviewcontroller, it is never called.
You can add it wherever you want.
Your problem is:
target:nil
You are essentially calling [nil backPressed:] which is a NOOP.
Try changing nil to self or composeViewController, or whatever object you want to be notified when the button is pressed.
You are setting the target to nil so the backPressed: will never be called
try to change this line
UIBarButtonItem *newBackButton = [[UIBarButtonItem alloc] initWithTitle:#"Cancel"
style:UIBarButtonItemStyleBordered
target:nil
action:#selector(backPressed:)];
to be
UIBarButtonItem *newBackButton = [[UIBarButtonItem alloc] initWithTitle:#"Cancel"
style:UIBarButtonItemStyleBordered
target: composeViewController
action:#selector(backPressed:)];
set your target
initWithTitle:style:target:action:
Initializes a new item using the specified title and other properties.
- (id)initWithTitle:(NSString *)title style:(UIBarButtonItemStyle)style target:(id)target action:(SEL)action
Parameters
title
The item’s title. If nil a title is not displayed.
style
The style of the item. One of the constants defined in UIBarButtonItemStyle.
target
The object that receives the action message.
action
The action to send to target when this item is selected.
and then use
-(void) backPressed:(id)sender{
[self dismissViewControllerAnimated:YES completion:nil];
}

How to give barbuttonitem action?

I want to bring up the .nib of "TableViewController" when a done button is clicked on my UIToolBar. But the below isn't allowing the click to bring up a new view. How do I rectify this? Please show me where I went wrong and what should be replaced and why.
//Here's the selector in my overlay.
UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:
UIBarButtonSystemItemDone target:self action:#selector(doneButtonPressed)];
//Here's how I made my action. Btw, the uitoolbar has no nib, it's an overlay on the
//(camera mode).
-(void)doneButtonPressed {
TableViewController *tableView = [[TableViewController alloc]
initWithNibName:#"TableViewController" bundle:nil];
tableView.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self presentModalViewController:tableView animated:YES];
}
//Yet nothing happens when I click on my done button on my overlay. And I've made sure
// i've imported .h frameworks correctly too.
Suppose you were to bring up a nib from a barbuttonitem which is on a UItoolbar overlay. How would you do it?
I was told that to make it function properly I would have to add [barButtonItem addTarget:self action:#selector(doneButtonPressed) forControlEvents:UIControlEventTouchUpInside]; .
But if I add it I get this:
UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:
UIBarButtonSystemItemDone addTarget:self action:#selector(doneButtonPressed)
forControlEvents:UIControlEventTouchUpInside];
Which results in me getting an error reading "instance method' - initWithBarButtonSystemItem:target:action:forControlEvents:' not found (return type defaults to 'id')"
Instead of showing me only the correct additive, please show me the solution in addition to the code I've written here.
If you are using XCode 4, you can simply Ctrl+Drag the BarButtonItem, to your .h file, and you can create an IB Action from there automatically.
A UIBarButtonItem follows the default UIControlEventTouchUpInside and you cannot set it. Xcode should auto-suggest the methods for allocating it, but the correct code is:
UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(doneButtonPressed)];
Note, there's no forControlEvents:.
Try these changes:
UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem: UIBarButtonSystemItemDone target:self action:#selector(doneButtonPressed:)];
-(void)doneButtonPressed:(id)sender
{
}
the target is passed the object that initiated the action (i.e. the UIBarButtonItem itself)
Secondly, set a breakpoint in your doneButtonPressed function. If, for example, the tableView is getting set to nil, then you'll see nothing happen. i.e. perhaps there is an issue with instantiating this view controller.

iOS Can't get my custom back button to show

I'm having trouble setting a custom back button. Below is the current code I'm using in the parent ViewController in viewDidLoad:
UIButton *custBackButton = [[UIButton alloc] init];
[custBackButton setBackgroundImage:[UIImage imageNamed:#"back_btn.png"] forState:UIControlStateNormal];
self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:custBackButton];
I can get the below code to work as a test:
self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"Test" style:UIBarButtonItemStyleBordered target:nil action:nil];
Can anyone give me a pointer or two with what I'm doing wrong for the first example?
Thank you,
don not use self.navigationItem.backbarbutton....use self.navigationItem.leftbarbutton....it will work....and before that make self.backbarbutton=nil....to remove it, otherwise it will overlap...and this wont run ur custom button

Resources