iPhone app reusing a view displays black screen - ios

So I'm trying to finish this iPhone app I started years ago. Anyway, I have an options menu, from which you can create a custom level (which goes to another view). Then when I return to the main menu, then the options menu, it just displays a black screen.
// shows options menu, works the first time
-(void) options : (id) sender{
[self.menuViewController.view removeFromSuperview];
[self.bg.view removeFromSuperview];
[self transition:self.view :navController.view];
}
// goes to custom built level
- (void) createCustom : (int) colorCount : (int) width : (int) height : (int) shuffles : (int) partners : (ToggleMode) toggleMode : (BOOL) colorblind{
self.gameViewController.isCustom = true;
self.gameViewController.width = width;
self.gameViewController.height = height;
self.gameViewController.shuffles = shuffles;
self.gameViewController.partners = partners;
self.gameViewController.toggleMode = toggleMode;
self.gameViewController.colorCount = colorCount;
srandom(arc4random());
[self.navController setNavigationBarHidden:true];
[self.gameViewController goToLevel];
[self transition:self.optionsMenu.customLevel.view : gameViewController.view];
}
- (void) transition : (UIView *) fromView : (UIView *) toView{
[UIView transitionFromView:fromView toView:toView duration:1.0 options:UIViewAnimationOptionTransitionFlipFromRight completion:NULL];
}
When I print out the objects involved, they all seem to still be there, so I have NO idea why it's just showing black. Please help me finish this app!

Why not display your options menu using a ModalViewController? It will display overtop your existing ViewController and will not dismiss/dealloc it. This will also remove the need to manually remove the views and view controller before transition, which is probably what is causing your black screen issue. You can add a button on this modal to dismiss it after the user has finished looking through the options.
Also as a general point on objective c, to make your life easier you should follow the correct format for naming methods. This involves putting the name of the parameter before each parameter in order to make calling the method much less confusing. As an example:
- (void)createCustom:(int)colorCount
:(int)width
:(int)height
:(int)shuffles
:(int)partners
:(ToggleMode)toggleMode
:(BOOL)colorblind {
}
Would turn into something like:
- (void)createCustomColorCount:(int)colorCount
withWidth:(int)width
withHeight:(int)height
withNumberOfShuffles:(int)shuffles
WithNumberOfPartners:(int)partners
withToggleMode:(ToggleMode)toggleMode
setColorBlind:(BOOL)colorblind {
}
To demonstrate why this is helpful, here is an example of how you would call your method:
[self createCustom:0
:100
:100
:5
:5
:nil
:NO];
versus:
[self createCustomColorCount:0
withWidth:100
withHeight:100
withNumberOfShuffles:5
WithNumberOfPartners:5
withToggleMode:nil
setColorBlind:NO];
As you can see with the second method it is much more clear what each parameter value corresponds to without having to go back to the implementation of the method.

Related

UISplitViewController pan to primary view from anywhere

