101

How do I make a UISegmentedControl as a part of an UINavigationBar below it? Is it connected to the UINavigationBar or is it a complete separate view just added as a subview to the UINavigationController's view controller. Looks like it is part of the UINavigationBar since there is a shadow below the bar.

enter image description here

yoeriboven
  • 3,541
  • 3
  • 25
  • 40

10 Answers10

153

It's a simple effect to accomplish.

First, place a segment in a toolbar. Place this toolbar right below the navigation bar. Set the delegate of the toolbar to your view controller, and return UIBarPositionTopAttached in positionForBar:. You can see in the store app, if you perform an interactive pop gesture, that the segment bar does not move the same as the navigation bar. That's because they are not the same bar.

enter image description here

Now to remove the hairline. The "hairline" is an UIImageView that is a subview of the navigation bar. You can find it and set it as hidden. This is what Apple does in their native calendar app, for example, as well as the store app. Remember to show it when the current view disappears. If you play a little with the Apple apps, you will see that the hairline is set to hidden on viewWillAppear: and set to shown in viewDidDisappear:.

To achieve the style of the search bar, just set the bar's searchBarStyle to UISearchBarStyleMinimal.

Léo Natan
  • 56,823
  • 9
  • 150
  • 195
  • 6
    Good answer! Don't forget to update the contentInset of the tableView to avoid the toolBar to cover the content :-) – LombaX Feb 25 '14 at 14:19
  • Accept your answer because the bounty was almost expiring and because it was almost right. Problem is, I don't see my tableview's content behind the toolbar, only behind the navigation bar. After all, this answer helped me out the most. – yoeriboven Mar 03 '14 at 11:26
  • @yoeriboven Uhm, in my app, the toolbar is also translucent. Make sure you set it as translucent. – Léo Natan Mar 03 '14 at 17:32
  • Turned out it is translucent, although it's color is different from the navigation bar. Only when I scroll the tableview's contents behind the toolbar, the color is the same. – yoeriboven Mar 04 '14 at 10:28
  • @yoeriboven Ah, yes, this is normal. It happens with the app store app as well, but it is less noticeable when using a custom color. – Léo Natan Mar 04 '14 at 11:11
  • We can't add constraints in toolbar right? How do we stretch out the segmented depending on the screensize? – Rhenz Mar 20 '15 at 03:10
  • @Rhenz You will have to calculate the size in `viewWillLayout`/`viewDidLayout` and update the bar button items. – Léo Natan Mar 20 '15 at 17:19
  • I'm trying to do just this - within a UITableViewController. Event with the toolbar position set to TopAttached, it still scrolls with the rolls of the table. How do we stop that? – Daniel D May 20 '15 at 00:08
  • @DanielD You have added the toolbar as a tableview subview. It won't work like that. – Léo Natan May 20 '15 at 00:12
  • @DanielD You need to create a container controller. Add your toolbar at the top and add a container view, which will include the table controller's contents. – Léo Natan May 20 '15 at 00:23
  • Thanks - I've seen that method discussed. The problem there, is, if I move from UITableviewController to a UIViewController (a container) I have a problem also wiring up UIRefreshControl and UISearchBarDelegate.... :) – Daniel D May 20 '15 at 00:25
  • 1
    "Place this toolbar right below the navigation bar." What should be the superView ? – koen Jul 12 '15 at 13:47
  • @Koen It should be your view controller's view, for example. – Léo Natan Jul 12 '15 at 14:55
  • Thanks, I am swapping three different viewControllers with the segmentedControl, which one should I use ? – koen Jul 12 '15 at 16:09
  • 1
    @Koen Your use case is more complex. Create a container view controller, and add your segment there. Then add the other controllers as child controllers under the segment controller. – Léo Natan Jul 12 '15 at 16:17
  • Got that working, only my view content is now covered by the `UIToolbar`. For instance one of the segments has a `UITableView` and the first cell is partially hidden. – koen Jul 22 '15 at 19:13
  • See also my question here: http://stackoverflow.com/questions/31761396/uinavigationbar-with-uisegmentedcontrol-partially-covers-childviews – koen Aug 01 '15 at 16:33
  • 2
    Still confused what the best way is to add the toolbar, should I hardcode the frame in `initWithRect: CGRectMake(0, self.toplayoutGuide.length, 320, 44)`, or maybe use autolayout to position it? What will be the new top of the childViews, will that be `self.toplayoutGuide.length + 44` ? – koen Aug 03 '15 at 11:44
  • I achieved this result, but... pushing and popping view controllers in the navigation stack cause the animation to be rough, not very fluid. How can I fix this? – Dree Aug 03 '15 at 14:17
  • How do you prevent the searchBar to stay below the segmented control when activated? – koen Aug 29 '15 at 22:58
  • I haven't dealt with such a problem. The way Apple solved it is having a bar button and not display a search bar. – Léo Natan Aug 30 '15 at 05:03
  • This seems to work: `self.searchController.hidesNavigationBarDuringPresentation = NO;` – koen Aug 30 '15 at 13:41
  • How to get SegmentedControl to use the full width? – Vrutin Rathod Nov 03 '16 at 11:24
  • 2
    @Vrutin Don't use a bar button item. Instead, add as a sub view of the toolbar. You can then set the size to be that of the toolbar. – Léo Natan Nov 03 '16 at 11:30
