views:

171

answers:

2

I have code that works great for adding a button to the toolbar:

NSArray* toolbarItems = [NSArray arrayWithObjects:flexibleSpace,shuffleBarItem,flexibleSpace,nil];
self.toolbarItems = toolbarItems;

However, I also want to be able to remove toolbar items. When I use the below method, my application crashes:

NSArray* toolbarItems = [NSArray arrayWithObjects:flexibleSpace,nil];
self.toolbarItems = toolbarItems;

Does anyone know how I can dynamically alter the toolbar on the iPhone?

Thanks!

+1  A: 

Change it into a NSMutableArray.

NSMutableArray* _toolbarItems = [NSMutableArray arrayWithCapacity: 3]; 
[ _toolbarItems addObjects: flexibleSpace,shuffleBarItem,flexibleSpace,nil];

self.toolbarItems = _toolbarItems;

When you want to remove items from the array:

NSInteger indexOfItem = ...
[ _toolbarItems removeObjectAtIndex: indexOfItem ];

self.toolbarItems = _toolbarItems;

Note that in this case you should not use removeObject since you have repeating objects in your array, and calling [ _toolbarItems removeObject: flexibleSpace ] will actually remove both instances of flexibleSpace in the array

Jacob Relkin
This all will work, but it won't update the display of the toolbar. You need to call setToolbarItems: (one way or another) to trigger the update.
Paul Lynch
Also the code above that crashes, doesn't. Something else is causing the crash.
Paul Lynch
@paull Assigning properties **implicitly** calls `setToolbarItems` :)
Jacob Relkin
toolbarItems is an NSArray* so your method does not work. i guess you can assign an NSMutableArray to toolbarItems but when you reference toolbarItems in the future to remove objects, it will not respond to the mutable selectors
Tony
@paul - try setting the toolbarItems twice. i am pretty sure that is causing the crash
Tony
@jacob yes, that's why I said "one way or another".@Tony - setting an NSMutableArray to toolbarItems does allow mutable calls to toolbarItems to work - I was a little surprised, but not too much.
Paul Lynch
@paull - you are right. i was getting the "not responds to selector" warning but it disappeared when i made toolbarItems a class member. for some reason i still get a crash when removing the items from the mutable array. could it have something to do with toolbarItems getting auto-released when I say self.toolbarItems = toolbarItems?
Tony
Be careful - toolbarItems is a property of UIViewController, and making a instance variable or even a local variable with the same name will either fail, or turn around and bite you. Make sure that you have no compiler warnings in your code.
Paul Lynch
+1  A: 

To remove items from the front or back, you could use subarrayWithRange, i.e.:

NSRange allExceptLast;
allExceptLast.location = 0;
allExceptLast.length = [self.toolbarItems count] - 1;
self.toolbarItems = [self.toolbarItems subarrayWithRange:allExceptLast];

If you want to remove objects from the middle, you could either use -[NSArray filteredArrayUsingPredicate:] (which might be overly complicated), or brute force:

NSMutableArray *mutToolbarItems = [NSMutableArray arrayWithArray:self.toolbarItems];
[mutToolbarItems removeObjectAtIndex:<index of object>];
self.toolbarItems = mutToolbarItems;

Note that you shouldn't send removeObjectAtIndex: to self.toolbarItems directly (even if you use the above method), since toolbarItems is exposed as an NSArray--you'll get a compiler warning, and possibly a crash (since you have no control over whether it will actually be implemented as an NSMutableArray behind the scenes).

eman
i agree that it's probably better to treat it as NSArray, even though Jacob was right that I could send removeObjectAtIndex. anyway, this line crashes my app - NSMutableArray *mutToolbarItems = [NSMutableArray arrayWithArray:self.toolbarItems];
Tony
Are you doing this before you've set `self.toolbarItems`? If so, that would cause it to crash. Otherwise, my guess would be that you're over-releasing `self.toolbarItems` somewhere. Are you ever sending it `release`? (You shouldn't, since whenever you set it, it will automatically release the old value.)
eman