Sorry for the long-winded explination, but this question - or something similar - has been asked a few times and I havent found a satisfactory answer. I am writing an iPad app in iOS 8 that implements UISplitViewController. Recently I have been attempting to get it to work on the iPhone. It transferred over pretty well, everything collapses automatically and a back button is included in the left side of my nav. bar.
My problem is that I want to keep the back button functionality to pop one view off the stack, but also be able to pan back to the primary view even if there are several detail views on top of it. Ideally, I want to be able to overwrite or redirect the interactivePopGestureRecognizer so that the gesture smoothly pans to the primary view (in some cases it can have anywhere from 1 to 4 detail views stacked on top of it). But, I cannot figure out how to do this.
My current solution (code below) is to disable the interactivePopGestureRecognizer in the detail viewcontroller and implement my own ScreenEdgePanGestureRecognizer that, when triggered, executes popToRootViewController. I've subclassed the ScreenEdgePanGestureRecognizer so it treats the screen edge pan as a discrete "swipe" (i.e. once a large enough screen edge swipe is detected - pop everything off the stack so the primary view is visible).
Code in detail view controller to stop interactivePopGestureRecognizer:
-(void)viewWillAppear : (BOOL) animated {
[super viewWillAppear : animated];
// stops navigation controller from responding to the default back swipe gesture
if ([self.navigationController respondsToSelector:#selector(interactivePopGestureRecognizer)]) {
self.navigationController.interactivePopGestureRecognizer.enabled =NO;
self.navigationController.interactivePopGestureRecognizer.delegate = self;
}
}
// Disable the default back swipe gesture tied to automatically included back button
-(BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
if ([gestureRecognizer isEqual:self.navigationController.interactivePopGestureRecognizer]) {
return NO;
} else {
return YES;
}
}
I didn't think it was necessary to include my subclass for the screenEdgePanGestureRecognizer because it has nothing to do with the solution I am asking about here is some pseudocode that shows what my #selector does in the detail viewcontroller:
- (IBAction)leftEdgeSwipe:(ScreenEdgeSwipeGestureRecognizer*)sender {
if (sender.swipeIsValid) {
[(UINavigationController *)self.splitViewController.viewControllers[0]
popToRootViewControllerAnimated:YES];
}
}
I tried to use the continuous pan, but cannot find a way to present the primary view in the background as I am pulling the current view aside to give that clean, smooth panning effect. I am able to make it so I can move the current view around, but there is just a grey background behind it where I would want my primary view to be.
Summation: If there is indeed no way to change the interactivePopGestureRecognizer to always jump to my primary view (ideal solution), then any info on how I can make my own smooth pan back to my primary view would be much appreciated.
So I have been messing around with making a smooth panning gesture subclass. Currently it functions similarly to Apple's back gesture except it jumps all the way back to the root view controller instead of popping one view off the stack. The only problem is that it does not yet show the primary view in the background while panning. I will update the answer once I get that worked out.
Here is the subclass:
#import <UIKit/UIKit.h>
#import <UIKit/UIGestureRecognizerSubclass.h>
#import "ScreenEdgeSwipeGestureRecognizer.h"
#interface ScreenEdgeSwipeGestureRecognizer ()
#property (nonatomic) UINavigationController* navController;
#end
#implementation ScreenEdgeSwipeGestureRecognizer{
CGPoint _screenCenter;
CGPoint _cumulativePanDistance;
}
- (id)initWithNavigationController:(UINavigationController*)navController {
self = [super initWithTarget:self action:#selector(leftEdgePan:)];
_screenCenter = CGPointZero;
_cumulativePanDistance = CGPointZero;
self.edges = UIRectEdgeLeft;
self.navController = navController;
return self;
}
- (IBAction)leftEdgePan:(ScreenEdgeSwipeGestureRecognizer*)sender {
assert(sender == self);
switch (self.state) {
case UIGestureRecognizerStateBegan:
[self initializePositions];
break;
case UIGestureRecognizerStateChanged:
[self updatePositions];
break;
case UIGestureRecognizerStateEnded:
[self animateViewBasedOnCurrentLocation];
break;
case UIGestureRecognizerStateCancelled:
[self animateViewToCenter];
break;
default:
break;
}
// Reset velocity of the pan so current velocity does not compound with velocity of next cycle
[sender setTranslation:CGPointMake(0, 0) inView:sender.view];
}
- (void)initializePositions {
_screenCenter = self.view.center;
_cumulativePanDistance = CGPointZero;
}
- (void)updatePositions {
// Track position of user touch event
CGPoint deltaSinceLastCycle = [self translationInView:self.view];
// View center = view center at last cycle + distance moved by user touch since last cycle
self.view.center=CGPointMake((self.view.center.x + deltaSinceLastCycle.x), self.view.center.y+ 0);
// Update the total positive distance traveled by the user touch event.
_cumulativePanDistance.x = _cumulativePanDistance.x + deltaSinceLastCycle.x;
}
- (void)animateViewBasedOnCurrentLocation {
if (_cumulativePanDistance.x >= (_screenCenter.x - 50)){
[self reset];
[_navController popToRootViewControllerAnimated:YES];
}else{
[self animateViewToCenter];
[self reset];
}
}
- (void)animateViewToCenter {
[UIView animateWithDuration:0.25 animations:^{self.view.center = self->_screenCenter;}];
}
- (void)reset {
[super reset];
_cumulativePanDistance = CGPointZero;
self.state = UIGestureRecognizerStatePossible;
}
#end
Here is how I instantiate the recognizer in my view controller:
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
// Initialize the screen edge pan gesture recognizer.
_masterNavigationController = self.splitViewController.viewControllers[0];
ScreenEdgePanGestureRecognizer* edgePanRecognizer = [[ScreenEdgeSwipeGestureRecognizer alloc] initWithNavigationController:_masterNavigationController];
// Add recognizer to view this controller is bound to.
[self.view addGestureRecognizer:_edgePanRecognizer];
}

