UISegmentedControl debajo de UINavigationbar en iOS 7

¿Cómo hago un UISegmentedControl como parte de un UINavigationBar debajo de él? ¿Está conectado a UINavigationBar o es una vista completa separada que se acaba de agregar como subvista al controlador de vista de UINavigationController ? Parece que es parte de UINavigationBar ya que hay una sombra debajo de la barra.

enter image description here

    Es un efecto simple de lograr.

    Primero, coloca un segmento en una barra de herramientas. Coloque esta barra de herramientas justo debajo de la barra de navegación. Establezca el delegado de la barra de herramientas en su controlador de vista y devuelva UIBarPositionTopAttached en positionForBar: Puede ver en la aplicación de la tienda, si realiza un gesto pop interactivo, que la barra de segmento no se mueve igual que la barra de navegación. Eso es porque no son el mismo bar.

    enter image description here

    Ahora para quitar la línea del cabello. La “línea del cabello” es un UIImageView que es una subvista de la barra de navegación. Puede encontrarlo y configurarlo como oculto. Esto es lo que hace Apple en su aplicación de calendario nativo, por ejemplo, así como en la aplicación de la tienda. Recuerde mostrarlo cuando desaparece la vista actual. Si juegas un poco con las aplicaciones de Apple, verás que la línea de implantación del cabello está oculta en viewWillAppear: y configurada como se muestra en viewDidDisappear:

    Para lograr el estilo de la barra de búsqueda, simplemente establece searchBarStyle en UISearchBarStyleMinimal .

    Ahora para quitar la línea del cabello. La “línea del cabello” es un UIImageView que es una subvista de la barra de navegación. Puede encontrarlo y configurarlo como oculto. Esto es lo que hace Apple en su aplicación de calendario nativo, por ejemplo, así como en la aplicación de la tienda. Recuerde mostrarlo cuando desaparece la vista actual. Si juegas un poco con las aplicaciones de Apple, verás que la línea de implantación del cabello está oculta en viewWillAppear: y configurada como se muestra en viewDidDisappear :.

    Otro enfoque sería buscar la línea del cabello y moverla debajo de la barra de herramientas agregada. Esto es lo que se me ocurrió.

     @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 

    También encontré la muestra de código Apple NavBar (Personalización de UINavigationBar) muy útil para resolver este problema.

    También asegúrese de manejar el borde superior de la barra de herramientas de UIT , podría aparecer y podría confundirlo con la rayita del NavBar. También quería que el UIToolbar se viera exactamente como el NavBar, entonces probablemente quieras ajustar las Barras de herramientas barTintColor .

    Aquí hay un enfoque Swift orientado a los protocolos para este problema en particular, tomando como base la respuesta aceptada:

    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 } } 

    Puede encontrar la barra de navegación con UISegmentedControl en Apple Sample Code: https://developer.apple.com/library/ios/samplecode/NavBar/Introduction/Intro.html

    O puede crearlo programáticamente, aquí está el código en mi respuesta en el otro hilo Agregue control segmentado a la barra de navegación y mantenga el título con botones

    Yo quería hacer lo mismo … Y obtuve esto:


    1 – Subclase UINavigationBar

     //------------------------- // UINavigationBarCustom.h //------------------------- #import  @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 – Configure su NavigationController con la subclase

    Configure su NavigationController con la subclase


    3 – Agregue su UISegmentedControl en navigationBar

    enter image description here


    4 – Run and Fun -> no olvides poner el mismo color en ambos

    enter image description here


    fuente de búsqueda:

    Hackear UINavigationBar

    ASI pregunta

    Apple tiene una aplicación de muestra específicamente para esto. Describe la configuración de una imagen de sombra transparente y una imagen de fondo de color para la barra de navegación y cómo configurar una vista debajo de la barra de navegación. También tiene ejemplos de otras personalizaciones de barras de navegación.

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

    Intenté quitar la línea del cabello usando el método de @ Simon, pero no funcionó. Probablemente estoy haciendo algo mal porque soy súper novato. Sin embargo, en lugar de eliminar la línea, simplemente puede ocultarla utilizando el atributo hidden . Aquí está el código:

     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 } 

    Espero que esto ayude a alguien!

    UISegmentedControl debajo de UINavigationbar en swift 3/4

    Detalles

    Xcode 9.2, veloz 4

    Muestra completa

    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"?>                                                                                                                                               

    Resultados

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

    Hay muchas maneras de hacer lo que pediste. El más fácil es, por supuesto, crearlo en el constructor de interfaz, pero supongo que esto no es lo que tenía en mente. Creé un ejemplo de la imagen que publicaste arriba. No es exactamente lo mismo, pero puede jugar con las numerosas propiedades para obtener la apariencia de lo que está buscando.

    En ViewController.h

     #import  @interface ViewController : UIViewController  @end 

    En 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 

    displaysSearchBarInNavigationBar es la forma de mostrar una barra de búsqueda, así como su barra de scope en la barra de navegación.

    solo tiene que ocultar la barra de búsqueda cada vez que muestre un título personalizado