14

Now to remove the hairline. The "hairline" is an UIImageView that is a subview of the navigation bar. You can find it and set it as hidden. This is what Apple does in their native calendar app, for example, as well as the store app. Remember to show it when the current view disappears. If you play a little with the Apple apps, you will see that the hairline is set to hidden on viewWillAppear: and set to shown in viewDidDisappear:.

Another approach would be to look for the hairline and move it below the added toolbar. Here is what I came up with.

@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIToolbar *segmentbar;
@property (weak, nonatomic) UIImageView *navHairline;
@end

@implementation ViewController

#pragma mark - View Lifecycle

- (void)viewDidLoad
{
    [super viewDidLoad];

    // find the hairline below the navigationBar
    for (UIView *aView in self.navigationController.navigationBar.subviews) {
        for (UIView *bView in aView.subviews) {
            if ([bView isKindOfClass:[UIImageView class]] &&
                bView.bounds.size.width == self.navigationController.navigationBar.frame.size.width &&
                bView.bounds.size.height < 2) {
                self.navHairline = (UIImageView *)bView;
            }
        }
    }
}

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    [self _moveHairline:YES];
}

- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];
    [self _moveHairline:NO];
}

- (void)_moveHairline:(BOOL)appearing
{
    // move the hairline below the segmentbar
    CGRect hairlineFrame = self.navHairline.frame;
    if (appearing) {
        hairlineFrame.origin.y += self.segmentbar.bounds.size.height;
    } else {
        hairlineFrame.origin.y -= self.segmentbar.bounds.size.height;
    }
    self.navHairline.frame = hairlineFrame;
}

@end

I also found the Apple NavBar Code Sample (Customizing UINavigationBar) very helpful to resolve this issue.

Also be sure to handle the top border of the UIToolbar, it might show up and you could confuse it with the hairline of the NavBar. I also wanted the UIToolbar to look exactly like the NavBar, you probably want to adjust the Toolbars barTintColor then.

Community
  • 1
  • 1
Simon
  • 601
  • 1
  • 7
  • 12
13

Here's a Protocol Oriented Swift approach to this particular problem, taking basis on the accepted answer:

HideableHairlineViewController.swift

protocol HideableHairlineViewController {

  func hideHairline()
  func showHairline()

}

extension HideableHairlineViewController where Self: UIViewController {

  func hideHairline() {
    findHairline()?.hidden = true
  }

  func showHairline() {
    findHairline()?.hidden = false
  }

  private func findHairline() -> UIImageView? {
    return navigationController?.navigationBar.subviews
      .flatMap { $0.subviews }
      .flatMap { $0 as? UIImageView }
      .filter { $0.bounds.size.width == self.navigationController?.navigationBar.bounds.size.width }
      .filter { $0.bounds.size.height <= 2 }
      .first
  }

}

