moonvader
moonvader

Reputation: 21111

perform segue from UIView

I have ViewController and there is UIView in it.

This UIView has separate class myView and there are many UI elements - one of them is CollectionView.

What I want is to perform segue when one of collection elements in myView is selected. But when I try to add line

performSegue(withIdentifier: "myIdintifier", sender: self)

to collection's view didSelectItemAt method I get error

Use of unresolved identifier 'performSegue'

And I understand that this is because I do it inside class that extends UIView and not UIViewController.

So how can I perfrom segue in this case? And also how can I prepare for segue?

Upvotes: 1

Views: 2624

Answers (3)

Antonia Zhang
Antonia Zhang

Reputation: 103

Other than defining protocol, you can also use Notification. First, extent nonfiction.name:

extension Notification.Name {
    static let yourNotificationName = Notification.Name(“yourNotificationName”)
}

Then right where you want to perform segue but can’t in your custom UIView:

NotificationCenter.default.post(name: .yourNotificationName, object: self)

Finally, you can listen to the notification in your viewControllers:

private var observer: NSObjectProtocol?
override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    observer = NotificationCenter.default.addObserver(forName: .yourNotificationName, object: nil, queue: nil) {notification in
    self.performSegue(withIdentifier:”your segue”, sender: notification.object}

Don’t forget to remove it:

override func viewWillDisappear(_ animated: Bool){
    super.viewWillDisappear(animated)
  NotificationCenter.default.removeObserver(observer)

}

Upvotes: 0

Maulik Pandya
Maulik Pandya

Reputation: 2230

Here I am going to evaluate it in step by step manner.

Step - 1

Create custom delegate using protocol as below snippet will guide you on your custom UIView. protocol must exist out of your custom view scope.

protocol CellTapped: class {
    /// Method
    func cellGotTapped(indexOfCell: Int) 
}

Don't forgot to create delegate variable of above class as below on your custom view

var delegate: CellTapped!

Go with your collection view didSelect method as below

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        if(delegate != nil) {
            self.delegate.cellGotTapped(indexOfCell: indexPath.item)
        }
    }

Step - 2

Let's come to the your view controller. give the CellTapped to your viewcontroller.

class ViewController: UIViewController,CellTapped {

    @IBOutlet weak var myView: MyUIView! //Here is your custom view outlet
    override func viewDidLoad() {
        super.viewDidLoad()
        myView.delegate = self  //Assign delegate to self
    }

    // Here you will get the event while you tapped the cell. inside it you can perform your performSegue method.
    func cellGotTapped(indexOfCell: Int) {
        print("Tapped cell is \(indexOfCell)")
    }
}

Hope this will help you.

Upvotes: 3

Abdelahad Darwish
Abdelahad Darwish

Reputation: 6067

You can achieve using protocols/delegates.

 // At your CustomView

protocol CustomViewProtocol {
    // protocol definition goes here
    func didClickBtn()
}


 var delegate:CustomViewProtocol




@IBAction func buttonClick(sender: UIButton) {
    delegate.didClickBtn() 
  }




//At your target Controller
public class YourViewController: UIViewController,CustomViewProtocol

let customView = CustomView()
customView.delegate = self

func didClickSubmit() {
     // Perform your segue here
}

Upvotes: 2

Related Questions