将子UIViewConroller添加到UITabBarController

时间:2018-11-16 12:51:27

标签: ios uiviewcontroller uitabbar

我的应用程序的结构如下:

UITabBarController-> UINavigationController-> [UIViewController1,UIViewController2,UIViewController3]

我需要实现的是在一个小框架中的tabBar上方显示并隐藏一个子UIViewController,以便在导航堆栈中的所有控制器上都可以看到它。因此,当用户来回浏览堆栈时,如果添加了该子级,则必须在所有控制器上可见。

我尝试将孩子添加到UITabBarController,并且工作正常,我遇到的问题是将阴影标签栏项添加到了标签栏,这是我不想要的。

我曾尝试将子级添加到导航控制器,但是在向后浏览堆栈时又添加了其他问题,它解散了子级而不是self并加载了相同的控制器。

有人对在整个导航过程中如何保留此子控制器有任何建议。

我在这里搜索了任何建议,但没有一个像我的情况那样,因此没有帮助。

谢谢

3 个答案:

答案 0 :(得分:2)

问题:

将子视图控制器添加到java.nio.file.AccessDeniedException: C:\...\Data\<directory> at sun.nio.fs.WindowsException.translateToIOException(Unknown Source) at sun.nio.fs.WindowsException.rethrowAsIOException(Unknown Source) at sun.nio.fs.WindowsException.rethrowAsIOException(Unknown Source) at sun.nio.fs.WindowsFileSystemProvider.newByteChannel(Unknown Source) at java.nio.file.Files.newByteChannel(Unknown Source) at java.nio.file.Files.newByteChannel(Unknown Source) at java.nio.file.Files.readAllBytes(Unknown Source) at main.UploadObject.uploadObject(UploadObject.java:25) at main.EngineGUI.btnLoadEngineActionPerformed(EngineGUI.java:151) at main.EngineGUI.access$2(EngineGUI.java:141) at main.EngineGUI$3.actionPerformed(EngineGUI.java:128) at javax.swing.AbstractButton.fireActionPerformed(Unknown Source) at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source) at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source) at javax.swing.DefaultButtonModel.setPressed(Unknown Source) at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source) at java.awt.Component.processMouseEvent(Unknown Source) at javax.swing.JComponent.processMouseEvent(Unknown Source) at java.awt.Component.processEvent(Unknown Source) at java.awt.Container.processEvent(Unknown Source) at java.awt.Component.dispatchEventImpl(Unknown Source) at java.awt.Container.dispatchEventImpl(Unknown Source) at java.awt.Component.dispatchEvent(Unknown Source) at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source) at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source) at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source) at java.awt.Container.dispatchEventImpl(Unknown Source) at java.awt.Window.dispatchEventImpl(Unknown Source) at java.awt.Component.dispatchEvent(Unknown Source) at java.awt.EventQueue.dispatchEventImpl(Unknown Source) at java.awt.EventQueue.access$500(Unknown Source) at java.awt.EventQueue$3.run(Unknown Source) at java.awt.EventQueue$3.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source) at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source) at java.awt.EventQueue$4.run(Unknown Source) at java.awt.EventQueue$4.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source) at java.awt.EventQueue.dispatchEvent(Unknown Source) at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source) at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source) at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source) at java.awt.EventDispatchThread.pumpEvents(Unknown Source) at java.awt.EventDispatchThread.pumpEvents(Unknown Source) at java.awt.EventDispatchThread.run(Unknown Source) 会将新标签添加到标签栏。并且在iOS 13.4中会清楚显示

解决方案

解决方案是覆盖UITablViewConltroller并仅返回原始控制器。

viewControllers

更多

更改标签栏项目标志

/// Neglect child insertion to `viewControllers`

var _viewControllers: [UIViewController]?

override var viewControllers: [UIViewController]? {
    get {
        return _viewControllers
    }
    set {
        _viewControllers = newValue
    }
}

答案 1 :(得分:1)

我假设您以编程方式将容器视图添加到了选项卡控制器中,然后将子视图控制器添加到了该容器视图中。我说的对吗?

在这种情况下,选项卡控制器将子控制器添加到其viewControllers数组中。

您可以在添加孩子后立即致电viewControllers?.removeLast()来解决此问题。

此代码对我有用:

override func viewDidLoad() {
    super.viewDidLoad()

    let containerView = UIView()
    view.addSubview(containerView)

    containerView.translatesAutoresizingMaskIntoConstraints = false
    containerView.bottomAnchor.constraint(equalTo: tabBar.topAnchor).isActive = true
    containerView.leftAnchor.constraint(equalTo: tabBar.leftAnchor, constant: 40).isActive = true
    containerView.rightAnchor.constraint(equalTo: tabBar.rightAnchor, constant: -40).isActive = true
    containerView.heightAnchor.constraint(equalToConstant: 150).isActive = true

    if let childVC = self.storyboard?.instantiateViewController(withIdentifier: "ChildViewController") {
        addChild(childVC)
        containerView.addSubview(childVC.view)
        childVC.didMove(toParent: self)

        childVC.view.translatesAutoresizingMaskIntoConstraints = false
        childVC.view.topAnchor.constraint(equalTo: containerView.topAnchor).isActive = true
        childVC.view.bottomAnchor.constraint(equalTo: containerView.bottomAnchor).isActive = true
        childVC.view.rightAnchor.constraint(equalTo: containerView.rightAnchor).isActive = true
        childVC.view.leftAnchor.constraint(equalTo: containerView.leftAnchor).isActive = true

        if let childIndex = viewControllers?.firstIndex(of: childVC) {
            viewControllers?.remove(at: childIndex)
        }
    }
}

在这里,我检查了removeLast()是否确实在该数组中,而不仅仅是调用了childVC。只是为了安全起见。

答案 2 :(得分:1)

不幸的是,所有提议的解决方案都不适合我,但我只是通过从 UITabBarController 的 viewControllers getter 中过滤掉孩子来解决问题:

override var viewControllers: [UIViewController]? {
    get {
        super.viewControllers?.filter { viewController in
            viewController != self.yourChildViewController
        }
    }
    set {
        super.viewControllers = newValue
    }
}