SampleViewController.swift

import UIKit

class SampleViewController: UIViewController, HideableHairlineViewController {

  @IBOutlet private weak var toolbar: UIToolbar!
  @IBOutlet private weak var segmentedControl: UISegmentedControl!

  override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(animated)
    hideHairline()
  }

  override func viewDidDisappear(animated: Bool) {
    super.viewDidDisappear(animated)
    showHairline()
  }


}

// MARK: UIToolbarDelegate
extension SampleViewController: UIToolbarDelegate {

  func positionForBar(bar: UIBarPositioning) -> UIBarPosition {
    return .TopAttached
  }

}
Ivan Bruel
  • 386
  • 4
  • 10
  • The “hairline” is the `shadowImage` property of the navigation bar. – LShi Feb 28 '18 at 07:27
  • 1
    Hi, could you explain how did you position the toolbar in Interface Builder? Auto Layout? Could you also comment out the extension above and see what happens? I don’t think it’s effective. – LShi Feb 28 '18 at 07:32
8

You can find navigation bar with UISegmentedControl in Apple Sample Code: https://developer.apple.com/library/ios/samplecode/NavBar/Introduction/Intro.html

Or you can create it programmatically, here is the code in my answer in the other thread Add segmented control to navigation bar and keep title with buttons

Community
  • 1
  • 1
pigmasha
  • 201
  • 3
  • 6
6

I wanted to do the same thing.. And got this:


1 - UINavigationBar subclass

//-------------------------
// UINavigationBarCustom.h
//-------------------------
#import <UIKit/UIKit.h>

@interface UINavigationBarCustom : UINavigationBar

@end


//-------------------------
// UINavigationBarCustom.m
//-------------------------
#import "UINavigationBarCustom.h"

const CGFloat MyNavigationBarHeightIncrease = 38.f;

@implementation UINavigationBarCustom


- (id)initWithCoder:(NSCoder *)aDecoder {
    
    self = [super initWithCoder:aDecoder];
    
    if (self) {
        [self initialize];
    }
    
    return self;
}

- (id)initWithFrame:(CGRect)frame {
    
    self = [super initWithFrame:frame];
    
    if (self) {
        [self initialize];
    }
    
    return self;
}

- (void)initialize {
    // Set tittle position for top
    [self setTitleVerticalPositionAdjustment:-(MyNavigationBarHeightIncrease) forBarMetrics:UIBarMetricsDefault];
}

- (CGSize)sizeThatFits:(CGSize)size {
    // Increase NavBar size
    CGSize amendedSize = [super sizeThatFits:size];
    amendedSize.height += MyNavigationBarHeightIncrease;
    
    return amendedSize;
}

- (void)layoutSubviews {
// Set buttons position for top
    [super layoutSubviews];
    
    NSArray *classNamesToReposition = @[@"UINavigationButton"];
    
    for (UIView *view in [self subviews]) {
        
        if ([classNamesToReposition containsObject:NSStringFromClass([view class])]) {
            
            CGRect frame = [view frame];
            frame.origin.y -= MyNavigationBarHeightIncrease;
            
            [view setFrame:frame];
        }
    }
}

- (void)didAddSubview:(UIView *)subview
{
    // Set segmented position
    [super didAddSubview:subview];
    
    if ([subview isKindOfClass:[UISegmentedControl class]])
    {
        CGRect frame = subview.frame;
        frame.origin.y += MyNavigationBarHeightIncrease;
        subview.frame = frame;
    }
}

@end

2 - Set your NavigationController with subclass

Set your NavigationController with subclass


3 - Add your UISegmentedControl in navigationBar

enter image description here


4 - Run and Fun ->do not forget to put the same color on both

enter image description here


searching source:

Hacking UINavigationBar

S.O question

Community
  • 1
  • 1