Move UINavigationController's toolbar to the top to lie underneath navigation bar

When you create a UINavigationController, you can reveal its default hidden UIToolbar via setToolbarHidden:animated: (or by checking Shows Toolbar in Interface Builder). This causes a toolbar to appear at the bottom of the screen, and this toolbar persists between pushing and popping of view controllers on the navigation stack. That is exactly what I need, except I need the toolbar to be located at the top of the screen. It appears that's exactly what Apple has done with the iTunes app:
How can one move UINavigationController's toolbar to the top to lie underneath the navigation bar instead of at the bottom?
I've tried to implement the UIToolbarDelegate, override positionForBar:, and return UIBarPosition.TopAttached or UIBarPosition.Top after setting the delegate of self.navigationController?.toolbar to self, but this did not even call the delegate method therefore it didn't change the bar position.
Note that I need the toolbar to be preserved between navigation, so I can't simply add a toolbar to a view controller and position it under the nav bar.
The solution for this problem is a two (and a half) step process:
First you have to add an observer to the toolbars 'center' member.
Second, inside your observeValueForKeyPath:ofObject:change:context:, relocate the toolbar to your target position every time it is moved by somebody (e.g. the navigation controller itself for example, when the device rotates).
I did this in my UINavigationController subclass.
To avoid recursion, I've installed an local flag member 'inToolbarFrameChange'.
The last (half) step was a bit tricky to find out... you've to access the toolbars 'frame' member, to get the observer to be called at all... I guess, the reason for this might be, that 'frame' is implemented as an method inside UIToolbar and the base 'frame' value in UIView is only updated when the UIToolbar method is called ?!?
I did implement this 'frame' access in my overloaded setToolbarHidden:animated: method, which does nothing but to forward the call and to access the toolbars 'frame' value.
#interface MMMasterNavigationController ()
#property (assign, nonatomic) BOOL inToolbarFrameChange;
#end
#implementation MMMasterNavigationController
/*
awakeFromNib
*/
- (void)awakeFromNib {
[super awakeFromNib];
// ... other inits
self.inToolbarFrameChange = NO;
}
/*
viewDidLoad
*/
- (void)viewDidLoad {
[super viewDidLoad];
// 'center' instead of 'frame' from: http://stackoverflow.com/a/17977278/2778898
[self.toolbar addObserver:self
forKeyPath:#"center"
options:NSKeyValueObservingOptionNew
context:0];
}
/*
observeValueForKeyPath:ofObject:change:context:
*/
- (void)observeValueForKeyPath:(NSString *)pKeyPath
ofObject:(id)pObject
change:(NSDictionary<NSString *,id> *)pChange
context:(void *)pContext {
if ([pKeyPath isEqualToString:#"center"]) {
if (!self.inToolbarFrameChange) {
//NSLog(#"%s (0): %#", __PRETTY_FUNCTION__, pChange);
self.inToolbarFrameChange = YES;
CGRect tbFrame = self.toolbar.frame;
// maybe some other values are needed here for you
tbFrame = CGRectMake(0, 0, CGRectGetWidth(tbFrame), CGRectGetHeight(tbFrame));
self.toolbar.frame = tbFrame;
self.inToolbarFrameChange = NO;
}
} else {
[super observeValueForKeyPath:pKeyPath ofObject:pObject change:pChange context:pContext];
}
}
/*
setToolbarHidden:animated:
*/
- (void)setToolbarHidden:(BOOL)pHidden
animated:(BOOL)pAnimated {
FLog;
[super setToolbarHidden:pHidden animated:NO];
// Access the 'frame' member to let to observer fire
CGRect rectTB = self.toolbar.frame;
rectTB = CGRectZero;
}
You may create not UITableViewController but UIViewController. In view of UIViewController place UIToolBar below NavigationBar and UITableView. Delegate all necessary list of UITableView to UIViewController and thats all.
Why should you use UIViewController instead UITableViewController? Because tableView will not have statical positions elements. You should have something that not contains ScrollView. In this situation it is only UIView. Also you may do some hack with UIScrollView of tableView but I think described method is easer.

Drag and drop from Collectionview into ContactViewController doesn't work on iPad

I'm developing an app which uses splitView.
I'm using two items in splitView (Called them Customer and Supplier).
When I click on one of them I just use one viewController to display (called it: ContactViewController) and I use collectionView to display its data. To get data I just code it:
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
if (!dbManager.synchronized) {
if (contactType == ContactTypeCustomer)
[dbManager requestData:kDbCustomers predicate:nil target:self];
else if (contactType == ContactTypeSuppplier)
[dbManager requestData:kDbSuppliers predicate:nil target:self];
}
}
And when get successful:
#pragma mark
#pragma DBDelegate
- (void)requestDataCompleted:(NSMutableArray *)results
{
datasource = results;
[self.collectionView reloadData];
}
I use I3DragBetweenHelper downloaded from github.com
Embedded into my app to initial drag and drop. To do this, I call the below method into viewDidLoad of ContactViewController
- (void) initDragAndDrop
{
self.helper = [[I3DragBetweenHelper alloc] initWithSuperview:self.view
srcView:_collectionView
dstView:_collectionView];
self.helper.delegate = self;
self.helper.isDstRearrangeable = NO;
self.helper.isSrcRearrangeable = NO;
self.helper.doesSrcRecieveDst = NO;
self.helper.doesDstRecieveSrc = YES;
self.helper.hideDstDraggingCell = YES;
self.helper.hideSrcDraggingCell = NO;
}
The helper here is:
#property (strong, nonatomic) I3DragBetweenHelper *helper;
The problem is when I click on Supplier I can drag and drop the cell of collectionView into ContactViewController. Below method had called and worked:
- (BOOL)droppedOutsideAtPoint:(CGPoint)pointIn fromDstIndexPath:(NSIndexPath *)from
But when I click on Customer the above method doesn't call. I can't even drag my cell of collectionView into ContactViewController. Any help will appreciate.
Why is isDstRearrangeable set to NO ??? coz eventually you would grab something and drop it onto something ( dest ) and that something ( dest ) will be rearranged, am i wrong ??
does your drag and drop happen in the same place ?? ( i.e: UICollectionView )
if it does, then why do you have src as not rearrangeable ??? both your destination and src should be rearrangeable.
Try this and let me know how it goes :)
I dont know about this library but I think the problem is your srcView and dstView are the same. These should be different and must be either UITableView or UICollectionView.
If you are using UISplitViewController, its probably going to be the Master and Detail View Controllers used by the UISplitView

How to reload a UISplitViewController object when settings have changed?

I've looked at the Apple appPrefs code sample, but that seems to be for navigation controllers only. I'm working with an iPad UISplitViewController that has simple root and detail VCs.
I can change certain settings (colors, date formats, etc) but currently, I have to restart the app to have the changes effected. I would prefer not to have to restart the app.
I'm using a system of loading the settings when the app starts each time. I can get a notification system to work, but I don't know how to reload the view controllers.
Any ideas how to do this (I guess reload the views somehow).
Thanks for any tips/advice. I can post some code if relevant.
If you use settings bundle to manage preferences from the Settings app:
From what you said in your question, you already know how to get a notification(UIApplicationDidBecomeActiveNotification) when your app becomes active, right?
If so, the only problem left is how to reload your view after you receive the notification. Other than UITableView, which can be easily reloaded by calling [tableView reloadData], you have to reload your view by assigning values to the UI controls that you want to reload just as you set them up initially. Say you have a UILabel label you want to reload with the newly set preference value, you just write code like this:
- (void)reloadView {
label.text = [[NSUserDefaults standardUserDefaults] stringForKey:#"PreferenceKey"];
self.view.background = …
[self.tableView reloadData];
}
- (void)reloadViewOnAppActivation:(NSNotification *)notif {
[self reloadView];
}
If you are using in app preferences setting:
If the preferences view controller does not display simultaneously with the SplitViewController. Reload your views in their controllers' viewWillAppear: methods:
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self reloadView]; // See the definition of reloadView above
}
Otherwise, make the SplitViewController the delegate of, or assign it to an ivar of, the preferences view controller, and notify it of the preferences changes when appropriate — immediately after changing any single preference if you prefer in realtime update, or after all the changes are done if you prefer batch update:
// SplitViewController methods:
- (void)preferencesAreChanged {
[self reloadView]; // See the definition of reloadView above
}
// Preferences view controller methods:
// Immediate update, use a preference controlled by a `UISegmentedControl` as an example
- (void)viewDidLoad {
[super viewDidLoad];
…
[segmentedControl addTarget:self action:#selector(xPreferenceTogglingAction:) forControlEvents:UIControlEventValueChanged];
…
}
- (IBAction)xPreferenceTogglingAction:(id)sender {
// Update the x preference.
…
[delegate preferencesAreChanged];
}
// Batch update
- (void)viewWillDisappear:(BOOL)animated {
[delegate preferencesAreChanged];
[super viewWillDisappear:animated];
}
So, to help others, I will post how I (with help from Apple) solved this.
In both root and detail view controllers, I added in styles based on user settings:
"Warm Tones", "Cool Tones", "Leather" etc. These translate to code like this:
switch (styleKey) {
case 0: // BASIC
fontName = #"Copperplate";
fontSize = 16;
selectedBarColor = [UIColor lightGrayColor];
selectedTintColor = [UIColor lightGrayColor];
selectedFontColor = [UIColor darkGrayColor];
backgroundColor = [UIColor whiteColor];
selectedHighlightColor = UITableViewCellSelectionStyleGray;
backgroundImage = nil;
detailBackgroundImage = nil;
break;
Then, whenever a color/style/font is called, I used something like this:
cell.selectionStyle = selectedHighlightColor;
cell.backgroundColor = backgroundColor;
This allowed me to change the settings and styles, but I still had to restart the app each time to see the changes.
The fix turned out to be simple.
Settings the styles changed the values of the constants (e.g. fontColor) - but I wasn't actually changing the fields.
So at the end of the switch statements, all I added was something like this:
self.tableView.backgroundColor = backgroundColor;
self.navigationController.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:backgroundImage]];
self.navigationController.navigationBar.tintColor = selectedBarColor;
self.tableView.separatorColor = selectedTintColor;
I had to do this in both view controllers.
Also, all this code was part of a routine (changeSettings).
This method is being observed to look for changes.
The way I handled the in-app preference look and feel (a modal VC) was to use the terrific InAppSettingsKit.
I hope this helps others. Most of you will find this a no-brainer I expect, but - having not much brain left - it took me two weeks to figure it out.

