190

Is there a built-in way to get from a UIView to its UIViewController? I know you can get from UIViewController to its UIView via [self view] but I was wondering if there is a reverse reference?

vikingosegundo
  • 51,126
  • 14
  • 131
  • 172
bertrandom
  • 2,031
  • 2
  • 13
  • 8

29 Answers29

203

Using the example posted by Brock, I modified it so that it is a category of UIView instead UIViewController and made it recursive so that any subview can (hopefully) find the parent UIViewController.

@interface UIView (FindUIViewController)
- (UIViewController *) firstAvailableUIViewController;
- (id) traverseResponderChainForUIViewController;
@end

@implementation UIView (FindUIViewController)
- (UIViewController *) firstAvailableUIViewController {
    // convenience function for casting and to "mask" the recursive function
    return (UIViewController *)[self traverseResponderChainForUIViewController];
}

- (id) traverseResponderChainForUIViewController {
    id nextResponder = [self nextResponder];
    if ([nextResponder isKindOfClass:[UIViewController class]]) {
        return nextResponder;
    } else if ([nextResponder isKindOfClass:[UIView class]]) {
        return [nextResponder traverseResponderChainForUIViewController];
    } else {
        return nil;
    }
}
@end

To use this code, add it into an new class file (I named mine "UIKitCategories") and remove the class data... copy the @interface into the header, and the @implementation into the .m file. Then in your project, #import "UIKitCategories.h" and use within the UIView code:

// from a UIView subclass... returns nil if UIViewController not available
UIViewController * myController = [self firstAvailableUIViewController];
Crashalot
  • 31,452
  • 56
  • 235
  • 393
Phil M
  • 2,063
  • 2
  • 12
  • 5
  • 48
    And one reason you need to allow the UIView to be aware of its UIViewController is when you have custom UIView subclasses that need to push a modal view/dialog. – Phil M Sep 17 '10 at 05:32
  • Awesome , I had to access my ViewController to display a custom popup which is created by a subview – aryaxt Aug 12 '11 at 06:00
  • 2
    Isn't this bad practice for a UIView to push a modal view? I'm doing this right now but I feel it's not the right thing to do.. – Van Du Tran Nov 26 '12 at 20:05
  • What a shame this is not picked as the best answer. – aryaxt Jul 28 '13 at 21:55
  • 6
    Phil, your custom view should call a delegate method which the view controller listens to and then it pushes from there. – malhal Nov 12 '13 at 20:20
  • `-traverseResponderChainForUIViewController`'s return type should just be UIViewController; you don't need the other method. `-firstAvailableUIViewController` is probably a better name. And it will break for things which override `-nextResponder`, but I'm not actually aware of any... – tc. Apr 05 '14 at 03:09
  • 12
    i just love how many SO questions has got a "wise man", academic, accepted answer with just a few points and a second answer which is practical, dirty and against the rules, with ten times the points :-) – hariseldon78 Jun 05 '15 at 22:41
116

UIView is a subclass of UIResponder. UIResponder lays out the method -nextResponder with an implementation that returns nil. UIView overrides this method, as documented in UIResponder (for some reason instead of in UIView) as follows: if the view has a view controller, it is returned by -nextResponder. If there is no view controller, the method will return the superview.

Add this to your project and you're ready to roll.

@interface UIView (APIFix)
- (UIViewController *)viewController;
@end

@implementation UIView (APIFix)

- (UIViewController *)viewController {
    if ([self.nextResponder isKindOfClass:UIViewController.class])
        return (UIViewController *)self.nextResponder;
    else
        return nil;
}
@end

Now UIView has a working method for returning the view controller.

memmons
  • 39,202
  • 21
  • 146
  • 181
Brock
  • 1,169
  • 1
  • 7
  • 3
  • 5
    This will only work if there is nothing in the responder chain between the receiving `UIView` and the `UIViewController`. Phil M's answer featuring recursion is the way to go. – Olivier Dec 16 '15 at 22:59
45

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.