iTSangar
  • 462
  • 8
  • 10
  • Please notice that `UINavigationButton` is private API, and your app will be rejected for using it. You should attempt to mask the use of that class. – Léo Natan Sep 05 '14 at 17:01
  • @LeoNatan after searching about I decided to risk send my app to store as it is in my answer and zhas! approved – iTSangar Dec 05 '14 at 23:12
  • 1
    Remember that even if you are approved once, you risk being rejected at a future date, or Apple can reject at future submission. At least do the tiny amount of work to hide the use of private API. – Léo Natan Dec 05 '14 at 23:19
  • 1
    Your solution is great, I can add anything to the nav bar but unfortunately I'm not able to click on any object added to the view :/ (The app I'm working on is for a JB device and not going to the Appstore) – Fouad Jun 21 '15 at 12:30
  • 1
    Looks good except for the back button, which happens to be added to the bottom. – gklka Aug 02 '15 at 15:18
2

Apple has sample app specifically for this. It describes setting a transparent shadow image and colored background image for the navigation bar and how to configure a view below the navigation bar. It also has examples of other navigation bar customizations.

See https://developer.apple.com/library/ios/samplecode/NavBar/Introduction/Intro.html

Michael Peterson
  • 10,383
  • 3
  • 54
  • 51
2

I tried removing the hairline using @Simon's method but it did not work. I'm probably doing something wrong because I am super noob. However, instead of removing the line, you can simply hide it using the hidden attribute. Here's the code:

var hairLine: UIView = UIView()
override func viewDidLoad() {
    super.viewDidLoad()
    doneButton.enabled = false

    for parent in self.navigationController!.navigationBar.subviews {
        for childView in parent.subviews {
            if childView is UIImageView && childView.bounds.size.width == self.navigationController!.navigationBar.frame.size.width {
                hairLine = childView
            }
        }
    }
}

override func viewWillAppear(animated: Bool) {
    hairLine.hidden = true
}

override func viewWillDisappear(animated: Bool) {
    hairLine.hidden = false
}

Hope this helps somebody!

aejhyun
  • 612
  • 1
  • 6
  • 19
2

UISegmentedControl below UINavigationbar in swift 3/4

Details

Xcode 9.2, swift 4

Full Sample

ViewController.swift

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var tableView: UITableView!
    @IBOutlet weak var navigationBarWithSegmentedControl: UINavigationBar!

    fileprivate let barBackgroundColor = UIColor(red: 248/255, green: 248/255, blue: 248/255, alpha: 1.0)

    override func viewDidLoad() {
        super.viewDidLoad()

        navigationBarWithSegmentedControl.barTintColor = barBackgroundColor
        tableView.dataSource = self
        tableView.delegate = self
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
        navigationController?.navigationBar.shadowImage = UIImage()
        navigationController?.navigationBar.barTintColor = barBackgroundColor
    }

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)

        navigationController?.navigationBar.setBackgroundImage(nil, for: .default)
        navigationController?.navigationBar.shadowImage =  nil
    }
}

extension ViewController: UITableViewDataSource {

    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 100
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "TableViewCell") as! TableViewCell
        cell.label.text = "\(indexPath)"
        return cell
    }
}

extension ViewController: UITableViewDelegate {
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        if let cell = tableView.cellForRow(at: indexPath) {
            cell.isSelected = false
        }
    }
}

TableViewCell.swift

import UIKit

class TableViewCell: UITableViewCell {

    @IBOutlet weak var label: UILabel!

}

Main.storyboard

<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13771" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="5TT-dT-dEr">
    <device id="retina4_7" orientation="portrait">
        <adaptation id="fullscreen"/>
    </device>
    <dependencies>
        <deployment identifier="iOS"/>
        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13772"/>
        <capability name="Constraints to layout margins" minToolsVersion="6.0"/>
        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
    </dependencies>
    <scenes>
        <!--Text-->
        <scene sceneID="tne-QT-ifu">
            <objects>
                <viewController id="BYZ-38-t0r" customClass="ViewController" customModule="stackoverflow_21887252" customModuleProvider="target" sceneMemberID="viewController">
                    <layoutGuides>
                        <viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
                        <viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
                    </layoutGuides>
                    <view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
                        <rect key="frame" x="0.0" y="0.0" width="375" height="603"/>
                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                        <subviews>
                            <tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="28" sectionFooterHeight="28" translatesAutoresizingMaskIntoConstraints="NO" id="HLl-W2-Moq">
                                <rect key="frame" x="0.0" y="44" width="375" height="559"/>
                                <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
                                <prototypes>
                                    <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" reuseIdentifier="TableViewCell" id="FKA-c2-G0Q" customClass="TableViewCell" customModule="stackoverflow_21887252" customModuleProvider="target">
                                        <rect key="frame" x="0.0" y="28" width="375" height="44"/>
                                        <autoresizingMask key="autoresizingMask"/>
                                        <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="FKA-c2-G0Q" id="Xga-fr-00H">
                                            <rect key="frame" x="0.0" y="0.0" width="375" height="43.5"/>
                                            <autoresizingMask key="autoresizingMask"/>
                                            <subviews>
                                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="QW3-Hg-hU9">
                                                    <rect key="frame" x="15" y="11" width="345" height="21"/>
                                                    <fontDescription key="fontDescription" type="system" pointSize="17"/>
                                                    <nil key="textColor"/>
                                                    <nil key="highlightedColor"/>
                                                </label>
                                            </subviews>
                                            <constraints>
                                                <constraint firstAttribute="trailingMargin" secondItem="QW3-Hg-hU9" secondAttribute="trailing" id="Grx-nu-2Tu"/>
                                                <constraint firstItem="QW3-Hg-hU9" firstAttribute="centerY" secondItem="Xga-fr-00H" secondAttribute="centerY" id="MIn-R2-wYE"/>
                                                <constraint firstItem="QW3-Hg-hU9" firstAttribute="leading" secondItem="Xga-fr-00H" secondAttribute="leadingMargin" id="h6T-gt-4xk"/>
                                            </constraints>
                                        </tableViewCellContentView>
                                        <color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.050000000000000003" colorSpace="custom" customColorSpace="sRGB"/>
                                        <connections>
                                            <outlet property="label" destination="QW3-Hg-hU9" id="QjK-i2-Ckd"/>
                                            <segue destination="hcx-2g-4ts" kind="show" id="IGa-oI-gtf"/>
                                        </connections>
                                    </tableViewCell>
                                </prototypes>
                            </tableView>
                            <navigationBar contentMode="scaleToFill" translucent="NO" translatesAutoresizingMaskIntoConstraints="NO" id="8jj-w6-ZtU">
                                <rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
                                <items>
                                    <navigationItem id="q8e-Yy-ceD">
                                        <nil key="title"/>
                                        <segmentedControl key="titleView" opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="bar" selectedSegmentIndex="0" id="cHD-bv-2w7">
                                            <rect key="frame" x="96.5" y="7" width="182" height="30"/>
                                            <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
                                            <segments>
                                                <segment title="First"/>
                                                <segment title="Second"/>
                                                <segment title="Third"/>
                                            </segments>
                                        </segmentedControl>
                                    </navigationItem>
                                </items>
                            </navigationBar>
                        </subviews>
                        <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                        <constraints>
                            <constraint firstItem="8jj-w6-ZtU" firstAttribute="trailing" secondItem="HLl-W2-Moq" secondAttribute="trailing" id="1vT-ta-AuP"/>
                            <constraint firstItem="8jj-w6-ZtU" firstAttribute="leading" secondItem="8bC-Xf-vdC" secondAttribute="leading" id="BJE-BC-XcB"/>
                            <constraint firstItem="8jj-w6-ZtU" firstAttribute="top" secondItem="y3c-jy-aDJ" secondAttribute="bottom" id="Boi-dN-awt"/>
                            <constraint firstItem="HLl-W2-Moq" firstAttribute="bottom" secondItem="wfy-db-euE" secondAttribute="top" id="W1n-m1-EOH"/>
                            <constraint firstAttribute="trailing" secondItem="8jj-w6-ZtU" secondAttribute="trailing" id="ihc-9p-71l"/>
                            <constraint firstItem="HLl-W2-Moq" firstAttribute="top" secondItem="8jj-w6-ZtU" secondAttribute="bottom" id="pFk-pU-y7j"/>
                            <constraint firstItem="8jj-w6-ZtU" firstAttribute="leading" secondItem="HLl-W2-Moq" secondAttribute="leading" id="yjf-7o-t2m"/>
                        </constraints>
                    </view>
                    <navigationItem key="navigationItem" title="Text" id="yrt-M7-PAX">
                        <barButtonItem key="leftBarButtonItem" systemItem="search" id="wrz-DS-FdJ"/>
                        <barButtonItem key="rightBarButtonItem" systemItem="add" id="LnB-Ci-YnO"/>
                    </navigationItem>
                    <connections>
                        <outlet property="navigationBarWithSegmentedControl" destination="8jj-w6-ZtU" id="Ggl-xb-fmj"/>
                        <outlet property="tableView" destination="HLl-W2-Moq" id="hEO-2U-I9k"/>
                    </connections>
                </viewController>
                <placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
            </objects>
            <point key="canvasLocation" x="894" y="791"/>
        </scene>
        <!--View Controller-->
        <scene sceneID="Bi7-4l-uRN">
            <objects>
                <viewController id="hcx-2g-4ts" sceneMemberID="viewController">
                    <layoutGuides>
                        <viewControllerLayoutGuide type="top" id="NSV-kw-fuz"/>
                        <viewControllerLayoutGuide type="bottom" id="aze-le-h11"/>
                    </layoutGuides>
                    <view key="view" contentMode="scaleToFill" id="1nd-qq-kDT">
                        <rect key="frame" x="0.0" y="0.0" width="375" height="603"/>
                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                        <subviews>
                            <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="k7W-CB-tpA">
                                <rect key="frame" x="0.0" y="0.0" width="375" height="603"/>
                                <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
                            </view>
                        </subviews>
                        <color key="backgroundColor" white="0.66666666666666663" alpha="0.5" colorSpace="calibratedWhite"/>
                        <constraints>
                            <constraint firstAttribute="trailing" secondItem="k7W-CB-tpA" secondAttribute="trailing" id="1t2-Bi-dR7"/>
                            <constraint firstItem="k7W-CB-tpA" firstAttribute="bottom" secondItem="aze-le-h11" secondAttribute="top" id="Fnm-UL-geX"/>
                            <constraint firstItem="k7W-CB-tpA" firstAttribute="leading" secondItem="1nd-qq-kDT" secondAttribute="leading" id="bKV-7A-hz0"/>
                            <constraint firstItem="k7W-CB-tpA" firstAttribute="top" secondItem="NSV-kw-fuz" secondAttribute="bottom" id="cFH-7i-vAm"/>
                        </constraints>
                    </view>
                </viewController>
                <placeholder placeholderIdentifier="IBFirstResponder" id="jPK-Z9-yvJ" userLabel="First Responder" sceneMemberID="firstResponder"/>
            </objects>
            <point key="canvasLocation" x="1566" y="791"/>
        </scene>
        <!--Navigation Controller-->
        <scene sceneID="1Pc-qt-rnW">
            <objects>
                <navigationController automaticallyAdjustsScrollViewInsets="NO" id="5TT-dT-dEr" sceneMemberID="viewController">
                    <toolbarItems/>
                    <navigationBar key="navigationBar" contentMode="scaleToFill" translucent="NO" id="lPt-hx-iar">
                        <rect key="frame" x="0.0" y="20" width="375" height="44"/>
                        <autoresizingMask key="autoresizingMask"/>
                    </navigationBar>
                    <nil name="viewControllers"/>
                    <connections>
                        <segue destination="BYZ-38-t0r" kind="relationship" relationship="rootViewController" id="6b8-br-zSy"/>
                    </connections>
                </navigationController>
                <placeholder placeholderIdentifier="IBFirstResponder" id="u7U-GH-NHe" userLabel="First Responder" sceneMemberID="firstResponder"/>
            </objects>
            <point key="canvasLocation" x="140" y="791.15442278860576"/>
        </scene>
    </scenes>
