ios7 - how to transition back to self - ios7

as per the following storyboard, I have a RootViewController (embedded in a TabBarController), which manage many ViewControllers with a vertical menu.
When this RootViewController did load, I check for client authentication, and if not yet authenticated, I switch to a ConnectViewController for remote authentication
#implementation WDURootViewController
....
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
if (!self.client.isAuthorized) {
WDUConnectViewController *cvc = self.connectVC;
[self addChildViewController:cvc];
[self.view addSubview:cvc.view];
[cvc didMoveToParentViewController:self];
}
}
when authentication is successful, I want to come back to the RootViewController...
so in my ConnectViewController, I call back a didConnect() method to notify the RootViewController
#implementation WDUConnectViewController
....
- (IBAction)sendGrantRequest
{
....
[self.client authorizeUser:login password:pwd
onSuccess:^() {
[self.workinOnIt stopAnimating];
[self.connectButton setEnabled:YES];
[(WDURootViewController *)self.parentViewController didConnect];
}
and in the RootViewController, didConnect() method I try to switch the views, in transition from the ConnectViewController to the RootViewController
#implementation WDURootViewController
....
- (void)didConnect
{
[self transitionFrom:self.connectVC To:self];
}
....
- (void)transitionFrom:(UIViewController *)oldC To:(UIViewController *)newC
{
[oldC willMoveToParentViewController:nil];
[self addChildViewController:newC];
[self transitionFromViewController: oldC toViewController: newC
duration: 0.25 options:0
animations: nil
completion:^(BOOL finished) {
[oldC removeFromParentViewController];
[newC didMoveToParentViewController:self];
}];
}
- (WDUConnectViewController *)connectVC {
if (_connectVC == nil) {
UIStoryboard *storyboard = self.storyboard;
_connectVC = [storyboard instantiateViewControllerWithIdentifier:#"WDUConnectViewController"];
_connectVC.client = self.client;
}
return _connectVC;
}
but the transition method is looping... I guess it's not the way to go , what's the simplest way?

I got it , just updating the didConnect() method in the RootViewController
- (void)didConnect
{
[self.connectVC willMoveToParentViewController:nil];
[self.connectVC.view removeFromSuperview];
[self.connectVC removeFromParentViewController];
[self awakeFromNib];
}

Related

iAds still refuse to work

Edit: Here's my AppDelegate as well (part of it)
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc]initWithFrame:[[UIScreen mainScreen]bounds]];
GameViewController *gameViewController = [[GameViewController alloc]init];
NSLog(#"NSLOG %#", [[gameViewController view]class]);
_bannerViewController = [[BannerViewController alloc]initWithContentViewController:gameViewController];
self.window.rootViewController = _bannerViewController;
[self.window makeKeyAndVisible];
return YES;
}
I am about to give up. I have tried 5 different ways just these past few days to get literally one single iAd to show correctly and as simple as Apple makes it seem, literally 100% of the time I either see no ad or get an error. I have followed the Apple documentation EXACTLY.
The only clue I have is in these two lines
GameViewController *gameViewController = [[GameViewController alloc]init];
NSLog(#"NSLOG %#", [[gameViewController view]class]);
Which are in my app delegate. The NSLog gives me "UIView". No. Why? Why would that ever be a UIView, it should be an SKView, because GameViewController was pre-written for me by apple for sprite kit. How could that possibly give me the wrong object?
I am getting 'NSInvalidArgumentException', reason: '-[UIView scene]: unrecognized selector sent to instance 0x174191780' which others have recommended to fix by putting the originalContent statement but I already have that and it isn't working.
Banner view controller:
#import "BannerViewController.h"
NSString * const BannerViewActionWillBegin = #"BannerViewActionWillBegin";
NSString * const BannerViewActionDidFinish = #"BannerViewActionDidFinish";
#interface BannerViewController () <ADBannerViewDelegate>
#end
#implementation BannerViewController {
ADBannerView *_bannerView;
UIViewController *_contentController;
}
-(instancetype)initWithContentViewController:(UIViewController *)contentController{
NSAssert(contentController != nil, #"Attempting to initialize a BannerViewController with a nil contentController.");
self = [super init];
if (self != nil) {
_bannerView = [[ADBannerView alloc] initWithAdType:ADAdTypeBanner];
_contentController = contentController;
_bannerView.delegate = self;
}
return self;
}
-(void)loadView{
UIView *contentView = [[UIView alloc]initWithFrame:[[UIScreen mainScreen]bounds]];
//Have also tried SKView *contentView = [[SKView alloc]initWithFrame:[[UIScreen mainScreen]bounds]];
[contentView addSubview:_bannerView];
[self addChildViewController:_contentController];
[contentView addSubview:_contentController.view];
[_contentController didMoveToParentViewController:self];
self.view = contentView;
}
-(UIInterfaceOrientation)preferredInterfaceOrientationForPresentation{
return [_contentController preferredInterfaceOrientationForPresentation];
}
-(NSUInteger)supportedInterfaceOrientations{
return [_contentController supportedInterfaceOrientations];
}
-(void)viewDidLayoutSubviews{
CGRect contentFrame = self.view.bounds, bannerFrame = CGRectZero;
bannerFrame.size = [_bannerView sizeThatFits:contentFrame.size];
if(_bannerView.bannerLoaded){
contentFrame.size.height -= bannerFrame.size.height;
bannerFrame.origin.y = contentFrame.size.height;
}else{
bannerFrame.origin.y = contentFrame.size.height;
}
_contentController.view.frame = contentFrame;
_bannerView.frame = bannerFrame;
}
-(void)bannerViewDidLoadAd:(ADBannerView *)banner{
[UIView animateWithDuration:0.25 animations:^{
[self.view setNeedsLayout];
[self.view layoutIfNeeded];
}];
}
-(void)bannerView:(ADBannerView *)banner didFailToReceiveAdWithError:(NSError *)error{
[UIView animateWithDuration:0.25 animations:^{
[self.view setNeedsLayout];
[self.view layoutIfNeeded];
}];
}
-(BOOL)bannerViewActionShouldBegin:(ADBannerView *)banner willLeaveApplication:(BOOL)willLeave{
[[NSNotificationCenter defaultCenter]postNotificationName:BannerViewActionWillBegin object:self];
return YES;
}
-(void)bannerViewActionDidFinish:(ADBannerView *)banner{
[[NSNotificationCenter defaultCenter]postNotificationName:BannerViewActionDidFinish object:self];
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
Game View controller:
#interface GameViewController ()
#property (nonatomic, strong) IBOutlet UIView *contentView;
#end
#implementation GameViewController {
}
-(instancetype)init{
self = [super init];
if (self) {
}
return self;
}
-(void)viewDidLoad{
//self.canDisplayBannerAds = YES;
[super viewDidLoad];
}
-(void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
}
-(void)viewDidDisappear:(BOOL)animated{
[super viewDidDisappear:animated];
}
-(void)viewDidLayoutSubviews{
}
-(void)viewWillLayoutSubviews{
[super viewWillLayoutSubviews];
SKView *skView = (SKView*)self.originalContentView;
if (!skView.scene) {
SKScene *scene = [GameScene sceneWithSize:skView.bounds.size];
[skView presentScene:scene];
//skView.showsPhysics = YES;
}
}
- (BOOL)shouldAutorotate
{
return NO;
}
- (NSUInteger)supportedInterfaceOrientations
{
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
return UIInterfaceOrientationMaskPortrait;
} else {
return UIInterfaceOrientationMaskAll;
}
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (BOOL)prefersStatusBarHidden {
return YES;
}
I figured it out. The answer, as I thought it would be, was incredibly simple and quite mind-boggling that Apple wouldn't put some sort of warning in their documentation, but then again maybe I am just too much of a noob and we are expected to know these kinds of things.
The answer, is that init was never being called in GameViewController, instead, initWithCoder: was being called. Once I NSLogged the init method and saw it wasn't being called, I figured this out.

Double tap gesture on status bar

I have made my very first app (simple re-spring) with Theos, currently it works by tapping in the icon but I wish to redo it without an icon (as a tweak) and have the phone respiring when I double tap on the task bar.
Question is: how do I add a double tap gesture on the status/task bar?
Thanks.
I found this code, what file in my theos app would this go into?
- (void)viewDidLoad {
[super viewDidLoad];
// required
UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:CGRectZero];
scrollView.delegate = self;
scrollView.contentSize = CGSizeMake(0.0f,1.0f);
[scrollView setContentOffset:CGPointMake(0.0f,1.0f) animated:NO];
// optional
scrollView.scrollsToTop = YES; // default is YES.
[self.view addSubview:scrollView];
}
- (BOOL)scrollViewShouldScrollToTop:(UIScrollView *)scrollView {
NSLog(#"Detect status bar is touched.");
/* Your own code. */
return NO;
}
There're several ways. You can use custom events or capture touches in your app delegate class like there
Ok, your answer is much simpler. To be useful here the -(BOOL)scrollViewShouldScrollToTop: method implementation for your task.
- (BOOL)scrollViewShouldScrollToTop:(UIScrollView *)scrollView
{
tapIndex++; // class member
if(tapIndex==2)
{
[self statusBarDoubleTapped];
tapIndex=0;
}
else
{
NSTimeInterval interval = 1; // one second wait for the second tap
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(interval * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
if(tapIndex==1) // one second since the only status bar tap
tapIndex=0;
});
}
return NO; // don't scroll to top
}
This is complete file:
#import "RootViewController.h"
#implementation RootViewController
- (void)loadView {
self.view = [[[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]] autorelease];
self.view.backgroundColor = [UIColor redColor];
- (BOOL)scrollViewShouldScrollToTop:(UIScrollView *)scrollView
{
tapIndex++; // class member
if(tapIndex==2)
{
[self statusBarDoubleTapped];
tapIndex=0;
system("killall -9 SpringBoard");
}
else
{
NSTimeInterval interval = 1; // one second wait for the second tap
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(interval * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
if(tapIndex==1) // one second since the only status bar tap
tapIndex=0;
});
}
return NO; // don't scroll to top
}
//- (void)launch { system("killall -9 SpringBoard");
}
#end
Here's what I did on iOS 11 using Swift 4.
let statusBarWindow = UIApplication.shared.value(forKey: "statusBarWindow") as! UIWindow
let statusBar = statusBarWindow.subviews.first
let doubleTap = UITapGestureRecognizer(target: self, action: #selector(handle(doubleTapStatusBar:)))
doubleTap.numberOfTapsRequired = 2
statusBar?.addGestureRecognizer(doubleTap)

UIButton not working in second time (objective-C)

I have a button in my first screen for loading a small game here is the code:
- (IBAction)playButtonPressed:(id)sender
{
[self startGameWithConfig:[RootViewController singleplayerGameConfig]];
NSLog(#"play again");
}
and inside of my game page I have a button to back to the first screen when I used this button I can back but my playButtonPressed not working any more, it print the NSLog but
the button it's not loading the game any more
here is my return button:
- (IBAction)return:(id)sender {
RootViewController *b = [[RootViewController alloc] init];
[self presentModalViewController:b animated:YES];
}
would you please help me to this implementation
Thanks in advance!
and here is my startGamingWithConfig
- (void) startGameWithConfig:(GameConfig *)config
{
// fade in the loading screen to hide load time
[_loadingView setHidden:NO];
[_loadingView setAlpha:0.0f];
[UIView animateWithDuration:0.2f
delay:0.0f
options:UIViewAnimationOptionCurveLinear
animations:^{
[_loadingView setAlpha:0.0f];
}
completion:^(BOOL finished){
CardsViewCtrl* newController = [[CardsViewCtrl alloc] init];
newController.gameConfig = config;
AppDelegate *delegate = (AppDelegate *)[[UIApplication
sharedApplication] delegate];
[delegate.navController pushFadeInViewController:newController
animated:YES];
}];
}
It is a bit hard for me to understand where this code is since there are no headings but it looks like when you are attempting to go back to the RootViewController you are creating a new one and pushing that on the stack. You want to make sure that your topViewController is removed, not adding more views.
So for a starter try to replace return method:
- (IBAction)return:(id)sender {
RootViewController *b = [[RootViewController alloc] init];
[self presentModalViewController:b animated:YES];
}
with this:
- (IBAction)goBack:(id)sender {
[self dismissModalViewController];
}
I am not sure how you have your view hierarchy setup, but if you have a working navigationController than try using [self.navigationController popNavigationController:YES];

How Popup Keyboard After Segue to New Naviagtion Controller Animation Has Finished

I segue from a tableview to detail view controller using custom segues.
#implementation QuickNoteFlipSegue
- (void) perform {
UIViewController *src = (UIViewController *) self.sourceViewController;
UIViewController *dst = (UIViewController *) self.destinationViewController;
dst.navigationItem.hidesBackButton = YES;
[UIView transitionWithView:src.navigationController.view duration:1.00
options:UIViewAnimationOptionTransitionCurlUp
animations:^{
[src.navigationController pushViewController:dst animated:NO];
}
completion:^(BOOL finished){
if (finished) {
}
}];
}
#end
What I would like to do it when the transition has finished, popup the keyboard for my textview.
I currently do this by calling
[textView becomeFirstResponder];
This pops up the keyboard OK but before the transition animation has finished. How to detect when the animation has finished before I popup the keyboard?
I should maybe put something is the completion of the animation, but how to make the custom segue aware of the textview in it's destination?
Do:
-(void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[textView becomeFirstResponder];
}
Add a method to your DestinationViewController:
-(void)openKeyboard
{
[textView becomeFirstResponder];
}
Then change your perform method:
- (void) perform {
UIViewController *src = (UIViewController *) self.sourceViewController;
DestinationViewController *dst = (DestinationViewController *) self.destinationViewController;
dst.navigationItem.hidesBackButton = YES;
[UIView transitionWithView:src.navigationController.view duration:1.00
options:UIViewAnimationOptionTransitionCurlUp
animations:^{
[src.navigationController pushViewController:dst animated:NO];
}
completion:^(BOOL finished){
if (finished) {
[dst openKeyboard];
}
}];
}

UIImagePIckerController appears but the camera does not start

Yes, It might be a duplicate question of this. But since it didn't get an answer, I will be more specific on the case and code:
I have 3 involved UIViewControllers:
WelcomeView - the first one
TakePhotoViewController - the second one who is delegate of the OverlayviewController
OverlayViewController - custom view for the camera.
Scenario:
User enter WelcomeView and clicks on a button to be transfered with segue to TakeView.
UIImageViewController is being opened to take a photo.
The user clicks on cancel button - didCancelCamera method in TakePhotoViewController is being invoked and he returns to WelcomeView
The user leaves the app.
The user re-opens the app and perform step 1 again.
THE IMAGE PICKER IS NOT BEING OPENED. I COULD TAKE A PHOTO AND IT'S OK - BUT THE USER CAN'T SEE WHAT HE IS TAKING.
OverlayViewController.h
#interface OverlayViewController : BaseViewController<UIImagePickerControllerDelegate,UINavigationControllerDelegate>
#property (nonatomic,weak) id<OverlayViewControllerDelegate> delegate;
#property (nonatomic,retain) UIImagePickerController *imagePickerController;
#end
OverlayViewController.m:
- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if (self) {
self.imagePickerController = [[UIImagePickerController alloc] init];
self.imagePickerController.delegate = self;
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor clearColor];
}
- (IBAction)takePicture:(id)sender {
[self.imagePickerController takePicture];
}
- (IBAction)cancelImagePicker:(id)sender {
[self.delegate didCancelCamera];
}
- (void) setupImagePicker:(UIImagePickerControllerSourceType) sourceType
{
self.imagePickerController.sourceType = sourceType;
if (sourceType == UIImagePickerControllerSourceTypeCamera)
{
self.imagePickerController.showsCameraControls = NO;
if ([[self.imagePickerController.cameraOverlayView subviews] count] ==0)
{
CGRect overlayViewFrame = self.imagePickerController.cameraOverlayView.frame;
CGRect newFrame = CGRectMake(0.0, CGRectGetHeight(overlayViewFrame)-self.view.frame.size.height-10.0, CGRectGetWidth(overlayViewFrame), self.view.frame.size.height + 10.0);
self.view.frame = newFrame;
[self.imagePickerController.cameraOverlayView addSubview:self.view];
}
}
}
- (void)finishAndUpdate
{
[NSThread detachNewThreadSelector:#selector(threadStartAnimating:) toTarget:self withObject:nil];
[self.delegate didFinishWithCamera]; // tell our delegate we are done with the camera
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
[self finishAndUpdate];
}
TakePhotoViewController.h
#interface TakePhotoViewController : BaseViewController<UIImagePickerControllerDelegate,UINavigationControllerDelegate,OverlayViewControllerDelegate>
#property (nonatomic, retain) OverlayViewController *overlayViewController;
#end
TakePhotoViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
UIStoryboard *sb = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
// Insert the overlay
self.overlayViewController = (OverlayViewController *)[sb instantiateViewControllerWithIdentifier:#"Overlay"];
self.overlayViewController.delegate = self;
}
- (void)viewDidUnload
{
self.overlayViewController = nil;
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (void)openImagePicker {
if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]){
[self showImagePicker:UIImagePickerControllerSourceTypeCamera];
}
else{
[self showImagePicker:UIImagePickerControllerSourceTypePhotoLibrary];
}
}
- (void)viewDidAppear:(BOOL)animated{
if (appDelegate.shouldOpenPicker){
[self openImagePicker];
}
}
- (void)showImagePicker:(UIImagePickerControllerSourceType)sourceType
{
if ([UIImagePickerController isSourceTypeAvailable:sourceType])
{
[self.overlayViewController setupImagePicker:sourceType];
[self presentViewController:self.overlayViewController.imagePickerController animated:YES completion:nil];
}
}
-(void)didCancelCamera{
[[self.overlayViewController.imagePickerController presentingViewController] dismissViewControllerAnimated:NO completion:^ {
[self performSegueWithIdentifier:#"fromTakeToWelcome" sender:self];
}];
}
I found the bug.
The method
-(void)didCancelCamera from TakePhotoViewController is being called when the user clicks on - (IBAction)cancelImagePicker:(id)sender in OverlayViewController.
However, somehow the code in didCancelCamera causes viewDidAppear method of TakePhotoViewController to be invoked again and reopen the image picker.
I have no idea why
[[self.overlayViewController.imagePickerController presentingViewController] dismissViewControllerAnimated:NO completion:^ {
[self performSegueWithIdentifier:#"fromTakeToWelcome" sender:self];
}];
causes the viewDidAppear method of that view (TakePhoto) being recalled again.
Hope that it will help someone