pgb
  • 24,163
  • 11
  • 81
  • 113
  • 26
    That's very bad advice. You shouldn't reference a view controller from a view – Philippe Leybaert Oct 05 '10 at 19:23
  • @Philippe Leybaert: Wouldn't setting property to "assign" resolve the circular reference and resolve the problems with this approach? – Ivan Vučica Feb 25 '11 at 13:14
  • @Philippe Leybaert, so are you saying Apple's very own BubbleLevel Xcode example app is bad? [`LevelView`](http://bit.ly/jh3gME) has an assign property to its `viewController`. – ma11hew28 Jun 20 '11 at 18:46
  • 6
    @MattDiPasquale: yes, it's bad design. – Philippe Leybaert Jun 21 '11 at 17:50
  • 23
    @Phillipe Leybaert I'm curious to know your thoughts on the best design for a button click event which should invoke some action on the controller, without the view holding a reference to the controller. Thanks – Jonathon Horsman Aug 22 '11 at 16:05
  • I have a view that is made from a viewcontroller that is used as a subview in a table. For efficiency, the view can be recycled, but I would need to update the represented object. In this case would it make sense for the view to be able to pull in the original controller? – tofutim Feb 26 '14 at 21:55
  • It's a big smell... Is your view a `UITableViewCell` subclass? How is it reused? I'm guessing the view controller is responsible for reusing it, and thus might be able to update the represented object at the same time. – pgb Feb 27 '14 at 16:02
  • 3
    @PhilippeLeybaert Apple's example projects tend to demonstrate usage of particular API features. Many I have referred to sacrifice good or scalable design in order to provide a concise demonstration of the topic. It took me a long time to realise this and while it makes sense, I find it unfortunate. I think a lot of developers take these pragmatic projects as Apple's guide to best design practice, which I am quite certain they are not. – Benjohn Jun 03 '14 at 10:27
  • 1
    While I agree that the view should not know about its controller in normal situations, I think it can still be useful when in LLDB, in the same manner as in normal situations the view should not care about its grandchildren, yet there still exists the `recursiveDescription` private method. – Victor Jalencas Feb 02 '15 at 12:00
  • 1
    Agreed. Regardless of whether it's bad form, it can be useful to know how to do this in debugging situations. Also, OP didn't ask if it was a good idea or not. – Cruinh May 07 '15 at 19:42
  • Obtaining a reference to the view controller appears to be the only way to get to the top or bottom layout guide. Even Apple's documentation for the "topLayoutGuide" property of UIViewController suggests doing this. I tried to include the relevant code snippet but I couldn't get the formatting right. – Greg Brown Jul 08 '15 at 16:56
  • @GregBrown assuming the `MyView` delegate will be the View Controller, I don't see why you can't add a method to `MyViewDelegate` to get the `topLayoutGuide` and have the delegate return that. Interesting point, anyway, that this is suggested on Apple Docs. – pgb Jul 08 '15 at 20:53
  • 14
    All this bs about "you shouldn't do this" is just that. If a view wants to know about its view controller, that is up to the programmer to decide. period. – Daniel Kanaan Dec 07 '15 at 23:42
  • 1
    Phil M does not seem to have created any protocol in his current answer. He wrote a category to the `UIView` class. – Franklin Yu Feb 13 '16 at 17:46
  • Just upvote the needed comment, not including the third one. – Itachi Oct 30 '17 at 03:03
  • Folks, how can you go without reference to vc in nested CollectionViewCell ? Like in TVC->TableView->TableViewCell->CollectionView->CollectionViewCell->Button that should launch a segue of the TVC? – Nick Dec 16 '19 at 17:27
34

I would suggest a more lightweight approach for traversing the complete responder chain without having to add a category on UIView:

@implementation MyUIViewSubclass

- (UIViewController *)viewController {
    UIResponder *responder = self;
    while (![responder isKindOfClass:[UIViewController class]]) {
        responder = [responder nextResponder];
        if (nil == responder) {
            break;
        }
    }
    return (UIViewController *)responder;
}

@end
de.
  • 3,391
  • 1
  • 27
  • 45
22

Combining several already given answers, I'm shipping on it as well with my implementation:

@implementation UIView (AppNameAdditions)