</document>

Results

enter image description here enter image description here enter image description here

Vasily Bodnarchuk
  • 24,482
  • 9
  • 132
  • 127
0

There are many ways to do what you asked. The easiest one being of course to just create it in the interface builder but I assume this is not what you had in mind. I created an example of the image you posted above. It's not exactly the same but you can play with the numerous properties to get the look and feel of what it is you are looking for.

In the ViewController.h

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController <UITableViewDataSource, UITableViewDelegate, UISearchBarDelegate>

@end

In the ViewController.m

#import "ViewController.h"

@interface ViewController ()

@property (strong, nonatomic) UISegmentedControl *mySegmentControl;
@property (strong, nonatomic) UISearchBar *mySearchBar;
@property (strong, nonatomic) UITableView *myTableView;
@property (strong, nonatomic) NSMutableArray *tableDataArray;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    // create a custom UIView
    UIView *myView = [[UIView alloc] initWithFrame:CGRectMake(0, 64, 320, 84)];
    myView.tintColor = [UIColor lightGrayColor]; // change tiny color or delete this line to default

    // create a UISegmentControl
    self.mySegmentControl = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObjects:@"All", @"Not on this iPhone", nil]];
    self.mySegmentControl.selectedSegmentIndex = 0;
    [self.mySegmentControl addTarget:self action:@selector(segmentAction:) forControlEvents:UIControlEventValueChanged];
    self.mySegmentControl.frame = CGRectMake(20, 10, 280, 30);
    [myView addSubview:self.mySegmentControl]; // add segment control to custom view

    // create UISearchBar
    self.mySearchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 40, 320, 44)];
    [self.mySearchBar setDelegate:self];
    self.mySearchBar.searchBarStyle = UISearchBarStyleMinimal;
    [myView addSubview:self.mySearchBar]; // add search bar to custom view

    [self.view addSubview:myView]; // add custom view to main view

    // create table data array
    self.tableDataArray = [[NSMutableArray alloc] initWithObjects:
                           @"Line 1",
                           @"Line 2",
                           @"Line 3",
                           @"Line 4",
                           @"Line 5",
                           @"Line 6",
                           @"Line 7",
                           @"Line 8",
                           @"Line 9",
                           @"Line 10",
                           @"Line 11",
                           @"Line 12", nil];
    self.myTableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 160, 320, 320)];
    [self.myTableView setDataSource:self];
    [self.myTableView setDelegate:self];
    [self.view addSubview:self.myTableView]; // add table to main view
}

-(void)searchBarSearchButtonClicked:(UISearchBar *)searchBar {
    [searchBar resignFirstResponder];
    NSLog(@"search text = %@",searchBar.text);
    // code for searching...
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return [self.tableDataArray count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil)
        {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
        }

    cell.textLabel.text = [self.tableDataArray objectAtIndex:indexPath.row];

    return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    NSLog(@"Selected table item: %@",[self.tableDataArray objectAtIndex:indexPath.row]);

    // do something once user has selected a table cell...
}

-(void)segmentAction:(id)sender {
    NSLog(@"Segment control changed to: %@",[self.mySegmentControl titleForSegmentAtIndex:[self.mySegmentControl selectedSegmentIndex]]);

    // do something based on segment control selection...
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end
pkamb
  • 33,281
  • 23
  • 160
  • 191
sangony
  • 11,636
  • 4
  • 39
  • 55
-2

displaysSearchBarInNavigationBar is the way to display a search bar as well as its scope bar in the navigation bar.

you need to just hide the search bar whenever you show custom title

Shubhank
  • 21,721
  • 8
  • 65
  • 83