How to Call Presentviewcontroller in Uiview Class

How can I call presentViewController in UIView class?

Call this function on your button

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)

}

This function will create root view controller

 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

}

This above code must work, it is working for me in Swift 4.0

How call presentViewController from UIView?

You are instantiating a new UIViewController here

func myV1(sender : UIButton!) {

v1Ctrl = V1ViewController()
v1Ctrl.presentViewController(SecondViewController(), animated : true, completion : nil)

}

And the v1Ctrl, which now should present a new UIViewController, is not added to the Window hierarchy before.

Generally, you should think about your architecture because a UIView should not be responsible for creating a new UIViewController and present it.

The quickest fix for your problem should be to assign the v1Ctrlvar in viewDidLoad of class V1ViewController like and remove the line v1Ctrl = V1ViewController()

class V1ViewController : UIViewController {

var V1 : Myv1!

override func viewDidLoad() {

V1 = Myv1()
V1.v1Ctrl = self
self.view.addSubView(V1)

}
}

.

func myV1(sender : UIButton!) {

v1Ctrl.presentViewController(SecondViewController(), animated : true, completion : nil)

}

Using presentViewController from UIView

Only UIViewController can present another view controller, so if you need to show a viewcontroller from view there are several way, one of them is like this:

make a viewcontroller on which your parent view is situated a delegate of it

ParentView *view = [ParentView new];
...
view.delegate = self;

then, inside ParentView call method of that delegate

- (IBAction)homeButtonPressed:(id)sender {
[self.delegate buttonPressed];
}

and then, inside your VC implement

 -(void)buttonPressed {
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
ViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"ViewController"];
[vc setModalPresentationStyle:UIModalPresentationFullScreen];
[self presentViewController:vc animated:NO completion:NULL];
}

If you need to keep this code inside UIView and avoid delegation you can do a trick like this (personally i don't like it but it should work)

-(void)buttonPressed{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
ViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"ViewController"];
[vc setModalPresentationStyle:UIModalPresentationFullScreen];
[(UIViewController*)self.nextResonder presentViewController:vc animated:NO completion:NULL];
}

iOS how present Modal ViewController from Uiview

When you need a communication between UIView instance and UIViewController, there are a few known iOS concepts, which you should adhere to. As you have figured out that UIView cannot really present a new controller (missing either presetViewController:animated:completion methods or navigationController property, which are both present in UIViewController).

Views are supposed to be the most reusable parts of your code, so you must think of a way to design your views to be completely blind to where they are at. They usually only know about user interaction.

So first, what you must do is refactor your view.

  1. If your UIView is supposed to be a UIControl (has some kind of target selectors), you need to use add target in your controller to get callback from view interaction.
  2. You can use delegate pattern as used in UITableView or UICollectionView, which is designed as a protocol.
  3. You can use gesture recognizers added to a view (UITapGestureRecognizer for example), so the controller knows about user interaction.

You can even mix and match those architectural patterns.

But you should really look into iOS programming basics, to understand this better.

In addition the first error I see in your code is that you create a generic UIViewController, when you should really be creating custom subclasses of it, defined in Storyboard and separate subclass of UIViewController.

The second error I see is that your UIView responds do tableView:didSelectRowAtIndexPath: method, which should in fact never happen. All this code must be moved back to one UIViewController subclass.

How to navigate To a ViewController From xib file of a UIView Class

I did it in a different way. In class file

class SlideMenuView: UIView { 

var navigationController: UINavigationController? // Declare a navigation controller variable

// And create a method which take a navigation controller

func prepareScreen(navController: UINavigationController)-> UIView {

navigationController = navController
let nibView = NSBundle.mainBundle().loadNibNamed("SlideMenuView", owner: self, options: nil)[0] as! UIView
self.addSubview(nibView)
return nibView
}

// In Button action

@IBAction func btnAction(sender: UIButton) {

var storyBoard = UIStoryboard(name: "Main", bundle: nil)
let nextViewController = storyBoard!.instantiateViewControllerWithIdentifier("NextViewController") as! UIViewController
navigationController?.pushViewController(nextViewController, animated: true)
}
}
// For calling from UIViewController

slideBarMenuIstance.prepareScreen(self.navigationController!)

How would you presentViewController from subview?

You can always use application rootviewController to present your alert view controller :) You dont always have to opt for your view controller's view :) rootview controller is always accessible no matter where your control is :)

Here is what you can do :)

Objective C

 AppDelegate *delegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
[delegate.window.rootViewController presentViewController:your_alert_view_controller animated:YES completion:nil];

Swift

let appDelegate : AppDelegate? = UIApplication.sharedApplication().delegate as? AppDelegate
if let unwrappedAppdelegate = appDelegate {
unwrappedAppdelegate.window!.rootViewController! .presentViewController(alert, animated: true, completion: nil)
}

Hope my answer helped you :)

How to call presentViewController?

You call the method on the UIViewController that is your MainView, and pass it your UIViewController you want to be the ActionSheet.

[mainViewController presentViewController:actionSheetController animated:YES];

To dismiss the UIActionSheet, dimissWithClickedButtonIndex:animated: is a method for the UIActionSheet that you can implement. The method can be called by whoever (so if you want to dismiss it from your mainview have a reference to the action sheet and do something like [self.myActionSheet dismissWithClickedButtonIndex:0 animated:YES];

The method is also called whenever the 'cancel' button is clicked by the user.

how to instantiate ViewController from UIView in SWIFT

However..i accomplised using a delegate to pass an id from UIView to UIViewController and checking to the id i instantiated ViewController From UIViewController class as Para said in his answer . I did it as below

Steps:

1) First create a protocol

2) create a Variable delegate conforming to protocol

3)Then create a call back method.

//Step1:    
protocol SendIndexDelegate{
func sendIndex(Int);
}

class CustomSwipeView: UIView , UITableViewDataSource , UITableViewDelegate {

var delegate : SendIndexDelegate? //Step2
override init(frame: CGRect) {
super.init(frame: frame)
self.addCustomView()
}
......

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
var row = indexPath.row
//for optional binding
if let temp = self.delegate {
delegate?.sendIndex(row) //Step 3
}else{
println("optional value contains nill value")
}
}
}

Steps Continued for Another Class:

4) Conform to the protocol SendIndexDelegate(so method sendIndex(Int) must be impelemented by this class)

5) Assign the value self in variable delegate in the optional variable delegate(it says that i will act as delegate for Class CustomSwipeView and implement the method sendIndex(Int))

6) Now implement the method and add body to it(because it has been delegate so must handle actions of the above class through call back method)

    class RootViewController: UIViewController,SendIndexDelegate //Step4 {

let rect: CGRect = CGRect (x: self.view.frame.size.width, y :10 , width: self.view.frame.size.width-50, height: self.view.frame.size.height-10)
var a = CustomSwipeView(frame : rect)
a.delegate = self//step5
self.myView = a
self.view.addSubview(self.myView)
}
// Step 6:
func sendIndex(row : Int){

switch row {

case 0:

let storyboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let moneySummaryVC: MoneySummaryVC = storyboard.instantiateViewControllerWithIdentifier("moneyVC") as! MoneySummaryVC
self.navigationController?.pushViewController(moneySummaryVC, animated: true)

default:
println("no index")

}

}


Related Topics



Leave a reply



Submit