- (UIViewController *)appName_viewController {
    /// Finds the view's view controller.

    // Take the view controller class object here and avoid sending the same message iteratively unnecessarily.
    Class vcc = [UIViewController class];

    // Traverse responder chain. Return first found view controller, which will be the view's view controller.
    UIResponder *responder = self;
    while ((responder = [responder nextResponder]))
        if ([responder isKindOfClass: vcc])
            return (UIViewController *)responder;

    // If the view controller isn't found, return nil.
    return nil;
}

@end

The category is part of my ARC-enabled static library that I ship on every application I create. It's been tested several times and I didn't find any problems or leaks.

P.S.: You don't need to use a category like I did if the concerned view is a subclass of yours. In the latter case, just put the method in your subclass and you're good to go.

Constantino Tsarouhas
  • 6,736
  • 6
  • 43
  • 54
13

I modified de answer so I can pass any view, button, label etc. to get it's parent UIViewController. Here is my code.

+(UIViewController *)viewController:(id)view {
    UIResponder *responder = view;
    while (![responder isKindOfClass:[UIViewController class]]) {
        responder = [responder nextResponder];
        if (nil == responder) {
            break;
        }
    }
    return (UIViewController *)responder;
}

Edit Swift 3 Version

class func viewController(_ view: UIView) -> UIViewController {
        var responder: UIResponder? = view
        while !(responder is UIViewController) {
            responder = responder?.next
            if nil == responder {
                break
            }
        }
        return (responder as? UIViewController)!
    }

Edit 2:- Swift Extention

extension UIView
{
    //Get Parent View Controller from any view
    func parentViewController() -> UIViewController {
        var responder: UIResponder? = self
        while !(responder is UIViewController) {
            responder = responder?.next
            if nil == responder {
                break
            }
        }
        return (responder as? UIViewController)!
    }
}
Varun Naharia
  • 4,836
  • 7
  • 42
  • 73
12

Even though this can technically be solved as pgb recommends, IMHO, this is a design flaw. The view should not need to be aware of the controller.

Ushox
  • 758
  • 6
  • 13
  • I'm just not sure how the viewController can be told that one of its view's is going away and it needs to call one of its viewXXXAppear/viewXXXDisappear methods. – mahboudz Sep 03 '09 at 18:40
  • 2
    This is the idea behind the Observer pattern. The Observed (the View in this case) should not be aware of its Observers directly. The Observer should only receive the callbacks that they're interested in. – Ushox Sep 04 '09 at 09:32
7

Don't forget that you can get access to the root view controller for the window that the view is a subview of. From there, if you are e.g. using a navigation view controller and want to push a new view onto it:

    [[[[self window] rootViewController] navigationController] pushViewController:newController animated:YES];

You will need to set up the rootViewController property of the window properly first, however. Do this when you first create the controller e.g. in your app delegate:

