I have a UIToolbar that I set up using IB with three buttons, left, middle and right. In some situations I would like to not display the middle button. Does anybody know of a way to hide a specific button on inside a UIToolBar? There is no hide property, all I can find is setEnable but this still leaves the button causing users to wonder what its purpose is. I would like to only display it in situations that it actually has a use.
Thanks in advance!
Reset the items:
-(void)setItems:(NSArray *)items animated:(BOOL)animated
You can get the current items using the items property, then just remove the one you don't want to show and pass in the new NSArray.
As you can see, you can also animate it to make it clear to the user.
Rather than guessing at the index, I added an IBOutlet for the UIBarButtonItem and then removed it by name:
NSMutableArray *toolBarButtons = [self._toolbar.items mutableCopy];
[toolBarButtons removeObject:self._selectButton]; // right button
[self._toolbar setItems:toolBarButtons];
And of course it helps to connect the outlets in the designer :)
This is how i did it.. too much headache but its the best i could come up with :
NSArray *toolBarArray = toolBar.items;
NSMutableArray *newToolBarArray = [NSMutableArray arrayWithArray:toolBarArray];
[newToolBarArray removeObjectAtIndex:2];
[newToolBarArray removeObjectAtIndex:1];
//remove whatever buttons you want to.
NSArray *finalTabBarArray =[[NSArray alloc] initWithObjects:newToolBarArray, nil];
[toolBar setItems:[finalTabBarArray objectAtIndex:0] animated:NO];
I know it is quite old thread for but those who look this page for solution, here you go :
With iOS7, you can use this approach to show/hide your toolbar button :
if(// your code Condition)
{ self.toolbarBtn1.enabled = YES;
self.toolbarBtn1.tintColor = nil; }
else
{ self.toolbarBtn1.enabled = NO;
self.toolbarBtn1.tintColor = [UIColor clearColor]; }
This does not work here because the array you are sending with setItem is not what the function expects.
I had to replace the line:
NSArray *finalTabBarArray = [[NSArray alloc] initWithObjects:newToolBarArray, nil];
with this one:
NSArray *finalTabBarArray = [newToolBarArray copy];
Then it works perfectly.
Mohit's answer is one that I have used, but you dont need to specifically make it a NSArray that the toolbar sets. You can just set the array of items as a NSMutableArray. No real advantage that I am aware off but its a few lines less code. And that way you can take the array and move about UIButton objects as you would any other array with objects and then just reset the toolbar with that mutable array.
[newToolBarArray removeObjectAtIndex:2];
[newToolBarArray removeObjectAtIndex:1];
[toolBar setItems:newToolBarArray];
Related
I have a situation here, I want to add user name with a check button in a view, looks simple :)...
Question is I may have single or multiple user, so I need to add it through code only, I want to add all names like a ladder with its corresponding check button.
What is the best way to do that?
I have tried by adding labels for each user.. While adding I wanted to set its top position one by one to make it aligned properly.. Do I have to calculate top like this? Any easiest way is there.. Like how they are doing in Android (relative Layout).
thanks
You can create array of usernames and use following code.
This is test code for your reference.
NSMutableArray *arr = [[NSMutableArray alloc] init];
[arr addObject:#"1"];
[arr addObject:#"2"];
[arr addObject:#"3"];
[arr addObject:#"4"];
[arr addObject:#"15"];
Now looping:
for (int i = 0; i<[arr count]; i++) {
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(20, 10*10*i, 100, 40)];
label.text = [arr objectAtIndex:i]; //usernames from array
[self.view addSubview:label];
}
The Objective-C equivalent of relativelayout is Cocoa Auto Layout
I would use a UItableView with a custom cell. The cell contains your input fields. This way you can have as many inputs as you like and they will always be layed out in order in the same way, and you don't need to write any funky code. You also get scrolling and memory management for free.
I am producing a JSON string that I need to parse out and display onto the page. My JSON string outputs information about the contents of a CD like this:
[{"song_name":"Song 1","artist":"John","price":"$1"},
{"song_name":"Song 2","artist":"Anna","price":"$2"},
{"song_name":"Song 3","artist":"Ryan","price":"$3"}]
I would like to display the contents in my viewController in a list format displaying the song_name, artist, and price. I do not want to use a tableView to display this information, but would rather just have a list displayed. How might I go about doing this? I would assume that I need to use NSJSONSerialization, but have only used that for a tableView in the past. Thank you!
In addition to other answers, you can use only one label, just create NSMutableString (for dynamicly adding tracks info) with #"\n" between tracks info, pass it to label.text and set UILabel's property numberOfLines to 0
Follow these steps:
Parse the JSON and store the key-value pair(NSDictionary of CDs) in an NSArray (say infoArray)
Add a UIScrollview as a subview on your viewController's view.
Allocate UILabels dynamically, depending on infoArray count. Looking at your data I believe you can initialize labels with static frames i.e your y can remain static.
Add the text from the infoArray on this label.
Still, I would suggest use UITableView only. It is much simpler and a better approach
You make an array of dictionaries using NSJSONSerialization indeed, then you parse this array one by one and create a view of every dictionary. You're probably best of using a method for this:
-(UIView *) listView: (NSString *)songName andArtist:(NSString *)artist andPrice:(NSString *)price andIndex:(int)viewIndex {
//create your view here and do anything you want
UIView *subView = [[UIView alloc] init] autoRelease];
subView.frame = CGRectMake(0, viewIndex * 70, self.view.frame.width, 70);
//add labels and other stuff
// return the view
return subView;
}
The you add it to the current view by setting different Y values so they appear underneath each other by using the viewIndex of the former method... So if you have an array it goes something like this:
for (int i = 0; i < [array count]; i++) {
NSDictionary *dict = [array objectAtIndex:i];
NSString *songName = [dict valueForKey:#"song_name"];
NSString *artist = [dict valueForKey:#"artist"];
NSString *price = [dict valueForKey:#"price"];
UIView *tempView = [self listView:songName andArtist:artist andPrice:price andIndex:i];
[self.view addSubView:tempView];
}
You have to add it all to a scrollview otherwise you will run into the problem of to many rows on the page. Google for UIScrollView if you don't know how.
But I would recommend against this approach.. Tableviews are there with a reason. They are made for this stuff. Because the also provide for scrolling, drawing and refreshing. If you can, use them!
I'm creating my first app. It will be a catalog of products, that you can scroll through.
I created a UIScrollView with a width of 960 (320*3) and added a UIPageControl. Inside it I added 3 different view, each of them represents one of my products - with all the information I need - name, image, description, price, etc..
I can see the views move, and so I've set the first product with UILabel classes and UIImageView. I was wondering if it is possible to use NSArray and set the UILabel's text property and imageNamed in the next view as the user switches to it.
My problem is that each view has a different UILabel element.
Thanks for your help, it is much appreciated!
Yes you could use a NSArray to store the data for each of your views. I would suggest first creating a simple object with the properties labelText and imageName;
Then you can create a NSArray of your custom object like this:
MyObject obj1 = [MyObject new];
obj1.labelText = #"My Text 1";
obj1.imageName = #"My Image 1";
//Other objects..
then
NSArray *myArray = [[NSArray alloc] initWithObjects: obj1, obj2, obj3, nil];
Then When you switch pages simply do this:
MyObject *myPageInfo = [myArray objectAtIndex:pageNumber];
myLabel.text = myPageInfo.labelText;
mylabel.imageName = myPageInfo.imageName;
Hope that helps.
I ran into difficulties with SSCollectionView and SSCollectionViewItem.
First of all I'd like to get it initialized from IB. But that won't work for me.
I have a SelectFooViewController which is:
#interface SelectFooViewController : SSCollectionViewController { ... }
and am using it as filesOwner of the corresponding XIB.
SelectFooViewController* selectFooVC = [[SelectFooViewController alloc]
initWithNibName:#"SelectFooViewController" bundle:nil];
But since it wont work I had to initialize its properties inside viewDidLoad() myself.
Furthermore I am not able to display anything except the backgroundColor of my SSCollectionViewItems. What I want is a textLabel and an image .
- (SSCollectionViewItem *)collectionView:(SSCollectionView *)aCollectionView itemForIndexPath:(NSIndexPath *)indexPath {
SSCollectionViewItem *item = [[[SSCollectionViewItem alloc] initWithStyle:SSCollectionViewItemStyleImage reuseIdentifier:itemIdentifier] autorelease];
SSLabel* label = [[SSLabel alloc] init];
[label setText:#"foo"];
item.imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"foo.png"]];
item.textLabel = label;
[label autorelease];
return item;
}
I can confirm that the delegate methods (for determining the number Of rows, sections and such) are implemented and working as expected. But my items are all empty - but react onclick with the expected popup.
Does anyone see an error in what I did? - Thanks...
EDIT: I was also not able to display a local image by changing SSCatalog project
I just figured out, that I have to set the frame of each property (textLabel, detailTextLabel and imageView) myself. That fixed it.
When you create instance SelectFooViewController just insert this line
selectFooVC.view;
or
selectFooVC.view.hidden = NO;
And then add it to the view.
This is because the view is not initalised until you explicitly access it. Hence your items are loaded only when you click it and not immediately. You can call it a hack but i don't call it one. :-)
How can I remove a UITabBarItem from a UITabBar?
I haven't tried anything, because I haven't found anything from Google searches or the documentation for UITabBar, UITabBarController, or UITabBarItem.
Thanks in advance! :)
UITabBar has an NSArray collection of items. Since the items property is an NSArray and not an NSMutableArray, you'd have to construct a new NSArray from the existing one devoid of the object you want to remove, then set the items property to the new array.
/* suppose we have a UITabBar *myBar, and an int index idx */
NSMutableArray *modifyMe = [[myBar items] mutableCopy];
[modifyMe removeObjectAtIndex:idx];
NSArray *newItems = [[NSArray alloc] initWithArray:modifyMe];
[myBar setItems:newItems animated:true];
Mike Caron's advice will throw an exception if you intend to modify a tabBar that belongs to a controller.
In iOS 3.0 and later, you should not
attempt to use the methods and
properties of this class to modify the
tab bar when it is associated with a
tab bar controller object. Modifying
the tab bar in this way results in the
throwing of an exception. Instead, any
modifications to the tab bar or its
items should occur through the tab bar
controller interface. You may still
directly modify a tab bar object that
is not associated with a tab bar
controller.
In this case self.tabBarItem=nil will remove it.
NOTE: this appears to not work in iOS 11. It was still good in iOS 10.
This is a moderately horrible answer, in my opinion, in part because it's subverting the human interface guidelines, but all the same it seems to work cleanly:
UITabBar *oldbar = self.tabBarController.tabBar;
UITabBar *newbar = [[UITabBar alloc] initWithFrame:CGRectMake(0,0,oldbar.frame.size.width,oldbar.frame.size.height)];
NSMutableArray *olditems = [[oldbar items] mutableCopy];
[olditems removeObjectAtIndex:0];
NSArray *newitems = [[NSArray alloc] initWithArray:olditems];
[newbar setItems:newitems animated:false];
[oldbar addSubview:newbar];
That layers it cleanly on top of the old tabbar, and it maintains its functionality.