What is the simplest way to add UIToolBar to UITableViewController? I'm depending on edit functionality, so I can't change UITableViewController to UIViewController easily.
No problem at all, UITableViewController is a subclass of UIViewController. And it so happens that in iPhone OS 3.0 any UIViewController (and subclasses) can work in conjunction with a UINavigationController to provide a context aware toolbar.
In order for this to work you must:
Make sure that you use a UINavigationController to contain all your view controllers that needs a toolbar.
Set the toolbarsItems property of the view controller that wants a toolbar.
This is almost as easy as as setting the view controller's title, and should be done the same way. Most probably by overriding the initWithNibName:bundle: initializer. As an example:
-(id)initWithNibName:(NSString*)name bundle:(NSBundle*)bundle;
{
self = [super initWithNibName:name bundle:bundle];
if (self) {
self.title = #"My Title";
NSArray* toolbarItems = [NSArray arrayWithObjects:
[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd
target:self
action:#selector(addStuff:)],
[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemSearch
target:self
action:#selector(searchStuff:)],
nil];
[toolbarItems makeObjectsPerformSelector:#selector(release)];
self.toolbarItems = toolbarItems;
self.navigationController.toolbarHidden = NO;
}
return self;
}
You can also use setToolbarItems:animated: instead of assigning to the toolbarItems property, to add and remove toolbar items in an animated fashion on the fly.
In order to make PeyloW's recipe to work, I needed to add the following additional line of code:
self.navigationController.toolbarHidden = NO;
Hope that helps...
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
//Initialize the toolbar
toolbar = [[UIToolbar alloc] init];
toolbar.barStyle = UIBarStyleDefault;
//Set the toolbar to fit the width of the app.
[toolbar sizeToFit];
//Caclulate the height of the toolbar
CGFloat toolbarHeight = [toolbar frame].size.height;
//Get the bounds of the parent view
CGRect rootViewBounds = self.parentViewController.view.bounds;
//Get the height of the parent view.
CGFloat rootViewHeight = CGRectGetHeight(rootViewBounds);
//Get the width of the parent view,
CGFloat rootViewWidth = CGRectGetWidth(rootViewBounds);
//Create a rectangle for the toolbar
CGRect rectArea = CGRectMake(0, rootViewHeight - toolbarHeight, rootViewWidth, toolbarHeight);
//Reposition and resize the receiver
[toolbar setFrame:rectArea];
//Create a button
UIBarButtonItem *infoButton = [[UIBarButtonItem alloc]
initWithTitle:#"back" style:UIBarButtonItemStyleBordered target:self action:#selector(info_clicked:)];
[toolbar setItems:[NSArray arrayWithObjects:infoButton,nil]];
//Add the toolbar as a subview to the navigation controller.
[self.navigationController.view addSubview:toolbar];
[[self tableView] reloadData];
}
- (void) info_clicked:(id)sender {
[self.navigationController popViewControllerAnimated:YES];
[toolbar removeFromSuperview];
}
And in Swift 3:
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
//Initialize the toolbar
let toolbar = UIToolbar()
toolbar.barStyle = UIBarStyle.default
//Set the toolbar to fit the width of the app.
toolbar.sizeToFit()
//Caclulate the height of the toolbar
let toolbarHeight = toolbar.frame.size.height
//Get the bounds of the parent view
let rootViewBounds = self.parent?.view.bounds
//Get the height of the parent view.
let rootViewHeight = rootViewBounds?.height
//Get the width of the parent view,
let rootViewWidth = rootViewBounds?.width
//Create a rectangle for the toolbar
let rectArea = CGRect(x: 0, y: rootViewHeight! - toolbarHeight, width: rootViewWidth!, height: toolbarHeight)
//Reposition and resize the receiver
toolbar.frame = rectArea
//Create a button
let infoButton = UIBarButtonItem(title: "Back", style: UIBarButtonItemStyle.plain, target: self, action: #selector(infoClicked))
toolbar.items = [infoButton]
//Add the toolbar as a subview to the navigation controller.
self.navigationController?.view.addSubview(toolbar)
}
func infoClicked() {
//Handle Click Here
}
Related
I have one view Controller and one UIView now in my ViewController when i click barButton than second view will apear like popup,now i want to add page controller and scrollview in that second view, my second view is not UIViewController but it is UIView.so how can i do that...
my first view is "ImageViewController" and second view is "PopupView"
in ImageViewController.m
#import "PopupView.h"
#implementation ImageViewController
- (void)viewDidLoad
{
UIBarButtonItem *clipArt = [[UIBarButtonItem alloc] initWithTitle:#"Clip Art"
style:UIBarButtonItemStyleBordered
target:self
action:#selector(popUpView:)];
}
- (void)popUpView:(id)sender {
CGRect * imageFrame = CGRectMake(10, 90, 300, 300);
PopupView *popUpView = [[PopupView alloc] initWithFrame:imageFrame];
[self.view addSubview:popUpView];
}
And in PopupView.m
- (id)initWithFrame:(CGRect)frame
{
if (self) {
CGRect * imageFrame = CGRectMake(0, 0, 300, 300);
self = [super initWithFrame:frame];
UIImageView *starImgView = [[UIImageView alloc] initWithFrame:imageFrame]; //create ImageView
starImgView.alpha =0.8;
starImgView.layer.cornerRadius = 15;
starImgView.layer.masksToBounds = YES;
starImgView.image = [UIImage imageNamed:#"black"];
[self addSubview:starImgView];
self.backgroundColor = [UIColor clearColor];
}
return self;
}
Implement like this in the second view, for scroll view with page control (this example illustrates the scenario for two views):
CGRect scrollViewFrame = CGRectMake(ur dimensions for scroll view);
UIScrollView *myScrollView = [[UIScrollView alloc] initWithFrame:scrollViewFrame];
myScrollView.pagingEnabled = YES;
myScrollView.contentSize = CGSizeMake(scrollViewFrame.size.width * 2, scrollViewFrame.size.height);
//content size is the actual size of the content to be displayed in the scroll view.
//Since, here we want to add two views so multiplied the width by two.
CGRect viewFrame = [myScrollView bounds];
UIView *view1 = [[UIView alloc] initWithFrame:viewFrame];
viewFrame.origin.x = viewFrame.size.width; //setting the offset so that view2 is next to view 1
UIView *view2 = [[UIView alloc] initWithFrame:viewFrame];
//add both the view to scroll view
[myScrollView addSubview:view1];
[myScrollView addSubview:view2];
//add scroll view to parent view
[self addSubview:myScrollView];
You can replace the view1/2 with any visual element. To have scrolling with page control make sure all the view that you want to add to scrollview are so same width/height. That way it work out of the box and you wont have to do anything. Also, its always a good idea to add UIPageControl to the view for giving user some kind of feedback. Its optional though.
One more thing, if you want horizontal scrolling with page control, increase the width as done above. If you want vertical scrolling, increase the height and keep the width same.
I have a view that has a UISegmentedControl in its bottom UIToolBar with 2 segments. The view when loaded should default to view 1. Then when segment 2 is selected, it should switch to view 2, etc.
Right now, when I click segment 2, it hides the view 1, then switches to the 2nd view, but how do I keep the segmentedControl displayed? When view 1 is hidden, the control is hidden as well.
Do I need to create 3 views total? And have views 1 and 2 as subviews of the default view that only has the segmented control in it?
EDIT:
- (void)segmentedControl:(SVSegmentedControl*)segmentedControl didSelectIndex:(NSUInteger)index
{
LogResultsViewController* v1 = [[LogResultsViewController alloc] initWithNibName: #"LogResultsViewController" bundle:nil];
CalendarController* v2 = [[CalendarController alloc] initWithNibName: #"CalendarController" bundle:nil];
if (index == 0)
{
[self.view addSubview: v1.view];
}
else
{
[self.view addSubview: v2.view];
}
}
And this is the code used to load this view:
- (void)loadView
{
UIBarButtonItem *actionButton = [[UIBarButtonItem alloc] initWithTitle:#"Back" style:UIBarButtonItemStylePlain target:self action:#selector(dismissCalendarView)];
self.navigationItem.leftBarButtonItem = actionButton;
[actionButton release];
int statusBarHeight = 20;
CGRect applicationFrame = (CGRect)[[UIScreen mainScreen] applicationFrame];
self.view = [[[UIView alloc] initWithFrame:CGRectMake(0, statusBarHeight, applicationFrame.size.width, applicationFrame.size.height)] autorelease];
self.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
self.view.backgroundColor = [UIColor grayColor];
calendar.frame = CGRectMake(0, 0, calendar.frame.size.width, calendar.frame.size.height);
[self.view addSubview:calendar];
[calendar reload];
}
Yes, you seem to have solved your own problem. Your two swappable views need to be inside of a third view. If not, your switching control will be hidden when the parent view is hidden.
Yes, that's exactly what you need to do. Set up a container view that holds the toolbar and the other views. Then add and remove the other two views as subviews of the container view as needed.
I have opted to use a UITableViewController without a nib. I need a UIToolbar at the bottom with two buttons. What is the simplest way of doing that?
P.S. I know that I can easily use a UIViewController and add a UITableView however I want things to look consistent across the app.
Can someone help?
I saw the following example and I am not sure on its validity:
(void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
//Initialize the toolbar
toolbar = [[UIToolbar alloc] init]; toolbar.barStyle = UIBarStyleDefault;
//Set the toolbar to fit the width of the app.
[toolbar sizeToFit];
//Caclulate the height of the toolbar
CGFloat toolbarHeight = [toolbar frame].size.height;
//Get the bounds of the parent view
CGRect rootViewBounds = self.parentViewController.view.bounds;
//Get the height of the parent view.
CGFloat rootViewHeight = CGRectGetHeight(rootViewBounds);
//Get the width of the parent view,
CGFloat rootViewWidth = CGRectGetWidth(rootViewBounds);
//Create a rectangle for the toolbar
CGRect rectArea = CGRectMake(0, rootViewHeight - toolbarHeight, rootViewWidth, toolbarHeight);
//Reposition and resize the receiver
[toolbar setFrame:rectArea];
//Create a button
UIBarButtonItem *infoButton = [[UIBarButtonItem alloc] initWithTitle:#"back"
style:UIBarButtonItemStyleBordered
target:self
action:#selector(info_clicked:)];
[toolbar setItems:[NSArray arrayWithObjects:infoButton,nil]];
//Add the toolbar as a subview to the navigation controller.
[self.navigationController.view addSubview:toolbar];
[[self tableView] reloadData];
}
(void) info_clicked:(id)sender {
[self.navigationController popViewControllerAnimated:YES];
[toolbar removeFromSuperview];
}
The simpler thing to do is to build your project on top of a UINavigationController. It already has a toolbar, it's just hidden by default. You can reveal it by toggling the toolbarHidden property, and your table view controller will be able to use it as long as it's in the navigation controller hierarchy.
In your app delegate, or in the object your app delegate passes control to, create the navigation controller with your UITableViewController as the root view controller:
- ( void )application: (UIApplication *)application
didFinishLaunchingWithOptions: (NSDictionary *)options
{
MyTableViewController *tableViewController;
UINavigationController *navController;
tableViewController = [[ MyTableViewController alloc ]
initWithStyle: UITableViewStylePlain ];
navController = [[ UINavigationController alloc ]
initWithRootViewController: tableViewController ];
[ tableViewController release ];
/* ensure that the toolbar is visible */
navController.toolbarHidden = NO;
self.navigationController = navController;
[ navController release ];
[ self.window addSubview: self.navigationController.view ];
[ self.window makeKeyAndVisible ];
}
Then set the toolbar items in your MyTableViewController object:
- ( void )viewDidLoad
{
UIBarButtonItem *buttonItem;
buttonItem = [[ UIBarButtonItem alloc ] initWithTitle: #"Back"
style: UIBarButtonItemStyleBordered
target: self
action: #selector( goBack: ) ];
self.toolbarItems = [ NSArray arrayWithObject: buttonItem ];
[ buttonItem release ];
/* ... additional setup ... */
}
You also can just check "shows toolbar" option in NavigationController attributes inspector.
Here is a simple example, which may help
UIBarButtonItem *spaceItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
UIBarButtonItem *trashItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemTrash target:self action:#selector(deleteMessages)];
UIBarButtonItem *composeItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCompose target:self action:#selector(composeMail)];
NSArray *toolbarItems = [NSMutableArray arrayWithObjects:spaceItem, trashItem,spaceItem,composeItem,nil];
self.navigationController.toolbarHidden = NO;
[self setToolbarItems:toolbarItems];
Thanks,
prodeveloper
In the interface builder, I can set the alignment for my UIToolbar to be at the bottom of my screen or to be at my top of my screen. How can this be done programatically?
You set the UIToolBar's frame or center. It's not alignment it's position. Can be done like so:
[myToolBar setFrame: CGRectMake(x, y, width, height)];
//OR
[myToolBar setCenter: CGPointMake(x, y)];
If the UIToolBoor is auto aligned in IB, it's because IB is programmed to help you position stuff.
~ Natanavra.
(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
//Initialize the toolbar
toolbar = [[UIToolbar alloc] init];
toolbar.barStyle = UIBarStyleDefault;
//Set the toolbar to fit the width of the app.
[toolbar sizeToFit];
//Caclulate the height of the toolbar
CGFloat toolbarHeight = [toolbar frame].size.height;
//Get the bounds of the parent view
CGRect rootViewBounds = self.parentViewController.view.bounds;
//Get the height of the parent view.
CGFloat rootViewHeight = CGRectGetHeight(rootViewBounds);
//Get the width of the parent view,
CGFloat rootViewWidth = CGRectGetWidth(rootViewBounds);
//Create a rectangle for the toolbar
CGRect rectArea = CGRectMake(0, rootViewHeight - toolbarHeight, rootViewWidth, toolbarHeight);
//Reposition and resize the receiver
[toolbar setFrame:rectArea];
//Create a button
UIBarButtonItem *infoButton = [[UIBarButtonItem alloc]
initWithTitle:#"back" style:UIBarButtonItemStyleBordered target:self action:#selector(info_clicked:)];
[toolbar setItems:[NSArray arrayWithObjects:infoButton,nil]];
//Add the toolbar as a subview to the navigation controller.
[self.navigationController.view addSubview:toolbar];
[[self tableView] reloadData];
}
(void) info_clicked:(id)sender {
[self.navigationController popViewControllerAnimated:YES];
[toolbar removeFromSuperview];
}
My main controller is a subclass of UITableViewController with a UIToolBar at the bottom and when a row is selected, I'd like to display another view without the toolbar. How can I hide the UIToolBar in the child view? Right now, it's present throughout all child views unless they're created as modal.
Toolbar is created in RootController:
self.toolbar = [[UIToolbar alloc] init];
// add tool bar items here
[self.navigationController.view addSubview:toolbar];
RootController displays its child views as such:
UIViewController *controller = [[UIViewController alloc] init...]
[self.navigationController pushViewController:controller animated:YES];
RootController is instantiated as such in the app delegate's applicationDidFinishLaunching:
RootController *rootcontroller = [[RootController alloc] initWithStyle:UITableViewStyleGrouped];
self.navigationController = [[UINavigationController alloc] initWithRootViewController:rootcontroller];
[rootcontroller release];
[window addSubview:[self.navigationController view]];
If I add the toolbar to [self.view] within RootController instead of navigationController's view, the toolbar disappears alltogether..
You can try hiding the toolbar before you display our child view with 'toolbar.hidden = YES' and then in your viewWillAppear method, show it again with 'toolbar.hidden = NO'.
Another alternative would be using "removeFromSuperview"
[toolbar removeFromSuperview];
Then use viewDidAppear method in the view where u wanna re-show the toolbar.
It works better than viewWillAppear since the toolbar is added after the view is showed.
(For viewWillAppear, toolbar is added during the transition so it is kinda awkward.)
I got it working with this
[toolbar removeFromSuperview];
Check this
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
//Initialize the toolbar
toolbar = [[UIToolbar alloc] init];
toolbar.barStyle = UIBarStyleDefault;
//Set the toolbar to fit the width of the app.
[toolbar sizeToFit];
//Caclulate the height of the toolbar
CGFloat toolbarHeight = [toolbar frame].size.height;
//Get the bounds of the parent view
CGRect rootViewBounds = self.parentViewController.view.bounds;
//Get the height of the parent view.
CGFloat rootViewHeight = CGRectGetHeight(rootViewBounds);
//Get the width of the parent view,
CGFloat rootViewWidth = CGRectGetWidth(rootViewBounds);
//Create a rectangle for the toolbar
CGRect rectArea = CGRectMake(0, rootViewHeight - toolbarHeight, rootViewWidth, toolbarHeight);
//Reposition and resize the receiver
[toolbar setFrame:rectArea];
//Create a button
UIBarButtonItem *infoButton = [[UIBarButtonItem alloc]
initWithTitle:#"back" style:UIBarButtonItemStyleBordered target:self action:#selector(info_clicked:)];
[toolbar setItems:[NSArray arrayWithObjects:infoButton,nil]];
//Add the toolbar as a subview to the navigation controller.
[self.navigationController.view addSubview:toolbar];
[[self tableView] reloadData];
}
- (void) info_clicked:(id)sender {
[self.navigationController popViewControllerAnimated:YES];
[toolbar removeFromSuperview];
}