如何在UINavigationBar中添加UISegmentedControl?

19

我尝试将UISegmentedControl添加到具有标题的UINavigationBar底部。但我无法添加它,也无法将UISegmentedControl添加到tableView.headerView中,因为我需要在tableView.headerView中使用搜索栏。因此,只有一种解决方案,那就是将UISegmentedControl添加到UINavigationBar底部。还有其他解决方法吗?

这是我尝试过的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)
                  }
          }

你可能在寻找这个..在导航栏中添加分段控制器 - Rahul Shirphule
你能添加一个截图或图示来展示你想要实现的内容吗? - Vivek Molkar
@VivekMolkar,我正在寻找Rahul Shirphule提供的编程解决方案,以通过编程方式将分段控件添加到导航栏中并保留标题和按钮。 - Jacky Shek
6个回答

30

如何在Swift 5中在UINavigationBar中添加分段控制器

    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

2
有人也给我的回答点了踩...我猜是有人因为自己无法理解而感到沮丧。 - Magoo
@Leon,请仔细阅读问题,它明确定义了在UINavigationbar中而不是在UINavigationbar下方,但有时候有人会没有任何合理的理由就给出负评。 - Hardik Thakkar
我不想再为这个愚蠢的观点与你讨论了。 - Hardik Thakkar
考虑到其他4个人已经点赞了我的评论,我认为我的观点是有效的,并且完美地回答了你的问题。如果你不在意按照提问的方式回答问题,那么也许这个平台并不适合你。 - Leon
但是我在2017年4月10日问了“谁给了负评,请给出理由”,你为什么有这么多空闲时间,在一年后才回答呢?请不要打扰我,这是对你的最后警告。你可以看到我的回答有14个赞,我很高兴其他人能够使用我的回答。 - Hardik Thakkar

21

把它放在navigationBar上有一个右边的、左边的和一个标题视图,可以使用...来访问。

self.navigationItem.titleView = mySegmentedControl

供以后参考。

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

如果希望在导航视图下方但又保持静态,请将其添加到viewController.view中...您是否在使用UITableViewController? 如果是这样,可以考虑切换到UIViewController并添加一个tableView,然后将toolbarview作为其self.view的子视图。


1
是的,我正在使用UITableViewController。您的答案“UIViewController和添加tableView然后将您的toolbarview作为子视图”,这对我很有效。我已经在一个UIViewController中添加了tableView,可以编辑tableView的偏移量y。非常感谢。 - Jacky Shek
好的,很高兴我能帮到你。 - Magoo
它工作得很奇怪。如果我设置navigationBar.prefersLargeTitles = true,那么mySegmentedControl会出现在标题上方。 - Gargo

8
我想您正在寻找这个。
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


我该如何使其在结束编辑后仍然可见呢?"searchController.searchBar.showsScopeBar = true" 可以让它们在第一次可见,但在结束编辑后又会隐藏。:-( 请帮忙。 - Gurjit Singh

3

这是我在Objective C中实现的方法(抱歉,我还没学过Swift):

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

在UITableViewController中(其中之一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)];

我已经尝试了你的代码,但它重叠了tableView.headerView,我该如何将表格视图移动到段控件下面? - Jacky Shek

2
您可以将分段控件添加到搜索栏中,而不是导航项。如果您像我一样需要一个大标题+搜索栏+导航项,那么使用当前的顶部答案是不可能的。
@Abhishek的回答接近正确。您可以执行以下操作:
// 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,带有.showsScopeBar = true的这一行是解决您问题的方法。


最佳答案以前对我有用过。我不会说它现在不起作用或不适用,因为我现在不维护该应用程序,并且当时它是有效的。 - Jacky Shek

1
你可以自定义navigationItem的titleView,像这样:
self.navigationItem.titleView = segmentview

不应向导航栏添加子视图,因为在推送或弹出UIViewController后,子视图仍然存在于导航栏上。


我已经尝试过,但它会删除导航栏的标题。 - Jacky Shek

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接