WARNING: More than 10 instances of ADBannerView or ADInterstitialView currently exist - objective-c

I have a iPad app with 2 view controllers; 1st one is for the UI, the 2nd for a view which displays help from a UIWebView. When I go back and forth 10 times between view controllers, I get the message in the title above on exactly the 10th time returning to the first VC.
This is my code in VC #1:
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
adView = [[ADBannerView alloc] initWithFrame:CGRectMake(0, self.view.frame.size.height - 50, 320, 50)];
_adBanner = [[ADBannerView alloc] initWithFrame:CGRectMake(0, self.view.frame.size.height, 320, 50)];
_adBanner.delegate = self;
[self.view addSubview:adView];
}
- (void) viewWillDisappear:(BOOL)animated {
[_adBanner removeFromSuperview];
_adBanner.delegate = nil;
_adBanner = nil;
}
- (void)bannerViewDidLoadAd:(ADBannerView *)banner {
if (!_bannerIsVisible) {
// If banner isn't part of view hierarchy, add it
if (_adBanner.superview == nil)
[self.view addSubview:_adBanner];
// }
[UIView beginAnimations:#"animateAdBannerOn" context:NULL];
// Assumes the banner view is just off the bottom of the screen.
banner.frame = CGRectOffset(banner.frame, 0, -banner.frame.size.height);
[UIView commitAnimations];
_bannerIsVisible = YES;
}
}
- (void)bannerView:(ADBannerView *)banner didFailToReceiveAdWithError:(NSError *)error {
NSLog(#"Failed to retrieve ad");
if (_bannerIsVisible) {
[UIView beginAnimations:#"animateAdBannerOff" context:NULL];
// Assumes the banner view is placed at the bottom of the screen.
banner.frame = CGRectOffset(banner.frame, 0, banner.frame.size.height);
[UIView commitAnimations];
_bannerIsVisible = NO;
}
}
I know why, just don't know how to fix it. Can someone please help me with this?

You create an instance of ADBannerView in viewDidAppear and assign it to adView You don't appear do anything with this and more relevantly don't discard it in viewWillDisappear so each time you pop back to this view controller the previous instance is orphaned when you cycle through viewDidAppear.
Also possibly another issue is that you are not calling [super viewWillDisappear:] in your viewWillDisappear method.

Related

How to flip an individual UIView (without flipping the parent view)

This is an iPad project where I have a UIView with several subViews, and I am trying to animate one of this UIViews using [UIView transitionFromView:toView:duration:options:completion], but when I run this method the whole parent view gets flipped!
This is the code I'm using:
UIView *secondView = [[UIView alloc] initWithFrame:CGRectMake(200, 200, 300, 300)];
[newView setBackgroundColor:[UIColor redColor]];
[UIView transitionFromView:self.firstView.view toView:secondView duration:1.0 options:UIViewAnimationOptionTransitionFlipFromLeft completion:nil];
Any idea on how can I flip between this views without animating the whole parent view?
Thanks!
this code may helps you:
put the two views you want to flip inside an unnamed view with the same size
and link the IBOutlet UIView *newView,*oldView; to the views and put the new view on top
bool a = NO;
#implementation ViewController
- (IBAction)flip:(id)sender
{
if (a == NO) {
[UIView transitionFromView:oldView toView:newView
duration:1.0
options:UIViewAnimationOptionTransitionFlipFromLeft
completion:NULL];
a = YES; // a = !a;
}
else {
[UIView transitionFromView:newView toView:oldView
duration:1.0
options:UIViewAnimationOptionTransitionFlipFromLeft
completion:NULL];
a = NO; // a = !a;
}
}
I had problems getting this to work also. I used the code written by Floris, but although it worked for the first "flip" the next flip started to go weird where the buttons and labels on the frontside UI View lost there positions.
I put the code below into place and it is working fine.
Couple of things to note:
panelView is a UIView control on the ViewController that has two other UIViews nested inside it (subviews). The first one is called frontView, second one is called backView. (see picture below)
I have a bool property called displayingFront on the class
(in my .h)
#property BOOL displayingFront;
in my .m
#synthesize displayingFront;
in my viewDidLoad method
self.displayingFront = YES;
This is the code in the .m that i have rigged up to the two buttons if front and back UIViews...
- (IBAction)flip:(id)sender
{
[UIView transitionWithView:self.panelView
duration:1.0
options:(displayingFront ? UIViewAnimationOptionTransitionFlipFromRight :
UIViewAnimationOptionTransitionFlipFromLeft)
animations: ^{
if(displayingFront)
{
self.frontView.hidden = true;
self.backView.hidden = false;
}
else
{
self.frontView.hidden = false;
self.backView.hidden = true;
}
}
completion:^(BOOL finished) {
if (finished) {
displayingFront = !displayingFront;
}
}];
}
Use a container view to hold your subviews, and make the container view the same size as your subview that you're trying to animate.
So, you can setup your views like this.
self.view-> "a container view" -> subviews
**//flipping view continuously**
bool a = NO;
-(void)viewDidLoad
{
// THIS is the canvass holding the two views this view is flipping
UIView *v=[[UIView alloc]initWithFrame:CGRectMake(40, 40, 150, 150)];
v.backgroundColor=[UIColor clearColor];
[self.view addSubview:v];
[v addSubview:yourfirstview];
[v addSubview:yoursecondview];
// calling the method
[NSTimer scheduledTimerWithTimeInterval:2.0
target:self
selector:#selector(flip)
userInfo:nil
repeats:YES];
}
//flipping view randomly
-(void)flip
{
if (a == NO)
{
[UIView transitionFromView:yourfirstview toView:yoursecondview duration:1.0 options:UIViewAnimationOptionTransitionFlipFromLeft completion:NULL];
a = YES;
}
else if(a==YES)
{
[UIView transitionFromView:yoursecondview toView:yourfirstview duration:1.0 options:UIViewAnimationOptionTransitionFlipFromLeft completion:NULL];
a = NO;
}
}
I fixed this problem by using old-school animations:
[UIView beginAnimations:#"Flip" context:nil];
[UIView setAnimationDuration:1];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:firstView cache:YES];
[self addSubview:secondView];
[UIView commitAnimations];
Additionally you can remove the firstView:
[firstView removeFromSuperview];
I'd like to make an update of Steve Parker's answer in SWIFT 4:-
var displayBlankView:Bool = true
UIView.transition(with:flipView, duration:1.0, options:displayBlankView ? .transitionFlipFromLeft:.transitionFlipFromRight, animations:{
if(self.displayBlankView){
self.view1.isHidden=true
self.view2.isHidden=false
}else{
self.view1.isHidden=false
self.view2.isHidden=true
}
}, completion:{
(finished: Bool) in
self.displayBlankView = !self.displayBlankView;
})

Changing iAd position and placement

I've been looking at various tutorials and code snippets, try to implement iAd. I've been successful to an extent but I need to customise, I can't seem to work out what I need to do to make my changes, can anyone help?
- (void)viewDidLoad
{
adView = [[ADBannerView alloc] initWithFrame:CGRectZero];
adView.frame = CGRectOffset(adView.frame, 0, -50);
adView.requiredContentSizeIdentifiers = [NSSet setWithObjects:ADBannerContentSizeIdentifierPortrait, ADBannerContentSizeIdentifierLandscape, nil];
adView.currentContentSizeIdentifier = ADBannerContentSizeIdentifierPortrait;
[self.view addSubview:adView];
adView.delegate = self;
self.bannerIsVisible = NO;
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}
- (void)bannerViewDidLoadAd:(ADBannerView *)banner
{
if (!self.bannerIsVisible)
{
[UIView beginAnimations:#"animateAdBannerOn" context:NULL];
// banner is invisible now and moved out of the screen on 50 px
banner.frame = CGRectOffset(banner.frame, 0, 50);
[UIView commitAnimations];
self.bannerIsVisible = YES;
}
}
- (void)bannerView:(ADBannerView *)banner didFailToReceiveAdWithError:(NSError *)error
{
if (self.bannerIsVisible)
{
[UIView beginAnimations:#"animateAdBannerOff" context:NULL];
// banner is visible and we move it out of the screen, due to connection issue
banner.frame = CGRectOffset(banner.frame, 0, -50);
[UIView commitAnimations];
self.bannerIsVisible = NO;
}
}
As it stands, the banners are loaded at the top of a UIWebView. Firstly I'd like it at the bottom and secondly, the ad overlaps the WebView content, is there any way I can push the WebView when an ad loads or disappears?
I'd appreciate any help, this is driving round the bend!
Thanks.
set adview.frame.origin.y to however far bottom you want it, when you want it. For instance, my iad is setup in the app delegate, then in the view controller I want, in viewwillapear, I'd use adview.frame.origin.x = 0;adview.frame.origin.y = 420; [SharediAdView setframe:adview.frame];
with diff settings depending on iphone 3.5inch/4inch, space in the current view controller, & orientation.
If you'd rather move everything up/down, and don't want to mess with a tailored solution, I'd try this stuff: https://github.com/chrisjp/CJPAdController
adView.frame = CGRectMake(0.0, 375.0, iAdView.frame.size.width, iAdView.frame.size.height);
Use this code instead of
adView.frame = CGRectOffset(adView.frame, 0, -50);
banner.frame = CGRectOffset(banner.frame, 0, 50);
banner.frame = CGRectOffset(banner.frame, 0, -50);
and change Ad placement (375.0) according to what you want :)

Why is my iAd banner not showing?

- (void)viewDidLoad
{
adView = [[ADBannerView alloc] initWithFrame:CGRectZero];
adView.requiredContentSizeIdentifiers = [NSSet setWithObject:ADBannerContentSizeIdentifierPortrait];
adView.currentContentSizeIdentifier = ADBannerContentSizeIdentifierPortrait;
CGRect adFrame = adView.frame;
adFrame.origin.y = self.view.frame.size.height-adView.frame.size.height;
adView.frame = adFrame;
[self.view addSubview:adView];
}
- (void)bannerViewDidLoadAd:(ADBannerView *)banner
{
if (!self.bannerIsVisible)
{
self.bannerIsVisible = YES;
}
}
- (void)bannerView:(ADBannerView *)banner didFailToReceiveAdWithError:(NSError *)error
{
if (self.bannerIsVisible)
{
self.bannerIsVisible = NO;
}
There are a four things. First, you should be positioning the banner off screen in your viewDidLoad method because it will just show an empty frame when you first launch and will more than likely get rejected because of it.
Secondly, you are setting up your banner view incorrectly. I think the frame is still CGZero. Thirdly you are not setting the bannerView's delegate. Try the following:
-(void)viewDidLoad{
CGRect frame=CGRectZero;
frame.size = [ADBannerView sizeFromBannerContentSizeIdentifier:ADBannerContentSizeIdentifierPortrait];
// Place frame at the bottom edge of the screen out of sight
frame.origin = CGPointMake(0.0, CGRectGetMaxY(self.view.bounds));
// Now to create and configure the banner view
ADBannerView *adView = [[ADBannerView alloc] initWithFrame:frame];
adView.requiredContentSizeIdentifiers = [NSSet setWithObject:ADBannerContentSizeIdentifierPortrait];
// Set the delegate to self, so that we are notified of ad responses
adView.delegate = self;
[self.view addSubview: adView];
}
Fourth, in your bannerViewDidLoadAd: method you are not animating the banner ad into place. Try this:
- (void)bannerViewDidLoadAd:(ADBannerView *)banner
{
// Get a brand new frame
CGRect newFrame=CGRectZero;
CGPoint frameOrigin=CGPointZero;
// Set the origin
frameOrigin=CGPointMake(0.0, CGRectGetMaxY(self.view.bounds));
newFrame.origin=frameOrigin;
// Set the size
newFrame.size=[ADBannerView sizeFromBannerContentSizeIdentifier:ADBannerContentSizeIdentifierPortrait];
CGFloat bannerHeight = newFrame.size.height;
CGFloat bannerOffset=0.0;
// Determine where the new frame should be
if (!self.bannerIsVisible)
{
// It should be visible, raise it up
bannerOffset=-bannerHeight;
}
CGRect offSetRect=CGRectOffset(newFrame,0.0f,bannerOffset);
[UIView animateWithDuration:0.2
animations:^{banner.view.frame=offSetRect}
completion:^(BOOL finished){
if (bannerOffSet<0){
self.bannerIsVisible=YES;
}else{
self.bannerIsVisible=NO;
}
}
];
}
of course if the banner is supposed to be positioned at the top of the screen, you can probably figure out how things need to be modified, but this gets you in going in the right direction.
Good luck
Not sure by reading your question, but do be aware that Apple simulates iAds not being available. Sometimes you need to try multiple times before the sample ad comes through.

Auto scroll functionality in iPhone SDK

I had added auto scroll functionality to my application by going through sample code.
In this code I'm getting scroll from top to bottom and bottom to top. But I don't want to scroll from top to bottom . I always wants to scroll from bottom to top only. If I'm removing the topToBottom code and making changes to the remaining code according to that it is not working. Can any one help me.
-(void)viewdidLoad
{
infoScrollView = [[UIScrollView alloc]init];
infoScrollView.frame = CGRectMake(0,0,330,270);
infoScrollView.contentSize = CGSizeMake(100,1000);
[myInfoView addSubview:infoScrollView];
scrollingToTop=NO;
UIImageView *infoImgView = [[UIImageView alloc]initWithFrame:CGRectMake(70,0,200,1000)];
infoImgView.image = [UIImage imageNamed:#"lepke-tar2.png"];
[infoScrollView addSubview:infoImgView];
infoScrollView.delegate = self;
if (infoScrollView.contentSize.height>infoScrollView.frame.size.height)
{
[infoScrollView scrollRectToVisible:CGRectMake(0, infoScrollView.contentSize.height-infoScrollView.frame.size.height, infoScrollView.frame.size.width, infoScrollView.frame.size.height) animated:NO];
}
[self performSelector:#selector(scrollToTop) withObject:nil afterDelay:0.5];
[myInfoView addSubview:infoScrollView];
UIButton* infocancelBttn = [[UIButton alloc ]initWithFrame:CGRectMake(295,-8,45,45)];
[infocancelBttn setImage:[UIImage imageNamed:#"cancel_icon.png"] forState:UIControlStateNormal];
[infocancelBttn addTarget:self action:#selector(infoViewCloseAction) forControlEvents:UIControlEventTouchUpInside];
[myInfoView addSubview:infocancelBttn];
[infocancelBttn release];
}
-(void)viewDidAppear:(BOOL)animated
{
[infoScrollView scrollRectToVisible:CGRectMake(0, 0, infoScrollView.frame.size.width, infoScrollView.frame.size.height+200) animated:YES];
}
- (void) scrollToTop
{
scrollingToTop=YES;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:10.0];
//[self.scrollView scrollRectToVisible:CGRectMake(0, 0, self.scrollView.frame.size.width, self.scrollView.frame.size.height) animated:YES];
[infoScrollView setContentOffset:CGPointMake(0,-300)];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:#selector(scroll)];
[UIView commitAnimations];
}
-(void) scroll
{
if (scrollingToTop==YES)
{
[self performSelector:#selector(scrollToBottom) withObject:nil afterDelay:1.0];
}
else
{
[self performSelector:#selector(scrollToTop) withObject:nil afterDelay:1.0];
}
}
- (void)scrollToBottom
{
scrollingToTop=NO;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:10.0];
[infoScrollView setContentOffset:CGPointMake(0,infoScrollView.contentSize.height-infoScrollView.frame.size.height)animated:NO];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:#selector(scroll)];
[UIView commitAnimations];
}
I think your if-statement is wrong:
-(void) scroll
{
if (scrollingToTop==YES)
{
[self performSelector:#selector(scrollToBottom) withObject:nil afterDelay:1.0];
}
else...
if you delete your scrollToBottom-method your code fails.
you should change this to
[self performSelector:#selector(scrollToTop) withObject:nil afterDelay:1.0];
because you are asking if scrollingToTop is true

Handling Device orientation problem for swapped views

i'm doing an ipad application, in which i have say two views
mainview and aboutus view
on startup i put the mainview in the rootcontroller's view (the one that is added to the window) alone.
and there's a button on mainview, that, when pressed, will remove the mainview from superview and put the aboutusview instead. aboutus has a similar button that gets us back to mainview.
Now the problem lies in the rotation (orientation).
when i detect an orientation change, i update the displayed view. works fine. (for mainview and aboutusview)
But if i rotate once any view, and then then try to see the second view. it seems that the second view is not autosizing.
CODE in rootViewController:
- (void)viewDidLoad
{
[super viewDidLoad];
_currentOrientation=UIDeviceOrientationPortrait;
[self.view addSubview:_mainView];
[_splashView removeFromSuperview];
}
-(void)viewDidAppear:(BOOL)animated
{
_currentView = _mainView;
}
-(void)toggleMainPage
{
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:.5];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:[self view] cache:YES];
[_infoView removeFromSuperview];
[self.view addSubview:_mainView];
_currentView=_mainView;
[self transformViewAccordingToOrientation:_currentOrientation];
[UIView commitAnimations];
}
-(void)toggleAboutPage
{
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:.5];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:[self view] cache:YES];
[_mainView removeFromSuperview];
[self.view addSubview:_infoView];
_currentView=_infoView;
[self transformViewAccordingToOrientation:_currentOrientation];
[UIView commitAnimations];
}
-(void) transformViewAccordingToOrientation:(UIDeviceOrientation)toInterfaceOrientation
{
if(toInterfaceOrientation == UIDeviceOrientationPortrait)
{
[_mainBtnCustom setBackgroundImage:[UIImage imageNamed:#"main.png"] forState:UIControlStateNormal];
_infoImage.image = [UIImage imageNamed:#"about.png"];
}else
{
[_mainBtnCustom setBackgroundImage:[UIImage imageNamed:#"mainr.png"] forState:UIControlStateNormal];
_infoImage.image = [UIImage imageNamed:#"aboutr.png"];
}
}
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
[self transformViewAccordingToOrientation:toInterfaceOrientation];
}
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
_currentOrientation = [UIDevice currentDevice].orientation;
[self transformViewAccordingToOrientation:_currentOrientation];
}
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (_currentOrientation !=interfaceOrientation);
}
what am i doing wrong?