标题下方的NavigationBar上的UiSegmentedControl

时间:2014-12-20 19:49:24

标签: ios swift ios8 uistoryboard

我是iOS开发的新手,在我正在建立的应用程序的工作中,我正在建立一些疑问。我正在尝试构建一个将由多个ViewControllers复合的Screen,但是在NavigationBar上我想在Title上面有一个UiSegmentedControl,类似于Scope Bar来控制子ViewController之间的导航。我想构建类似于HealthKit仪表板上的内容:

enter image description here

您建议采取何种方法?我知道有些问题已经完成,但经过长时间的研究后我还没有得出结论。

在我的研究过程中,我注意到导航栏上的UISearchBar(构建范围栏)只适用于UITableViewControllers,我是对的吗?所以我认为这不是一种方法。

我的下一个想法是在NavigationBar下方手动放置UISegmentedControl,然后使用Containment Api更改为此屏幕的不同ViewControllers。这里的问题是,我将不得不在所有子ViewControllers上复制UISegmentedControl。有没有办法不必复制它?

我尝试的另一种方法是使用NavigationBar和UISegmentedControl为NavigationBar创建自己的titleView。我不喜欢这个想法,也没有尝试复制NavigationBar。

最后,我认为另一种方法是使用UIPageViewController。虽然这种方法对我来说听起来不错,但我想我也必须复制UISegmentedControl

最后我认为最好的解决方案是在NavigationBar上有一个UISegmentControl,但我没有看到如何实现它。

您认为实现我的意识形态的最佳方法是什么?我认为这很容易,因为它是我在许多应用程序中看到的模式。有什么建议吗?

我在XCode 6.1.1上使用Swift for iOS 8进行此操作。

非常感谢你的帮助。

2 个答案:

答案 0 :(得分:2)

您可以通过将细分添加为标题视图并设置所需的提示来获得此效果。在界面构建器中,它看起来像这样: enter image description here

答案 1 :(得分:0)

UIToolbar 添加到您的视图中。如果您通过代码或界面构建器添加它并不重要。然后将您的 UISegmentedControl 添加为 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

然后实现这个委托方法(见documentation UIBarPosition.topAttached

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

然后你就有了你需要的东西。但是导航栏和工具栏之间仍然有一条分隔线。要摆脱它,请使用此扩展方法并在 viewWillAppearviewWillDisappear 中调用它们:

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