UISearchDisplayController Without Dimming?

I am writing a SplitView iPad app. Inside the DetailViewController, there's a little view that contains a UITableView and a UISearchBar and its controller. This view does not represent the whole screen space reserved for the DetailViewController. Actually, it uses just half of it. There's an UIImageView on the other half.
And this is where trouble comes in: every time I use the search bar, the displaycontroller (I assume) dims everything present inside the DetailViewController, including the image view. That is not consistent with what someone would expect when running the app. Is there any way to set the frame to be dimmed? Or at least disable dimming for good?
Thanks in advance.
You are correct that it is the UISearchDisplayController that is managing the "dimming" effect that you're seeing.
What the UISearchDisplayController is doing is adding a UIControl as a subview to the view of the searchContentsController (a property of UISearchDisplayController), which is likely your detail-view controller. This UIControl is just an alpha'd view with a gray background. It seems to have a touch-up-inside event handler that ends searching when tapped.
To constrain the dimming effect to your sub-view of the detail-view, you need to do three things. (I'm assuming your detail-view-controller is defined via a xib. If not, these steps can be done in code too.)
1) add a new UIViewController to your detail-view-controller xib. Attach this new view-controller to an IBOutlet of your detail-view-controller. In my example I call this "_searchAreaViewController". This is important, even if you wont ever access the view controller (but remember, you'll have to release it at some point)
#interface DetailViewController : UIViewController <UIPopoverControllerDelegate, UISplitViewControllerDelegate, UITableViewDelegate, UITableViewDataSource> {
UIPopoverController *popoverController;
UIToolbar *toolbar;
id detailItem;
UILabel *detailDescriptionLabel;
IBOutlet UIViewController* _searchAreaViewController;
}
2) make the containing view for your search area the view of this new view-controller. To do this, use Interface Builder to set a new referencing outlet for this view by dragging the outlet to the searchAreaViewController and selecting the "view" outlet. You must have a containing view - it should be a subview of your detail-view, and it should contain the UISearchBar and likely your UITableView.
3) make the searchContentsController property of the UISearchDisplayController refer to this new view controller instead of the detail-view-controller. This can only be done via Interface Builder as the property is read-only (IB has some magic to make this work?) If you need to do this step via code you'll have to subclass the UISearchDisplayController and return the correct value from a property override of "searchContentsController".
I made a sample app to demonstrate this and the only line of code I had to add to the SplitView template was the one listed in step 1 above. Everything else was just adding the views/controllers and connecting them properly in IB.
good luck!
iOS 8+
[[UIView appearanceWhenContainedInInstancesOfClasses:#[NSClassFromString(#"UISearchDisplayControllerContainerView")]] setHidden:YES];
iOS 7
[View appearanceWhenContainedIn:NSClassFromString(#"UISearchDisplayControllerContainerView"), nil] setHidden:YES];
I know, that UISearchDisplayController is deprecated for now, but if you still need to use it, you can solve your issue with one line of code perfectly. Add it to viewDidLoad method.
Could you clarify what you mean by "use the search bar" and "dims everything present"? I interpret what you wrote in such a way that the keyboard pops up when you are about to enter text in the text field of the search bar. And that at this point the detail view is dimmed out, preventing user interaction.
The cause is that the search bar implements a modal dialog which prevents user interaction with the view as long as the keyboard is shown. Unfortunately, there doesn't seem to be any way to configure the search bar to prevent this behavior. On the other hand I am not sure that the user won't expect this behavior since search bars are modal consistently and behave like this in general under iOS.
I have tried two work-arounds:
1.) There is a property of the UIViewController called modalPresentationStyle which produces exactly the behavior you describe if it has the value UIModalPresentationFormSheet ("All uncovered areas are dimmed to prevent the user from interacting with them.", see the Apple documentation). But setting this property to a different values does not change the result (at least for me it didn't work).
2.) You would need to write your own non-modal search bar replacement since a standard UITextField is non-modal and thus does not dim out any other UI elements. This approach works, but you might need a little more work to make it look like a "regular" search bar. But, again, since this search bar behaves differently from the modal normal search bars in iOS this might not really be what the users expect.
I know I am late and this is a horrible idea here, but 'setHidden:No' did not work for me.
-(void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
BOOL hasBeenremoved = NO;
hasBeenremoved = [[[[NSThread mainThread] threadDictionary] objectForKey:#"hasBeenremoved"] boolValue];
if (hasBeenremoved)
{
UIView* dimmingView = nil;
dimmingView = [[[NSThread mainThread] threadDictionary] objectForKey:#"dimmingView"];
UIView* dimmingViewSuperView = nil;
dimmingViewSuperView = [[[NSThread mainThread] threadDictionary] objectForKey:#"dimmingViewSuperView"];
[dimmingViewSuperView addSubview:dimmingView];
[[[NSThread mainThread] threadDictionary] setObject:#NO forKey:#"hasBeenremoved"];
}
if ([searchText length] == 0 || [searchText isEqualToString:#""] )
{
[searchBar becomeFirstResponder];
[[[self primarySearchDisplayController] searchResultsTableView] reloadData];
[[[self primarySearchDisplayController] searchResultsTableView] setHidden:NO];
for( UIView *subview in self.view.subviews )
{
if([subview isMemberOfClass:[UIControl class]] ||
([[[subview class] description] isEqualToString:#"UISearchDisplayControllerContainerView"]))
{
for(UIView *subView2 in subview.subviews)
{
for(UIView *subView3 in subView2.subviews)
{
if (subView3.alpha < 1)
{
if ([[[subView3 class] description] isEqualToString:#"_UISearchDisplayControllerDimmingView"])
{
[[[NSThread mainThread] threadDictionary] setObject:subView3 forKey:#"dimmingView"];
[[[NSThread mainThread] threadDictionary] setObject:subView3.superview forKey:#"dimmingViewSuperView"];
[[[NSThread mainThread] threadDictionary] setObject:#YES forKey:#"hasBeenremoved"];
[subView3 removeFromSuperview];
}
}
}
}
}
}
}
}

Resources