如何在 UIView 类中调用 presentViewController?

Posted

技术标签:

【中文标题】如何在 UIView 类中调用 presentViewController?【英文标题】:How can I call presentViewController in UIView class? 【发布时间】:2016-01-07 07:04:17 【问题描述】:

我的项目中有一个自定义选项卡,它位于应用程序的每个屏幕上,因此我制作了自定义 UIView 类和 xib 文件并在其中添加了按钮。现在我想要我的按钮在具有不同story board id 的不同屏幕上进行导航。但是我不能从UIView 类中调用presentViewController。以前我在extension 类中自定义函数以在屏幕之间导航,但UIView 类也不能调用该函数。

import UIKit

@IBDesignable class tab: UIView 

var view: UIView!

@IBAction func btn1(sender: UIButton) 
    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    let vc = storyboard.instantiateViewControllerWithIdentifier("6")
    self.presentViewController(vc, animated: true, completion: nil)

override init(frame: CGRect) 
    super.init(frame: frame)
    xibSetup()


required init?(coder aDecoder: NSCoder)  
    super.init(coder: aDecoder) 
    xibSetup()


func xibSetup() 
    view = loadViewFromNib() 
    view.frame = bounds 
    view.autoresizingMask = [UIViewAutoresizing.FlexibleWidth, UIViewAutoresizing.FlexibleHeight] 
    addSubview(view)
 
func loadViewFromNib() -> UIView 
    let bundle = NSBundle(forClass: self.dynamicType)
    let nib = UINib(nibName: "tab", bundle: bundle) 
    let view = nib.instantiateWithOwner(self, options: nil)[0] as! UIView
    return view
 

【问题讨论】:

你可能需要看看这个***.com/questions/29094106/… 【参考方案1】:

在你的按钮上调用这个函数

func infoClick()  

        let storyboard: UIStoryboard = UIStoryboard (name: "Main", bundle: nil)
        let vc: CampainDetailView = storyboard.instantiateViewControllerWithIdentifier("campainDetailView") as! CampainDetailView
        let currentController = self.getCurrentViewController()
        currentController?.presentViewController(vc, animated: false, completion: nil)

    

这个函数将创建根视图控制器

 func getCurrentViewController() -> UIViewController? 

    if let rootController = UIApplication.shared.keyWindow?.rootViewController 
        var currentController: UIViewController! = rootController
        while( currentController.presentedViewController != nil ) 
            currentController = currentController.presentedViewController
        
        return currentController
    
    return nil


上面的代码必须有效,它在 Swift 4.0 中为我工作

【讨论】:

谢谢,在最新的 swift 版本中选择根视图控制器时看起来会有些不同。【参考方案2】:

您可以使用委托。将此添加到 Tab 类中

protocol TabDelegate 

    func didButtonTapped()


var delegate: TabDelegate?

@IBAction func btn1(sender: UIButton) 
    delegate?.didButtonTapped()

在使用 Tab 的 viewController 中。 像这样设置委托

let tab = Tab()
tab.delegate = self

然后在委托方法中推送新的viewController 您可以制作一个 BaseViewController 来执行此操作,然后它的所有 viewController 子类都可以具有相同的功能。

class BaseViewController: UIViewController, TabDelegate 

    func didButtonTapped() 
        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        let vc = storyboard.instantiateViewControllerWithIdentifier("6")
        self.presentViewController(vc, animated: true, completion: nil)
    


Class ViewControllerA: BaseViewController 


Class ViewControllerB: BaseViewController 

【讨论】:

tab().delegate 处的错误 = self 无法将“ViewController”类型的值分配给“TabDelegate”类型? 另外我在每个控制器中都有这个视图,所以我应该在每个视图控制器中都这样做吗?有没有办法对所有屏幕只做一次 更新了答案。希望有帮助。【参考方案3】:

给这个类添加一个属性,然后你就可以使用控制器的方法了。

弱变量控制器:UIViewController!

self.controller?.presentViewController(vc, animated: true, completion: nil)

【讨论】:

错误消失了,但仍然没有导航到那个屏幕

以上是关于如何在 UIView 类中调用 presentViewController?的主要内容,如果未能解决你的问题,请参考以下文章

iOS:UIView子类init会调用[super init]然后调用超类中的方法,为啥会调用[subclass initWithFrame:xx]?

UIView 类中的 Swift 集合视图委托

如何访问使用 Paintcode 生成的 UIView 自定义类中的图层?

如何调用从 NSObject 类添加视图

在 Swift 中单击 NSObject 内部的 tableView 中的项目时,如何在 NSObject 类中的 UIViewController 上的 UIView 之间正确切换?

在 UIView 中将 tapGestureRecognizer 添加到 UIImageView 并通过协议调用方法