-(void) applicationDidFinishLaunching:(UIApplication *)application {
    window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    RootViewController *controller = [[YourRootViewController] alloc] init];
    [window setRootViewController: controller];
    navigationController = [[UINavigationController alloc] initWithRootViewController:rootViewController];
    [controller release];
    [window addSubview:[[self navigationController] view]];
    [window makeKeyAndVisible];
}
Gabriel
  • 573
  • 6
  • 11
  • It seems to me that in accordance with [Apple docs](http://developer.apple.com/library/ios/documentation/UIKit/Reference/UIWindow_Class/UIWindowClassReference/UIWindowClassReference.html#//apple_ref/occ/instp/UIWindow/rootViewController) since `[[self navigationController] view]` is the "main" (sub)view of the window, the `rootViewController` property of the window has to be set to `navigationController` which controls the "main" view immediately. – adubr May 14 '11 at 18:03
6

I stumbled upon a situation where I have a small component I want to reuse, and added some code in a reusable view itself(it's really not much more than a button that opens a PopoverController).

While this works fine in the iPad (the UIPopoverController presents itself, therefor needs no reference to a UIViewController), getting the same code to work means suddenly referencing your presentViewController from your UIViewController. Kinda inconsistent right?

Like mentioned before, it's not the best approach to have logic in your UIView. But it felt really useless to wrap the few lines of code needed in a separate controller.

Either way, here's a swift solution, which adds a new property to any UIView:

extension UIView {

    var viewController: UIViewController? {

        var responder: UIResponder? = self

        while responder != nil {

            if let responder = responder as? UIViewController {
                return responder
            }
            responder = responder?.nextResponder()
        }
        return nil
    }
}
Kevin R
  • 6,952
  • 4
  • 35
  • 43
6

While these answers are technically correct, including Ushox, I think the approved way is to implement a new protocol or re-use an existing one. A protocol insulates the observer from the observed, sort of like putting a mail slot in between them. In effect, that is what Gabriel does via the pushViewController method invocation; the view "knows" that it is proper protocol to politely ask your navigationController to push a view, since the viewController conforms to the navigationController protocol. While you can create your own protocol, just using Gabriel's example and re-using the UINavigationController protocol is just fine.

PapaSmurf
  • 2,058
  • 18
  • 9
5

I don't think it's "bad" idea to find out who is the view controller for some cases. What could be a bad idea is to save the reference to this controller as it could change just as superviews change. In my case I have a getter that traverses the responder chain.

//.h

@property (nonatomic, readonly) UIViewController * viewController;

//.m

- (UIViewController *)viewController
{
    for (UIResponder * nextResponder = self.nextResponder;
         nextResponder;
         nextResponder = nextResponder.nextResponder)
    {
        if ([nextResponder isKindOfClass:[UIViewController class]])
            return (UIViewController *)nextResponder;
    }

    // Not found
    NSLog(@"%@ doesn't seem to have a viewController". self);
    return nil;
}
Rivera
  • 10,182
  • 3
  • 49
  • 96
4

The simplest do while loop for finding the viewController.

-(UIViewController*)viewController
{
    UIResponder *nextResponder =  self;

    do
    {
        nextResponder = [nextResponder nextResponder];

        if ([nextResponder isKindOfClass:[UIViewController class]])
            return (UIViewController*)nextResponder;

    } while (nextResponder != nil);

    return nil;
}
Mohd Iftekhar Qurashi
  • 2,353
  • 3
  • 29
  • 43
4

Swift 4

(more concise than the other answers)

fileprivate extension UIView {

  var firstViewController: UIViewController? {
    let firstViewController = sequence(first: self, next: { $0.next }).first(where: { $0 is UIViewController })
    return firstViewController as? UIViewController
  }

}

My use case for which I need to access the view first UIViewController: I have an object that wraps around AVPlayer / AVPlayerViewController and I want to provide a simple show(in view: UIView) method that will embed AVPlayerViewController into view. For that, I need to access view's UIViewController.

frouo
  • 3,886
  • 1
  • 22
  • 26
3

This doesn't answer the question directly, but rather makes an assumption about the intent of the question.

If you have a view and in that view you need to call a method on another object, like say the view controller, you can use the NSNotificationCenter instead.

First create your notification string in a header file

#define SLCopyStringNotification @"ShaoloCopyStringNotification"

In your view call postNotificationName:

- (IBAction) copyString:(id)sender
{
    [[NSNotificationCenter defaultCenter] postNotificationName:SLCopyStringNotification object:nil];
}

Then in your view controller you add an observer. I do this in viewDidLoad

- (void)viewDidLoad
{
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(copyString:)
                                                 name:SLCopyStringNotification
                                               object:nil];
}

Now (also in the same view controller) implement your method copyString: as depicted in the @selector above.

- (IBAction) copyString:(id)sender
{
    CalculatorResult* result = (CalculatorResult*)[[PercentCalculator sharedInstance].arrayTableDS objectAtIndex:([self.viewTableResults indexPathForSelectedRow].row)];
    UIPasteboard *gpBoard = [UIPasteboard generalPasteboard];
    [gpBoard setString:result.stringResult];
}

I'm not saying this is the right way to do this, it just seems cleaner than running up the first responder chain. I used this code to implement a UIMenuController on a UITableView and pass the event back up to the UIViewController so I can do something with the data.

Shaolo
  • 1,181
  • 10
  • 12
3

It's surely a bad idea and a wrong design, but I'm sure we can all enjoy a Swift solution of the best answer proposed by @Phil_M:

static func firstAvailableUIViewController(fromResponder responder: UIResponder) -> UIViewController? {
    func traverseResponderChainForUIViewController(responder: UIResponder) -> UIViewController? {
        if let nextResponder = responder.nextResponder() {
            if let nextResp = nextResponder as? UIViewController {
                return nextResp
            } else {
                return traverseResponderChainForUIViewController(nextResponder)
            }
        }
        return nil
    }

    return traverseResponderChainForUIViewController(responder)
}

If your intention is to do simple things, as showing a modal dialog or tracking data, that doesn't justify the use of a protocol. I personally store this function in an utility object, you can use it from anything that implement the UIResponder protocol as:

if let viewController = MyUtilityClass.firstAvailableUIViewController(self) {}

All credit to @Phil_M

Crashalot
  • 31,452
  • 56
  • 235
  • 393
Paul Slm
  • 223
  • 2
  • 9
3

Maybe I'm late here. But in this situation I don't like category (pollution). I love this way:

#define UIViewParentController(__view) ({ \
UIResponder *__responder = __view; \
while ([__responder isKindOfClass:[UIView class]]) \
__responder = [__responder nextResponder]; \
(UIViewController *)__responder; \
})
lee
  • 7,016
  • 8
  • 41
  • 56
3

Swift 4 version

extension UIView {
var parentViewController: UIViewController? {
    var parentResponder: UIResponder? = self
    while parentResponder != nil {
        parentResponder = parentResponder!.next
        if let viewController = parentResponder as? UIViewController {
            return viewController
        }
    }
    return nil
}

Usage example

 if let parent = self.view.parentViewController{

 }
Ryan Heitner
  • 11,746
  • 6
  • 65
  • 104
levin varghese
  • 660
  • 11
  • 12
3

Swiftier solution

extension UIView {
    var parentViewController: UIViewController? {
        for responder in sequence(first: self, next: { $0.next }) {
            if let viewController = responder as? UIViewController {
                return viewController
            }
        }
        return nil
    }
}
Igor Palaguta
  • 3,490
  • 2
  • 18
  • 31
  • I like this answer. I'm not sure it's more swifty though. Swift is yet-another-can't-decide-which-of-multiple-paradigms-it-wants-to-be-married-to languages. In this case, you have a nice demonstration of a more functional approach (the `sequence` bit). So if "swifty" means "more functional", then I guess it's more swifty. – Travis Griggs Oct 24 '18 at 22:41
2

Updated version for swift 4 : Thanks for @Phil_M and @paul-slm

static func firstAvailableUIViewController(fromResponder responder: UIResponder) -> UIViewController? {
    func traverseResponderChainForUIViewController(responder: UIResponder) -> UIViewController? {
        if let nextResponder = responder.next {
            if let nextResp = nextResponder as? UIViewController {
                return nextResp
            } else {
                return traverseResponderChainForUIViewController(responder: nextResponder)
            }
        }
        return nil
    }

    return traverseResponderChainForUIViewController(responder: responder)
}
dicle
  • 932
  • 1
  • 8
  • 35
2

Two solutions as of Swift 5.2:

  • More on the functional side
  • No need for the return keyword now

Solution 1:

extension UIView {
    var parentViewController: UIViewController? {
        sequence(first: self) { $0.next }
            .first(where: { $0 is UIViewController })
            .flatMap { $0 as? UIViewController }
    }
}

Solution 2:

extension UIView {
    var parentViewController: UIViewController? {
        sequence(first: self) { $0.next }
            .compactMap{ $0 as? UIViewController }
            .first
    }
}
  • This solution requires iterating through each responder first, so may not be the most performant.
jason z
  • 1,117
  • 10
  • 17
1

To Phil's answer:

In line: id nextResponder = [self nextResponder]; if self(UIView) is not a subview of ViewController's view, if you know hierarchy of self(UIView) you can use also: id nextResponder = [[self superview] nextResponder];...

sag
  • 159
  • 1
  • 6
0

Another easy way is to have your own view class and add a property of the view controller in the view class. Usually the view controller creates the view and that is where the controller can set itself to the property. Basically it is instead of searching around (with a bit of hacking) for the controller, having the controller to set itself to the view - this is simple but makes sense because it is the controller that "controls" the view.

jack
  • 671
  • 7
  • 8
0

My solution would probably be considered kind of bogus but I had a similar situation as mayoneez (I wanted to switch views in response to a gesture in an EAGLView), and I got the EAGL's view controller this way:

EAGLViewController *vc = ((EAGLAppDelegate*)[[UIApplication sharedApplication] delegate]).viewController;
gulchrider
  • 4,206
  • 3
  • 23
  • 15
  • 2
    Please rewrite your code as follows: `EAGLViewController *vc = [(EAGLAppDelegate *)[UIApplication sharedApplication].delegate viewController];`. – Jonathan Sterling Aug 21 '10 at 05:21
  • 1
    The problem is not with the dot syntax, but with types. In Objective C to declare an object you write `ClassName *object` - with an asterisk. – adubr May 14 '11 at 18:09
  • Oops... that's actually what I had, but the StackOverflow HTML widget thingy looks like it thought the asterisk meant italics... I changed it to a code block, now it displays correctly. Thanks! – gulchrider Aug 07 '11 at 19:44
0

If you aren't going to upload this to the App Store, you can also use a private method of UIView.

@interface UIView(Private)
- (UIViewController *)_viewControllerForAncestor;
@end

// Later in the code
UIViewController *vc = [myView _viewControllerForAncestor];
0

I think there is a case when the observed needs to inform the observer.

I see a similar problem where the UIView in a UIViewController is responding to a situation and it needs to first tell its parent view controller to hide the back button and then upon completion tell the parent view controller that it needs to pop itself off the stack.

I have been trying this with delegates with no success.

I don't understand why this should be a bad idea?

Brock Adams
  • 82,642
  • 19
  • 207
  • 268
user7865437
  • 804
  • 14
  • 28
0
var parentViewController: UIViewController? {
    let s = sequence(first: self) { $0.next }
    return s.compactMap { $0 as? UIViewController }.first
}
klaudas
  • 218
  • 3
  • 13
  • Although this code might answer the question, a good answer should also explain what the code does and how it solves the problem. – BDL Jan 23 '20 at 08:57
0

To get the controller of a given view, one can use UIFirstResponder chain.

customView.target(forAction: Selector("viewDidLoad"), withSender: nil)
Blazej SLEBODA
  • 6,503
  • 3
  • 35
  • 69
-1

If your rootViewController is UINavigationViewController, which was set up in AppDelegate class, then

    + (UIViewController *) getNearestViewController:(Class) c {
NSArray *arrVc = [[[[UIApplication sharedApplication] keyWindow] rootViewController] childViewControllers];

for (UIViewController *v in arrVc)
{
    if ([v isKindOfClass:c])
    {
        return v;
    }
}

return nil;}

Where c required view controllers class.

USAGE:

     RequiredViewController* rvc = [Utilities getNearestViewController:[RequiredViewController class]];
Ansari Awais
  • 289
  • 4
  • 14
-5

There is no way.

What I do is pass the UIViewController pointer to the UIView (or an appropriate inheritance). I'm sorry I can't help with the IB approach to the problem because I don't believe in IB.

To answer the first commenter: sometimes you do need to know who called you because it determines what you can do. For example with a database you might have read access only or read/write ...

John Smith
  • 11,467
  • 16
  • 59
  • 105
  • 10
    What does that mean - "I don't believe in IB" ? I've launched it, it certainly exists. – marcc Jan 02 '10 at 00:33
  • 5
    You need a better grasp of fun and abstraction, especially with regards to the English language. It means I don't like it. – John Smith Jan 04 '10 at 16:44
  • 4
    I don't like avocados. But I bet I can help someone make guacamole. It can be done in IB, so obviously your answer of "there is no way" is incorrect. Whether you like IB or not is irrelevant. – Feloneous Cat Jun 22 '12 at 17:01