简体   繁体   English

如何在Swift 3的UIView类中使用performSegue

[英]How to use performSegue from UIView class in swift 3

I have an UIView class that contains a UILabel . 我有一个包含UILabelUIView类。 I have added a UITapGestureRecognizer for the UILabel and want to do a performSegue to open a new UIViewController on tap of the UILabel . 我为UILabel添加了UITapGestureRecognizer ,并希望执行performSegue以在UILabel点击上打开一个新的UIViewController The problem is that I can't use performSegue in UIView class. 问题是我不能在UIView类中使用performSegue

Can anyone please help to use performSegue in UIView class? 任何人都可以帮助在UIView类中使用performSegue吗?

I have added a tap gesture to my label as, 我在标签上添加了轻按手势,

nameLabel.isUserInteractionEnabled = true

let tap = UITapGestureRecognizer(target: self, action: #selector(tapFunction))  
tap.numberOfTapsRequired = 1
tap.numberOfTouchesRequired = 1
tap.isEnabled = true
nameLabel.addGestureRecognizer(tap)

Now in my tapFunction, 现在在我的tapFunction中,

func tapFunction(sender:UITapGestureRecognizer) {
    print("tap working")
    self.performSegue(withIdentifier: "memberSegue", sender: self)
}

But I get an error: 但是我得到一个错误:

"Value of type UIViewController has no member performSegue" “类型为UIViewController的值没有成员performSegue”

as it is an UIView Class. 因为它是一个UIView类。

You should try and separate any functionality from your UIViews . 您应该尝试将所有功能与UIViews分开。 A best practice is your UIViewControllers to be responsible for any functionality in your app and your UIViews to be used only for displaying elements. 最佳实践是UIViewControllers负责应用程序中的任何功能,而UIViews仅用于显示元素。 Thus I would suggest that you make your nameLabel a property in your UIView , so that you can access it from your UIViewController after instantiating the UIView . 因此,我建议您将nameLabelUIView一个属性,以便在实例化UIView之后可以从UIViewController访问它。 Then the code in your UIViewController should look like this: 然后, UIViewController的代码应如下所示:

let yourView = new YourView()
let tap = UITapGestureRecognizer(target: self, action: #selector(tapFunction))
tap.numberOfTapsRequired = 1
tap.numberOfTouchesRequired = 1
tap.isEnabled = true
yourView.nameLabel.addGestureRecognizer(tap)

and you would have your tap() function in your UIViewController . 并且您将在您的UIViewController具有tap()函数。

Make delegate in UIView Class and used to where you are using UIView in YourController class 在UIView类中创建委托,并习惯于在YourController类中使用UIView的位置

 protocol UIViewDelegate { 
     func tapFunction() //this function will be use in controller class which uiview are using
 }

 var delegate: UIViewDelegate?

 func tapFunction(sender:UITapGestureRecognizer) {
     delegate?.tapFunction()
 }

 class YourController: UIViewController, UIViewDelegate {
     let yourView = YourView()
     yourView.delegate = self

     func tapFunction() {
         self.performSegue(withIdentifier: "memberSegue", sender: self)
     }
 }

you can do it by protocol and delegate. 您可以按协议和委托进行操作。 Because actually you can not do it from UIView you should always do it from controller. 因为实际上您不能通过UIView执行此操作,所以应该始终从控制器执行此操作。

/// add this protocol in your project
protocol ViewProtocol {
    func performSegueFromView()
}

class View : UIView {

    /// add this line to your view
    var delegate : ViewProtocol?


    /// replace your tap function with this
    func tapFunction(sender:UITapGestureRecognizer) {

        print("tap working")

        self.delegate?.performSegueFromView()
    }

}


class ViewController : UIViewController, ViewProtocol {

    override func viewDidLoad() {

        /// create view
        let view = View()
        /// assign view delegate
        view.delegate = self

    }

    /// delegate function
    func performSegueFromView() {
        ///peform segue from controller because you can not do this from uiview anyway
        self.performSegue(withIdentifier: "memberSegue", sender: self)
    }

}

I would suggest you to add action for that tap gesture instead of segue. 我建议您为该轻击手势添加动作,而不要选择segue。

TapRecognizer.addTarget(self, action: #selector(YourFunc))

Samle Func: Samle Func:

func YourFunc(){                  
        let storyBoardHome = UIStoryboard(name: "", bundle: nil)        
     let memberController = storyBoardHome.instantiateViewController(withIdentifier: "") 
           self.navigationController?.pushViewController(memberController, animated: true)
                }

Refer This : https://stackoverflow.com/a/26366366/6818278 参考此: https : //stackoverflow.com/a/26366366/6818278

the error you wrote is wrong, UIViewController's do have that method. 您编写的错误是错误的,UIViewController确实具有该方法。 Your error must be "UIVIew has no member...", as for the solution you just need to get a reference to whatever UIViewController is using this specific view. 您的错误必须是“ UIVIew没有成员...”,因为对于解决方案,您只需获取对使用此特定视图的任何UIViewController的引用即可。

Then use that reference to call your perform method. 然后使用该引用来调用您的perform方法。

For example, if your custom View is being added programmatically, you can add an extra property to your class like 例如,如果您的自定义视图是通过编程方式添加的,则可以向您的类添加额外的属性,例如

weak var myVC : UIViewController?

then after instantiating it just assign it to this property. 然后实例化后,只需将其分配给该属性。

Then the perform segue becomes: 然后表演赛段变成:

myVC?.performSegue....

Alternatively you can just add the tap gesture recognizer from the UIViewController that is using this view, then have the view show it from there. 或者,您可以只从使用此视图的UIViewController添加轻击手势识别器,然后从那里显示该视图。


Or you could just use: 或者,您可以使用:

UIApplication.shared.keyWindow?.rootViewController.performSegue...

But if you do, you should be careful as this one might have unintended consequences depending on what you are presenting and which is the current rootViewController. 但是,如果这样做,则应小心,因为这可能会带来意想不到的后果,具体取决于您所呈现的内容以及当前的rootViewController。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM