Lag / Delay on ModalViewController dismiss after loading an xib view over SKView - objective-c

Imagine this scenario (some code below):
I have an SKView on a viewcontroller.
I load an xib view (external .xib file) over skview (xib view is a like small menu view that does not cover screen in full).
Then, I show a view controller modally from SKView's controller
When I dismiss this modal view controller, there is a lag on every second dismissal (so, i show it modally, dismiss, it is fine, then i repeat, there is delay, then repeat, works fine, then do again, there is delay ... and so on)
If I do not use SKView (if i just used UIView), that delay does not happen. It only happens when I use SKView.
What may be causing that? Here is simplified code that produces this problem:
#implementation NOZTestController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
// button that loads xib view onto the current skview
UIButton *showxib = [[UIButton alloc] initWithFrame:CGRectMake(20, 80, 280, 30)];
[showxib setTitle:#"Add xib view here" forState:UIControlStateNormal];
[showxib addTarget:self action:#selector(showxibTapped) forControlEvents:UIControlEventTouchUpInside];
// button that loads a view controller programmatically
UIButton *showmodal = [[UIButton alloc] initWithFrame:CGRectMake(20, 120, 280, 30)];
[showmodal setTitle:#"Show modal" forState:UIControlStateNormal];
[showmodal addTarget:self action:#selector(showmodalTapped) forControlEvents:UIControlEventTouchUpInside];
self.view = [[SKView alloc] initWithFrame:self.view.frame];
SKView *v = (SKView *)self.view;
//UIView *v = self.view;
[v addSubview:showxib];
[v addSubview:showmodal];
}
- (void)showxibTapped
{
// displays the xib view
[NOZPlayAgainView presentOnView:self.view inRect:CGRectMake(20, 200, 280, 160) withDelegate:self];
}
- (void)showmodalTapped
{
// displays the modal window
UIViewController *vc = [[UIViewController alloc] init];
UIButton *dismiss = [[UIButton alloc] initWithFrame:CGRectMake(40, 40, 240, 40)];
[dismiss setTitle:#"Dismiss" forState:UIControlStateNormal];
[dismiss addTarget:self action:#selector(dismissModal) forControlEvents:UIControlEventTouchUpInside];
[vc.view addSubview:dismiss];
[self presentViewController:vc animated:YES completion:nil];
}
- (void)dismissModal
{
[self.presentedViewController dismissViewControllerAnimated:YES completion:nil];
}
#end

It is caused by autolayout constraints on the xib view. To arrive to that conclusion, I created a simple view with a subview and added it to SKView. The problem I reported above happened only when I used auto layout constraints to place the subview. I don't know why this is happening but that is the reason for it.

Related

UIkit elements can't see in overlaySKScene for AR

I making some simple AR app with interfaces using overlaySKScene.
In viewDidLoad, I applied overlay scene in main ARSCNView(OverlayScene is my class inherited SKScene).
self.sceneView.overlaySKScene = [[OverlayScene alloc] initWithSize:self.sceneView.bounds.size];
self.sceneView.overlaySKScene.delegate = self;
Then, I added UIkit button in OverlayScene init.
UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 200, 100)];
[button setTitle:#"button" forState:UIControlStateNormal];
button.layer.position = CGPointMake(self.view.frame.size.width/2, 200);
[self.view addSubview:button];
But, that button didn't appear on screen.
When I added sprite node in this scene, it worked.
Is there other method for it or bug?
Thank you.
OverlayScene's init isn't really an appropriate place to do that, as self.view will equal nil because when a scene is initialize it has yet to be added to the view hierarchy. A better choice might be the SKScene lifecycle method - (void)didMoveToView:(SKView *)view; like:
- (void)didMoveToView:(SKView *)view {
[super didMoveToView:view];
UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 200, 100)];
[button setTitle:#"button" forState:UIControlStateNormal];
button.layer.position = CGPointMake(self.view.frame.size.width/2, 200);
[self.view addSubview:button];
}

View controller not taking up entire window frame in Mac OSX project

So I'm creating a mac OSX app and right now I have a main view controller set up to be the size of the window and a NSView subview on top of the view controller with the same frame size. However, this is the result I am getting: (I colored the NSView subview pinkish)
What I want is for the whole window to be taken up by the NSView subview (so the whole window should be pink). Here is my code thus far:
In AppDelegate.m:
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
// Insert code here to initialize your application
self.mainViewController = [[NSViewController alloc]
initWithNibName:Nil bundle:Nil];
self.mainViewController.view.frame = ((NSView *)self.window.contentView).bounds;
[self.window.contentView addSubview:self.mainViewController.view];
}
And then in my view controller:
-(void)loadView
{
[super loadView];
NSView *myView = [[NSView alloc] initWithFrame:self.view.frame];
CALayer *viewLayer = [CALayer layer];
[viewLayer setBackgroundColor:CGColorCreateGenericRGB(100.0, 0.0, 0.0, 0.4)];
[myView setWantsLayer:YES];
[myView setLayer:viewLayer];
[self.view addSubview:myView];
}
What am I doing wrong?
Instead of adding a subview to your view controller in your loadView: method, you should set the view of view controller here as:
-(void)loadView
{
.
.
.
// [self.view addSubview:myView]; //update this to
[self setView: myView];
}

Display default tabBarView on tabBarItem Click event

I have used UITabbarController in my app.One of the tabBarItem is contactsViewController which displays list of contacts with UITableView.When I click on the tableRow it loads another view.then I click some other tabBarItem.again I click contactsViewController it takes me to the view where i left.It does not display default contact view.I have created UITabbarController progrmattically.How do i display default tabBarView on tabBarItem click?
tabbarController = [[UITabBarController alloc]init];
self.tabbarController.delegate = self;
tabbarView = [[UIView alloc]initWithFrame:CGRectMake(0, 431, 320, 49)];
UIImageView *tabImage = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 320, 49)];
[tabImage setImage:[UIImage imageNamed:#"Taskbar.png"]];
[tabbarView addSubview:tabImage];
UIButton *tabItem1 = [[UIButton alloc]initWithFrame:CGRectMake(0, 0, 64, 49)];
[tabItem1 setImage:[UIImage imageNamed:#"Btn_Home.png"] forState:UIControlStateNormal];
[tabItem1 setTag:1];
[tabItem1 addTarget:self action:#selector(tabBarBtnAction:) forControlEvents:UIControlEventTouchUpInside];
[tabbarView addSubview:tabItem1];
-(IBAction)tabBarBtnAction:(id)sender
{
UIButton *btn = (UIButton *)sender;
// NSLog(#"tag %d\n",btn.tag);
[self resetTabBarBtnImage];
[self resetAllTabBarBtnImage];
PreviousBtnTag = btn.tag;
if ([btn tag]==1) {
tabbarView.hidden = YES;
[self.tabbarController setSelectedIndex:0];
[self.navigationController popToRootViewControllerAnimated:YES];
[btn setImage:[UIImage imageNamed:#"Btn_Home-Over.png"] forState:UIControlStateNormal];
}
else if([btn tag]==2)
{
tabbarView.hidden = NO;
[self.tabbarController setSelectedIndex:1];
[btn setImage:[UIImage imageNamed:#"Btn_Contacts-Over.png"] forState:UIControlStateNormal];
[self.navigationController popToRootViewControllerAnimated:YES];
}
In the appDelegate class , initially set the UItabbarController delegate as self
In the implememtation of appDelegate i.e .m file
//Assuming the first tab has the contactsviewController
-
(void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController {
if (tabBarController.selectedIndex == 0) {
UINavigationController *requiredNavigationController = [tabBarController.viewControllers objectAtIndex:0];
[requiredNavigationController popToRootViewControllerAnimated:YES];
}
}
I would recommend you to create the "tab bar controller" with the Interface Builder, as it is much easier to implement these kind of things this way. Anyway, if you want to keep trying to create it programmatically, try changing this:
[self.navigationController popToRootViewControllerAnimated:YES];
for this:
RootViewController *controller = [self.storyboard instantiateViewControllerWithIdentifier:#"Root"];
[self.navigationController pushViewController:controller animated:YES];
If this does not work for you, why don't you use Tool Bar Items, in instead of a Tab Bar Controller? It is quite easy to manage events with Tool Bar items, as they are treated like buttons.
Good luck!

UIButton does not fire target on touchUpInside unless I drag just outside?

I have a Button that when I press it, it does not fire the target selector that I've added. I've made the button Different Images, so I can see that I am Pressing it.
So here is the Funny if I Press, and drag outside of the button, but not outside of the button's immediate superView, the target selector is fired!
I've also in testing set the setClipsToBounds:YES on all the super/sub views just to be sure it was still in the views bounds. Seems to be within bounds. The dragging outside the button area seems to be omni directional, so its not like I can only tap/drag right. Left up and down work too. I can tap, drag out then back in and it works. If I don't start to drag and just tap and hold, the button highlights and then goes back to unselected state.
Here is the code for the Button. The Button is on a UIView along with a UITextView, Actually onTop Of the UITextView. The UIView that all of this is on is on a Larger View, which is on a Scaling/Scrolling view
messageLookupButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 21, 20)];
[messageLookupButton setTitle:#"junk" forState:UIControlStateNormal];
[messageLookupButton sizeToFit];
[messageLookupButton setTag:kGearButtonView];
//Get the images for the buttons
UIImage *gearButtonImage = [UIImage imageNamed:#"gear.png"];
UIImage *gearButtonImage2 = [UIImage imageNamed:#"StatusLightOn.png"];
[messageLookupButton setImage:gearButtonImage forState:UIControlStateNormal];
[messageLookupButton setImage:gearButtonImage2 forState:UIControlStateHighlighted];
[messageLookupButton addTarget:self action:#selector(gearPressed:) forControlEvents:UIControlEventTouchUpInside];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(processLookupResults:)
name:kRefreshFromPopover object:nil];
[self addSubview: messageLookupButton ];
[messageLookupButton release];
[messageLookupButton setCenter:CGPointMake(CGRectGetMaxX(elementViewContents.bounds) -kElementContentFrameOffset -(CGRectGetWidth( messageLookupButton.bounds)/2), CGRectGetMidY(elementViewContents.bounds))];
[self bringSubviewToFront:messageLookupButton];
The Scroll View has several gesture recognizers on it. Though they don't seem to interfere with other buttons and controls that I've put on the screen. Though I have a feeling its the Scroll View that is the problem.
scroll view code clip:
[scrollContentView setUserInteractionEnabled:YES];
[scrollContentView setExclusiveTouch:YES];
[scrollContentView setCanCancelContentTouches:YES];
[scrollContentView setDelaysContentTouches:YES];
I ended up Just adding the gear as an Image to the View, then created a invisible button that was the same size as the UIView that I placed the gear icon on.
-(void) addMessageLookupSelector {
// Set a default Color if there is none
if (_isMessageLookupField ){
// Add Gear to End Of Text Field
if (!messageLookupImageView) {
messageLookupImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 21, 20)];
[messageLookupImageView setTag:kGearButtonView];
[messageLookupImageView setImage:[UIImage imageNamed:#"gear.png"] ];
[self addSubview: messageLookupImageView ];
[messageLookupImageView release];
}
[self positionMessageLookupImageView ];
}
[self setNeedsDisplay];
}
- (void)makeControlEditable {
//Setup the TextField so we can edit its value, need to see if there is a Write Animation Assocated with Element
[self setTheWriteTag];
if (writeTag) {
writeInputRequestedButton = [UIButton buttonWithType:UIButtonTypeCustom];
[writeInputRequestedButton setFrame:elementViewContents.frame];
[writeInputRequestedButton setUserInteractionEnabled:YES];
[writeInputRequestedButton setEnabled:YES];
// [writeInputRequestedButton setBackgroundColor:[UIColor clearColor]];
[self addSubview: writeInputRequestedButton];
[self bringSubviewToFront:writeInputRequestedButton];
[writeInputRequestedButton addTarget:self action:#selector(wantsToEditValue:) forControlEvents:UIControlEventTouchUpInside];
}
}

Button not clickable after adding as a subview to a UIView

I have created a class called UICustomButton, which is a subclass of UIView. I added a UIButton to UIView as a subview as shown in my code below:
-(id)initWithButtonType:(NSString *)type
{
self = [super init];
if (self)
{
self.customButton = [self setupButtonWithTitle:type andFrame:frame];
[self addSubview:self.customButton];
self.customButton addTarget:self action:#selector(buttonPressed) forControlEvents:UIControlEventTouchUpInside];
}
return self;
}
The problem I am facing is that although the button appears, they are not clickable. Is there something wrong with the way I am adding the buttons to the UIView?
EDIT: To add on, I am using this custom button class instance to a cell:
UICustomButton *customButton = [[UICustomButton alloc]initWithFrame:someFrame];
[cell.contentView addSubView:customButton];
check the frame of your UICustomButton object, and if self.customButton is out of its superView.
Make sure that the frame of the subview is within the frame of its superview. I encountered the issue twice and both times the frame of the subview was incorrect.
You should check if all properties userInteractionEnabled are on:
Check that property for UITableView where your cells with this view are displayed
Check that property for UITableViewCell where you add this view as subview
Check that property for UICustomButton
Check that property for customButton in -(id)initWithButtonType:(NSString *)type
My button was not working because i had two views in each other. The first view, as you can see, has a width and heigth of 0 pixels. I've made this view the same size as view2 and then my button was clickable.
UIView *view1 = [[UIView alloc] initWithFrame:CGRectMake(325, 346, 0, 0)];
view1.alpha = 0.90;
UIView *view2 = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 450, 150)];
[view2.layer setCornerRadius:10.0f];
view2.backgroundColor = [UIColor whiteColor];
UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[btn addTarget:self action:#selector(addClosedToCollection) forControlEvents:UIControlEventTouchUpInside];
[btn setFrame:CGRectMake(30, 30, 300, 32)];
[btn setTitle:#"i'm a button" forState:UIControlStateNormal];
[view2 addSubview:btn];
[view1 addSubview:view2];
i hope i've helped somebody out :)
Your outer view probably has a height of 0. Add constraints that makes it the same height as (or higher than) the subviews, or create it with a frame that is large enough.
try putting this after the if statement:
self.isTouchEnabled = YES;