Jacky Shek
Jacky Shek

Reputation: 955

How to add the UISegmentedControl in UINavigationBar?

I have tried to add the UISegmentedControl to the bottom of UINavigationBar with title. But i cannot add it and I cannot add UISegmentedControl in the tableView.headerView,because i need the search bar in the tableView.headerView, so there is just one solution that i need to add UISegmentedControl to the bottom of UINavigationBar. Anyone have another idea that i can solve this situation?

Here is the code that I have tried(with Swift):

        class searchingViewController: UITableViewController{ 
                override func viewDidLoad() {         
                    var items: [AnyObject] = ["Searching Method A", "Searching Method B"]
                    var searchSC:UISegmentedControl!
                    searchSC.frame = CGRectMake(0, 0, frame.width - 20, 30)
                    searchSC.selectedSegmentIndex = 1
                    searchSC.backgroundColor = UIColor(white: 1, alpha: 1)
                    searchSC.layer.cornerRadius = 5.0
                    navigateUIToolBar = UIToolbar(frame: CGRectMake(frame.minX + 10, ios7_8Info.getStatusBarHeight()+self.navigationController!.navigationBar.frame.height+frame.minY+(21/2),
                        frame.width - 20, 30))

                    navigateUIToolBar.addSubview(searchSC)
                    self.navigationController?.navigationBar.addSubview(navigateUIToolBar)
                  }
          }

Upvotes: 19

Views: 31485

Answers (6)

Hardik Thakkar
Hardik Thakkar

Reputation: 15951

To add segment control in UINavigationBar in Swift 5

    let segment: UISegmentedControl = UISegmentedControl(items: ["First", "Second"])
    segment.sizeToFit()
    if #available(iOS 13.0, *) {
        segment.selectedSegmentTintColor = UIColor.red
    } else {
       segment.tintColor = UIColor.red
    }
    segment.selectedSegmentIndex = 0
    segment.setTitleTextAttributes([NSAttributedString.Key.font : UIFont(name: "ProximaNova-Light", size: 15)!], for: .normal)
    self.navigationItem.titleView = segment

Upvotes: 31

Dominic Holmes
Dominic Holmes

Reputation: 598

You can also add the segment control to a search bar, not the navigation item. If you're like me, I needed a large title + search bar + navigation item, which would be impossible with the current top answer.

@Abhishek 's answer is close. You would do something like the following:

// Create the search controller
let searchController = UISearchController(searchResultsController: nil)
searchController.searchResultsUpdater = self
searchController.obscuresBackgroundDuringPresentation = false
searchController.searchBar.scopeButtonTitles = ["Option 1", "Option 2"]

// Make sure the scope bar is always showing, even when not actively searching
searchController.searchBar.showsScopeBar = true

// Make sure the search bar is showing, even when scrolling
navigationItem.hidesSearchBarWhenScrolling = false

// Add the search controller to the nav item   
navigationItem.searchController = searchController
definesPresentationContext = true

@Gurjit Singh, the line with .showsScopeBar = true is the solution to your problem.

Upvotes: 3

Abhishek
Abhishek

Reputation: 368

I think you are looking for this.

let searchVC = self.storyboard?.instantiateViewController(withIdentifier:"idofcontroller")
let searchController = UISearchController(searchResultsController: searchVC)
searchController.searchResultsUpdater = self
searchController.obscuresBackgroundDuringPresentation = false
searchController.searchBar.placeholder = "Search"
navigationItem.searchController = searchController
definesPresentationContext = true

searchController.searchBar.scopeButtonTitles = ["News", "Photos", "Videos"]
searchController.searchBar.delegate = self

enter image description here

Upvotes: 9

williamwu
williamwu

Reputation: 37

you can custom navigationItem's titleView, like this:

self.navigationItem.titleView = segmentview

you should not add subview to the navigationbar, for after push or pop UIViewcontroller ,the subview is still exsit on the navigationbar.

Upvotes: 1

koen
koen

Reputation: 5729

This is how I do it in Objective C (sorry, I haven't learned Swift yet):

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.viewControllers = [self segmentViewControllers];

    self.segmentedControl = [[UISegmentedControl alloc] initWithItems: [self.segmentedControl addTarget: self
                          action: @selector(segmentClicked:)
                forControlEvents: UIControlEventValueChanged];

    CGFloat topOffset = self.navigationController.navigationBar.frame.size.height + [UIApplication sharedApplication].statusBarFrame.size.height;

    self.toolbar = [[UIToolbar alloc] initWithFrame: CGRectMake(0, topOffset, self.navigationController.navigationBar.frame.size.width, kDefaultViewHeight)];
    self.toolbar.delegate = self;

    self.navigationController.navigationBar.backgroundColor = [UIColor whiteColor];
    self.toolbar.backgroundColor = [UIColor whiteColor];
    self.toolbar.clipsToBounds = YES;

    UIBarButtonItem *segmentedControlItem = [[UIBarButtonItem alloc] initWithCustomView: self.segmentedControl];
    UIBarButtonItem *flexibleItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem: UIBarButtonSystemItemFlexibleSpace
                                                                              target: nil
                                                                              action: nil];

    [self.toolbar setItems: @[flexibleItem, segmentedControlItem, flexibleItem] animated: YES];

    [self.navigationController.view addSubview: self.toolbar];

    self.segmentedControl.selectedSegmentIndex = 0;
}

And in UITableViewController (one of the segmentViewControllers):

  self.tableView.contentInset = UIEdgeInsetsMake(topOffset, 0, 0, 0);

    CGRect currentFrame = self.tableView.frame;
    [self.tableView setFrame: CGRectMake(currentFrame.origin.x,
                                     currentFrame.origin.y,
                                     currentFrame.size.width,
                                     currentFrame.size.height + [UIApplication sharedApplication].statusBarFrame.size.height)];

Upvotes: 3

Magoo
Magoo

Reputation: 2619

To put it in the navigationBar has a right left and title view for such things... accessed using....

self.navigationItem.titleView = mySegmentedControl

for future reference....

self.navigationItem.rightBarButtonItem
self.navigationItem.leftBarButtonItems // for adding an Array of items

To add it below the navigation view but have it static.. add it to the viewController.view... Are you using a UITableViewController? If so maybe switch to a UIViewController and add a tableView then your toolbarview as subviews to that self.view.

Upvotes: 21

Related Questions