如何在 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]?
如何访问使用 Paintcode 生成的 UIView 自定义类中的图层?
在 Swift 中单击 NSObject 内部的 tableView 中的项目时,如何在 NSObject 类中的 UIViewController 上的 UIView 之间正确切换?