7

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: enter image description here

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:

enter image description here

enter image description here

Esti M
  • 193
  • 2
  • 10

2 Answers2

13

Simply in viewDidAppear

self.navigationController?.navigationBar.topItem?.rightBarButtonItem?.title = "Save"
user3144836
  • 4,060
  • 3
  • 27
  • 27
7

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.

Tom Harrington
  • 69,312
  • 10
  • 146
  • 170
  • "it's entirely possible that there's framework code to prevent or override changes to the button text". I believe you're absolutely right: [I tried](http://stackoverflow.com/a/31770293/3765705) iterating through all the subviews, more as a proof of concept than for actual use in my app, and while I successfully get to the two buttons, I can't override their color nor text. Too bad! – cdf1982 Aug 02 '15 at 09:09
  • Well, I worked a bit more on this and I was able to make it work on iOS 8.4 - see [this answer](http://stackoverflow.com/a/31770293/3765705) here on Stack Overflow; I don't believe anymore that Apple has put in place code to prevent this kind of changes, but still I'm not sure this should be done. Let's say it was a fun way to spend a sunday morning ;) – cdf1982 Aug 02 '15 at 13:46
  • @cdf1982 I shared my solution in my question, and it's work on all versions. I just make new nav bar and I remove the original from subViews. – Esti M Aug 02 '15 at 16:12