简体   繁体   中英

UiSegmentedControl on NavigationBar below Title

I am new on iOS Development and during my works for an app I am building right now some doubts have appeared to me. I am trying to build a Screen that will be compounded by multiple ViewControllers, but on the NavigationBar I would like to have a UiSegmentedControl above the Title, something like a Scope Bar to control the navigation between the children ViewController. I wanted to build something similar to what we have on HealthKit Dashboard:

在此处输入图片说明 .

What kind of approach do you suggest to do that? I understand that some questions have already been done about it, but after a long research I have not got to a conclusion.

During my research I noticed that a UISearchBar on the NavigationBar ( to build the Scope Bar ) is only possible for UITableViewControllers , Am I right? So I think that can not be an approach.

My next idea was to use a UISegmentedControl placed manually below the NavigationBar and then use the Containment Api to change to the different ViewControllers for this Screen. The problem here, is I will have to duplicate the UISegmentedControl on all children ViewControllers. Is there any way to not have to duplicate that?

Another approach I tried was doing my own titleView for the NavigationBar with a NavigationBar and a UISegmentedControl below. I don't like this idea, neither it went well trying to replicate the NavigationBar.

Finally, another approach I thought was using a UIPageViewController . Although this approach sounds a good idea to me, I think I will also have to duplicate the UISegmentedControl .

In the end I think the best solution is to have a UISegmentControl on the NavigationBar, but I am not seeing how to implement this.

What do you think is the best approach to accomplish my ideia? I thought that it would be easy because it is a pattern I see in many apps. Any suggestions?

I am doing this on XCode 6.1.1 using Swift for iOS 8.

Thanks a lot for your help.

You can get this effect by adding the segment as the title view and setting your desired prompt. In interface builder it looks like this:在此处输入图片说明

Add a UIToolbar to your view. Doesn't matter if you add it through code or interface builder. Then you add your UISegmentedControl as custom view of an UIBarButtonItem

let toolbar = UIToolbar()
toolbar.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(toolbar)
NSLayoutConstraint.activate([
    toolbar.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
    toolbar.leadingAnchor.constraint(equalTo: view.leadingAnchor),
    toolbar.trailingAnchor.constraint(equalTo: view.trailingAnchor),
])

// Add SegmentedControl like this:
toolbar.setItems([UIBarButtonItem(customView: mySegmentedControl)], animated: false)
toolbar.delegate = self

Then implement this delegate method (See documentation for UIBarPosition.topAttached )

extension MyViewController: UIToolbarDelegate {
    public func position(for bar: UIBarPositioning) -> UIBarPosition {
        .topAttached
    }
}

Then you have what you need. But there's still a separator line between the navigation bar and the toolbar. To get rid of it use this extension methods and call them in viewWillAppear and viewWillDisappear :

extension UINavigationBar {
    func hideHairline() {
        // Hide border line of navigation bar since we're showing a toolbar
        if #available(iOS 13.0, *) {
            standardAppearance.shadowColor = nil
            standardAppearance.shadowImage = nil
        } else {
            shadowImage = UIImage()
            setBackgroundImage(UIImage(), for: .default)
        }
    }
    
    func restoreHairline() {
        // Hide border line of navigation bar since we're showing a toolbar
        if #available(iOS 13.0, *) {
            standardAppearance.shadowColor = .separator
        } else {
            shadowImage = nil
            setBackgroundImage(nil, for: .default)
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM