19

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)
                  }
          }
Jacky Shek
  • 953
  • 1
  • 11
  • 35
  • you might looking for this..[add segmentcontrol in navigationbar](http://stackoverflow.com/questions/18813563/add-segmented-control-to-navigation-bar-and-keep-title-with-buttons) – Rahul Shirphule May 28 '15 at 11:03
  • can you add a screenshot or fig. of what you are trying to achieve – Vivek Molkar May 28 '15 at 11:27
  • @VivekMolkar i am looking for the solution of [add segmentcontrol in navigationbar ](http://stackoverflow.com/questions/18813563/add-segmented-control-to-navigation-bar-and-keep-title-with-buttons) with programmatically which Rahul Shirphule gave. – Jacky Shek May 29 '15 at 02:30

6 Answers6

30

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
Hardik Thakkar
  • 15,269
  • 2
  • 94
  • 81
  • 2
    someone downvoted my answer as well... I guess someone frustrated with their inability to understand. – Magoo Apr 11 '17 at 09:27
  • @Leon Please read question it clearly define IN UINavigationbar not UNDER UINavigationbar, but some time some one give downvote without any proper reason. – Hardik Thakkar Jul 12 '18 at 10:22
  • i don't want to discuss with you further for this silly point. – Hardik Thakkar Jul 13 '18 at 10:03
  • Considering 4 other people have upvoted my comment, I would suggest my point is valid and perfectly answers your question. If you don't care about answering questions as they're being asked then perhaps this platform isn't for you. – Leon Jul 13 '18 at 10:11
  • But i ask "who give downvote. please give reason for that" on 10 april 2017 why you have this much of free time and you give answer after 1 year, please don't disturb me this is last waring to you. you can see 14 upvote to my answer and i am happy that other people can use my answer. – Hardik Thakkar Jul 13 '18 at 10:14
21

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.

Magoo
  • 2,552
  • 1
  • 23
  • 43
  • 1
    Yes, I am using `UITableViewController`. Your answer "UIViewController and add a tableView then your toolbarview as subviews" which is work for me. I have add the tableView in a `UIViewController` which can edit the tableview's offset y. Thank you very much. – Jacky Shek May 29 '15 at 02:26
  • OK great, glad I could help. – Magoo Jun 01 '15 at 10:46
  • it works strange. If I set `navigationBar.prefersLargeTitles = true` then `mySegmentedControl` appears above the title. – Gargo Aug 01 '23 at 09:20
8

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

Kalzem
  • 7,320
  • 6
  • 54
  • 79
Abhishek
  • 358
  • 3
  • 10
  • How I can make it visible always even after end editing. "searchController.searchBar.showsScopeBar = true" make them visible on first time but after end editing its make then hide again. :-( plz help – Gurjit Singh Nov 15 '18 at 10:18
3

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)];
koen
  • 5,383
  • 7
  • 50
  • 89
  • I have tried your code, but it overlap the `tableView.headerView`, how can i move the table view below the segment control? – Jacky Shek May 29 '15 at 01:26
2

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.

Dominic Holmes
  • 581
  • 5
  • 13
  • The top answer is work for me before. I would not say it is not work or not for now since i do not maintain that application for now and it is working at that time. – Jacky Shek Jan 08 '19 at 03:51
1

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.

itsji10dra
  • 4,603
  • 3
  • 39
  • 59
williamwu
  • 37
  • 5