swift 如何更改现有的UIViewController(由UITabController控制),使其显示为弹出窗口?

vawmfj5a  于 2023-04-19  发布在  Swift
关注(0)|答案(1)|浏览(124)

抱歉,Swift新手。我知道还有其他类似问题的答案,但我相信这个场景是不同的:
我正在对一个现有的应用程序进行一些UI更改。从包含的图片中可以看到,UI是从故事板创建的。有一个主选项卡控制器,控制5个UIViewControllers。它们都工作正常但我需要VC4打开作为一个弹出窗口上的任何其他VC显示的时间。我已经尝试设置不同的过渡风格演示设置,但他们不'似乎改变不了什么。
我希望它能从底部向上滑动。另外(在这个示例图片中没有显示),VC4的中心会有一个较小的视图,这将是一个对话框,需要在其他任何事情(包括其他标签栏项目)发生之前关闭。理想情况下,这个较小视图周围的区域将是VC下面的灰色版本。
我该如何实现这一点?

hjzp0vay

hjzp0vay1#

下面的解决方案涉及到创建一个自定义的UITabBarController子类。这个自定义类保存控制器的最后一个视图控制器,并用一个空的视图控制器替换它。然后它拦截一个检查是否应该选择一个选项卡。如果最后一个选项卡被选择,那么选择被拒绝,然后最后一个视图控制器以模式呈现。

class SpecialTabBarController: UITabBarController {
    private var lastViewController: UIViewController?

    // When the view controllers are set, replace the last view controller
    // with a dummy controller (so the tab appears normally). Save off the
    // the real last view controller for modal presentation when needed.
    override var viewControllers: [UIViewController]? {
        didSet {
            if let viewControllers, viewControllers.count > 1 {
                lastViewController = viewControllers.last
                var newVCs = Array(viewControllers.dropLast())
                let extra = UIViewController()
                extra.tabBarItem = lastViewController?.tabBarItem
                newVCs.append(extra)
                super.viewControllers = newVCs
            }
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        delegate = self

        if let vcs = viewControllers {
            viewControllers = vcs
        }
    }
}

extension SpecialTabBarController: UITabBarControllerDelegate {
    // When a tab is tapped, this is called to confirm whether the
    // corresponding controller should be shown. Here we disable the
    // showing of the last view controller and then manually present it.
    func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
        if let lastViewController, viewController === viewControllers?.last {
            present(lastViewController, animated: true)
            return false
        } else {
            return true
        }
    }
}

此解决方案将与以编程方式创建的选项卡栏控制器以及在故事板中创建的选项卡栏控制器一起工作。要在故事板中工作,请将选项卡栏控制器的类从默认值UITabBarController更新为SpecialTabBarController。这是使其工作的唯一更改。
这个解决方案确实有一个限制。由于SpecialTabBarController使自己成为UITabBarControllerDelegate,所以不能将任何其他对象作为委托。尽管如果需要,可以解决这个问题。这留给读者练习。
对于希望位于最后一个视图控制器(VC4)中心的对话框,可以让该视图控制器的代码在出现时显示UIAlertController

相关问题