Search code examples
uisplitviewcontrolleruibarbuttonitemuitoolbar

Trouble adding item to UIToolbar


I'm working on an app with a split view controller. The master is a subclass of a tab bar controller and is the split view controller delegate. That part seems to work fine, and it does push the correct information to the detail side -- except for the bar button item that the split view controller generates.

I have a UIToolbar that was dragged out in Xcode onto the only detail view controller in the project. I set an outlet to the public API in Xcode using ctrl-drag.

Also declared in the public API is a UIBarButtonItem *splitViewBarButtonItem, declared weak, nonatomic.

Here is the setter for that item:

-(void)setSplitViewBarButtonItem:(UIBarButtonItem *)barButtonItem
{
   NSLog(@"%@ setSplitViewBarButtonItem to %@ (%@)",self,barButtonItem,barButtonItem.title);
   //UIToolbar *toolbar = [self toolbar];
   UIToolbar *toolbar = self.toolbar;
   NSLog(@"toolbar[0] before adding the barButtonItem is %@",toolbar.items[0]);
   NSMutableArray *toolbarItems = [toolbar.items mutableCopy];
   if (_splitViewBarButtonItem)
   {
      NSLog(@"Removing _splitViewBarButtonItem from toolbarItems");
      [toolbarItems removeObject:_splitViewBarButtonItem];
      NSLog(@"toolbarItems[0] is %@",toolbarItems[0]);
   }
   if (barButtonItem)
   {
      NSLog(@"#####");
      NSLog(@"Now adding %@ to toolbarItems",[barButtonItem description]);
      [toolbarItems insertObject:barButtonItem atIndex:0];
      NSLog(@"toolbarItems[0] is %@",[toolbarItems[0] description]);
      NSLog(@"#####");
   }
   self.toolbar.items = [toolbarItems copy];
   NSLog(@"self.toolbar.items[0] is %@",self.toolbar.items[0]);
   _splitViewBarButtonItem = barButtonItem;
}

The first time through, it behaves as expected:

2013-04-01 10:33:46.270 SPoT[10389:907] <IViewController: 0x1e066430> setSplitViewBarButtonItem to <UIBarButtonItem: 0x1cd65490> (Text appearing on the button)
2013-04-01 10:33:46.272 SPoT[10389:907] toolbar[0] before adding the barButtonItem is <UIBarButtonItem: 0x1cd65400>
2013-04-01 10:33:46.275 SPoT[10389:907] #####
2013-04-01 10:33:46.277 SPoT[10389:907] Now adding <UIBarButtonItem: 0x1cd65490> to toolbarItems
2013-04-01 10:33:46.278 SPoT[10389:907] toolbarItems[0] is <UIBarButtonItem: 0x1cd65490>
2013-04-01 10:33:46.280 SPoT[10389:907] #####
2013-04-01 10:33:46.288 SPoT[10389:907] self.toolbar.items[0] is <UIBarButtonItem: 0x1cd65490>

However, if I use the button to activate the master, thus making the button disappear and use the master to refresh the detail screen with new data, the transfer of the button is not taking. I've traced the problem to this method, where the button is shown to be available but is not updating. Here's the debugger output from the second run:

2013-04-01 10:33:53.491 SPoT[10389:907] <IViewController: 0x1e09fad0> setSplitViewBarButtonItem to <UIBarButtonItem: 0x1cd65490> (Text appearing on the button)
2013-04-01 10:33:53.492 SPoT[10389:907] toolbar[0] before adding the barButtonItem is (null)
2013-04-01 10:33:53.493 SPoT[10389:907] #####
2013-04-01 10:33:53.494 SPoT[10389:907] Now adding <UIBarButtonItem: 0x1cd65490> to toolbarItems
2013-04-01 10:33:53.495 SPoT[10389:907] toolbarItems[0] is (null)
2013-04-01 10:33:53.496 SPoT[10389:907] #####
2013-04-01 10:33:53.497 SPoT[10389:907] self.toolbar.items[0] is (null)

Note that the debugger trace states, "Now adding ", so the item is available. So why is it not being added?

Edit: Now I'm thinking that since "toolbar[0] before adding the barButtonItem is (null)" that the segue that generated the object id of the new detail controller hasn't fully created that object, specifically, the toolbar property doesn't exist yet. I guess I'll have to figure out how to add the bar button item later in the process.


Solution

  • Not sure this is the best solution, but I figured the reason the bar button item wasn't being added to the title was that the title hadn't yet been added to the new detail VC object provided by the segue. I solved this problem by adding the following line to the detail VC's viewDidLayoutSubviews method:

    self.splitViewBarButtonItem = self.splitViewBarButtonItem;
    

    This calls the setter again, but this time after the titlebar exists.