Get to Uiviewcontroller from Uiview

Get to UIViewController from UIView?

Since this has been the accepted answer for a long time, I feel I need to rectify it with a better answer.

Some comments on the need:

  • Your view should not need to access the view controller directly.
  • The view should instead be independent of the view controller, and be able to work in different contexts.
  • Should you need the view to interface in a way with the view controller, the recommended way, and what Apple does across Cocoa is to use the delegate pattern.

An example of how to implement it follows:

@protocol MyViewDelegate < NSObject >

- (void)viewActionHappened;

@end

@interface MyView : UIView

@property (nonatomic, assign) MyViewDelegate delegate;

@end

@interface MyViewController < MyViewDelegate >

@end

The view interfaces with its delegate (as UITableView does, for instance) and it doesn't care if its implemented in the view controller or in any other class that you end up using.

My original answer follows: I don't recommend this, neither the rest of the answers where direct access to the view controller is achieved

There is no built-in way to do it. While you can get around it by adding a IBOutlet on the UIView and connecting these in Interface Builder, this is not recommended. The view should not know about the view controller. Instead, you should do as @Phil M suggests and create a protocol to be used as the delegate.

How to get a UIViewController from a UIView via code

You can use the -nextResponder method to do it. According to http://developer.apple.com/library/ios/documentation/uikit/reference/UIResponder_Class/Reference/Reference.html#//apple_ref/occ/instm/UIResponder/nextResponder , "UIView implements this method by returning the UIViewController object that manages it (if it has one) or its superview (if it doesn’t)"

Accessing a UIView from its UIViewController in Swift

the solution was -

 (self.view as! MyView'sName).myFunction

Embed UIViewController inside a UIView

As others said you can't embed a viewcontroller view inside a view.
What you can do is embed a ViewController inside another ViewController as a ChildViewController.

Try replacing your newView code with:

let storyboard = UIStoryboard(name: "Main", bundle: nil)
var controller: UIViewController = storyboard.instantiateViewController(withIdentifier: "testView") as UIViewController

//add as a childviewcontroller
addChildViewController(controller)

// Add the child's View as a subview
self.view.addSubview(controller.view)
controller.view.frame = view.bounds
controller.view.autoresizingMask = [.flexibleWidth, .flexibleHeight]

// tell the childviewcontroller it's contained in it's parent
controller.didMove(toParentViewController: self)

EDIT:
To change how and where the childviewcontroller appears, simply update its frame.
for example to make it half the height and anchored to the bottom:

controller.view.frame = CGRect(x: 0, y: view.center.y, width: view.size.width, height: view.size.height * 0.5) 

Given a view, how do I get its viewController?

Yes, the superview is the view that contains your view. Your view shouldn't know which exactly is its view controller, because that would break MVC principles.

The controller, on the other hand, knows which view it's responsible for (self.view = myView), and usually, this view delegates methods/events for handling to the controller.

Typically, instead of a pointer to your view, you should have a pointer to your controller, which in turn can either execute some controlling logic, or pass something to its view.

accessing UIView subclass in view controller

Posting my own answer.

  1. Create the XIB file.
  2. Create the UIView subclass Swift file.
  3. Under the XIB file owner's Identify Inspector custom class field, type in the UIView subclass name (your custom view).
  4. Under the XIB file owner's Connections Inspector, make sure all IBOutlets in the Swift file are connected.
  5. Add a view to the view controller and under its Identify Inspector custom class type, specify the custom class name.

Important:
* In your XIB swift file, you have to properly load the XIB content view.

...

/// Initializer used by Interface Builder.
required init?(coder: NSCoder) {
super.init(coder: coder)
configure()
}

/// Initializer used programmatically.
override init(frame: CGRect) {
super.init(frame: frame)
configure()
}

...

func configure() {
let contentView = // here use many of the functions available on the internet to
// load a view from a nib.
// Then add this view to the view hierarchy.
addSubview(contentView)
}

get the UIViewController from a UIView

You could hack something, but there is nothing that exists in the SDK, and for good reason.

I agree with Kurt, and will add that usually it's the view controller itself to which you want to maintain a reference, thereby maintaining a reference to its view. Code within a UIView subclass proper shouldn't concern itself whatsoever with whether it's owned by a VC, or for that matter is just a subview of another view; its responsibility is to maintaining its own house. Case in point, you write a view for the iPhone then later port to iPad. If it references an iPhone-specific VC, you must work to weed out all of that functionality when you include it in an iPad-type VC.

The idea is that UIKit is architected in layers of abstraction. One characteristic of the LoA paradigm is that layers should generally interact with other sibling layers, and those below. But it's generally not necessary (or possible) for a layer to look upwards to a more abstract concept. UIViewController and its variants are as abstract as classes get in UIKit. They are at the top of the food chain, as it were - no other classes consume their functionality. Requiring pointers to point only sideways or downwards also helps to prevent circular references.



Related Topics



Leave a reply



Submit