i have developed a tab bar application.
Like title i have an iad banner positioned at bottom of screen.
I have implemented this method to create/destroy banner and test iad works correctly:
Create:
-(void)viewWillAppear:(BOOL)animated {
if(!adView) {
adView = [[ADBannerView alloc] initWithFrame:CGRectMake(0, 315, 310, 45)];
adView.requiredContentSizeIdentifiers = [NSSet setWithObject:ADBannerContentSizeIdentifierPortrait];
adView.currentContentSizeIdentifier = ADBannerContentSizeIdentifierPortrait;
adView.delegate = self;
[self.view addSubview:adView];
}
Destroy:
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
// iAd
if (adView != nil) {
adView.delegate = nil;
adView.hidden = YES;
adView = nil;
[adView release];
}
}
But if i try to rapid change view from tab bar i receive this error:
WARNING: More than 10 instances of ADBannerView or ADInterstitialView
currently exist. This is a misuse of the iAd API, and ad performance
will suffer as a result. This message is printed only once.
But the method create and destroy are always called. What i can do to debug this warning problem?
Thanks so much.
You need to release your instance variable before you nil it, not the other way around.
adView = nil;
[adView release];
Should be:
[adView release];
adView = nil;
Related
Hello I'm working in an app with camera.
I can open and use the camera correctly. But I find a bug:
When I open the camera, flips camera, again flips camera and press cancel. Do it a few times ( 3 - 5 ) . Open again the camera and I have a black freeze screen for a few seconds and if you take a picture see the image but the screen continue in black. After a few seconds the camera appears again and you can continue with the normal behavior. But I cant find a solution to this.
I searched a lot in internet and find some answers but nothing solve my problem.
Here a similar problem but the solution didnt work for me:
Stackoverflow - UIImagePickerController Freezes when camera flips
Stackoverflow - UIImagePicker freezes
Stackoverflow - iOS 7 UIImagePicker preview black screen
Stackoverflow - iDevice camera shows black instead of preview
Also I use DejalBezelActivityView to create a spinner area with a label DejalBezelActivityView
Any idea?
I have my .h declaration:
#property (nonatomic, strong) UIImagePickerController* picker;
- (void) takePhoto: (id)vc;
- (void) selectPhoto: (id)vc;
And my .mm code:
#synthesize picker = _picker;
- (id) init{
self = [super init];
if (self){
self.picker = [[UIImagePickerController alloc] init];
}
return self;
}
- (void)takePhoto:(id)vc{
if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]){
[VC_Camera showAlert];
return;
}
[self init];
self.picker.delegate = self;
self.picker.allowsEditing = YES;
self.picker.sourceType = UIImagePickerControllerSourceTypeCamera;
self.picker.cameraDevice = UIImagePickerControllerCameraDeviceRear;
[[VC_Camera getMainWindow] presentViewController:self.picker animated:YES completion:NULL];
}
- (void)selectPhoto:(id)vc{
if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]){
[VC_Camera showAlert];
return;
}
[self init];
self.picker.delegate = self;
self.picker.allowsEditing = YES;
self.picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
[[VC_Camera getMainWindow] presentViewController:self.picker animated:YES completion:NULL];
}
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
self.picker = picker;
DejalActivityView * _activityView = [DejalBezelActivityView activityViewForView:[[UIApplication sharedApplication] keyWindow] withLabel:#"Loading"];
[self performSelector:#selector(cancelAfterDelay:) withObject:#{#"DejalAV":_activityView} afterDelay:1.0];
}
- (void) cancelAfterDelay:(NSDictionary*) dict
{
DejalActivityView* _activityView = [dict objectForKey:#"DejalAV"];
[DejalBezelActivityView removeViewAnimated:YES];
[self.picker dismissViewControllerAnimated:YES completion:nil];
}
Thanks :D
[UPDATE]
I try to use the UIImagePickerController as a singleton:
-(UIImagePickerController *) imagePicker{
if(!_imagePicker){
_imagePicker = [[UIImagePickerController alloc] init];
_imagePicker.delegate = self;
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]){
_imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
}
else{
_imagePicker.sourceType =UIImagePickerControllerSourceTypePhotoLibrary;
}
}
return _imagePicker;
}
And the problem persist.
This is a very late response, but for those still wrestling with this issue: I've noticed this seems to happen when something is either backing up the main thread, or affecting the graphics context on a separate thread. Those might be places to start looking.
Here is the set up of my view:
When the UIBarButtonItem is clicked, it should bring up a UIImagePickerController. I have to do this using a UIPopoverController, which is invoked by clicking on the "reset" button, because it is necessary on the iPad. Here is my code:
-(IBAction) btnReset:(id)sender {
[self chooseImage];
}
-(void) chooseImage {
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) {
imagepicker = [[UIImagePickerController alloc] init];
imagepicker.allowsEditing = NO;
imagepicker.delegate = self;
imagepicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
imagepicker.navigationBar.opaque = true;
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
popoverController = [[UIPopoverController alloc] initWithContentViewController:imagepicker];
[popoverController presentPopoverFromBarButtonItem:reset permittedArrowDirections:UIPopoverArrowDirectionDown animated:YES];
} else {
[self presentModalViewController:imagepicker animated:YES];
}
}
}
However, when this is called, the view crashes with the error:
'NSInvalidArgumentException', reason: '-[UIPopoverController presentPopoverFromRect:inView:permittedArrowDirections:animated:]: Popovers cannot be presented from a view which does not have a window.'
What am I doing wrong? Thank you in advance.
It looks like you are trying to create a popover on an item which is not on the view hierarchy. If this method is being invoked by your button then change the method header to -(void) chooseImage:(id)sender and try presenting the popover from the UIBarButton you have on your toolbar.
Also if you are using ARC (which it looks like you are) you have to hold on to your UIPopover otherwise it will be released when it is still required see this stack overflow post. You may already be doing this but I thought I would raise it as a I can't see if/how you have specified your popoverController.
I've seen several apps do this, and i've been wondering how it's done. If you look at the Wunderkit app, when it loads something, there's a blue animated bar that slides down to cover the status bar until it finishes loading. How is this done?
you can subclass UIWindow.
And set it windowLevel = UIWindowLevelStatusBar;
code:
#interface CHLoadingWindow : UIWindow
#implementation CHLoadingWindow
- (id)init
{
self = [super init];
if (self) {
self.windowLevel = UIWindowLevelStatusBar;
// then draw your UI
}
return self;
}
#end
use it:
CHLoadingWindow *loading = [[CHLoadingWindow alloc] init];
[loading makeKeyAndVisible];
discover it:
[loading release];
loading = nil;
[[[[UIApplication sharedApplication] windows] objectAtIndex:0] makeKeyWindow];
I've been trying to figure this out for 2 days now, and before anyone posts another stackoverflow question, I've read them all and none of them cover my problem exactly:
I have a CoreData app that updates dynamically. Now during the update I want an UIAlertView to pop up saying that an update is being downloaded.
So here's the important code:
AppDelegate:
- (void)applicationDidBecomeActive:(UIApplication *)application
{
[myUpdater checkForUpdatesInContext:self.managedObjectContext];
}
_
Updater Class:
- (void)checkForUpdatesInContext:(NSManagedObjectContext *)myManagedObjectContext
{
[self loadUpdateTime];
NSLog(#"Update start");
NSDate *now = [NSDate dateWithTimeIntervalSinceNow:[[NSTimeZone localTimeZone] secondsFromGMT]];
if ([now timeIntervalSinceDate:updateTime] < UPDATE_TIME_INTERVAL)
{
return;
}
[self showAlertViewWithTitle:#"Update"];
... //updating process
[self.alertView dismissWithClickedButtonIndex:0 animated:YES];
NSLog (#"Update done");
}
- (void) showAlertViewWithTitle:(NSString *)title
{
self.alertView = [[UIAlertView alloc] initWithTitle:title message:#"Daten werden aktualisiert..." delegate:self cancelButtonTitle:nil otherButtonTitles:nil];
... //design the alertView
[self.alertView show];
NSLog (#"AlertView shows");
}
So here is what happens when I run this:
Launch image shows
NSLog "Update starts" fires
NSLog "AlertView shows" fires
Screen dims but no AlertView is shown
Update is running
NSLog "Update done" fires
Launch image goes away and TabBarController shows up
UIAlertView shows up and is dismissed right away and the dimmed screen returns to normal
What I would like to have happen:
Launch image
TabBarController shows up
Screen dims and UIAlertView shows
Update is running
UIAlertView gets dismissed and dimmed screen returns to normal
I know it's something with the UI Thread and the main Thread and stuff.. But I tried every combination it seems but still not the expected result. Please help :)
EDIT:
HighlightsViewController Class:
- (void)viewDidLoad
{
[super viewDidLoad];
self.updater = [[Updater alloc] init];
[updater checkForUpdatesInContext:self.managedObjectContext];
... // other setup stuff nothing worth mentioning
}
Is this the right place to call [super viewDidLoad]? Because it still doesn't work like this, still the update is being done while the Launch Image is showing on the screen. :-(( I'm about to give this one up..
Here you go, in this prototype things work exactly how you want them to.
Header:
#import <UIKit/UIKit.h>
#interface AlertViewProtoViewController : UIViewController
{
}
- (void) showAlertViewWithTitle:(NSString *)title;
- (void) checkForUpdatesInContext;
- (void) update;
- (void)someMethod;
- (void)someOtherMethod;
#end
#import "AlertViewProtoViewController.h"
Class:
#implementation AlertViewProtoViewController
UIAlertView *alertView;
bool updateDone;
UILabel *test;
bool timershizzle;
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.view.backgroundColor = [UIColor yellowColor];
UILabel *test = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 500, 500)];
test.backgroundColor = [UIColor blueColor];
[self.view addSubview:test];
[self performSelector:#selector(checkForUpdatesInContext) withObject:nil afterDelay:0.0];
}
- (void)update
{
//NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; //commented for auto ref counting
NSLog(#"update start");
//your update stuff
NSLog(#"update end");
updateDone = YES;
//[pool release];
}
- (void)checkForUpdatesInContext//:(NSManagedObjectContext *)myManagedObjectContext
{
//[self loadUpdateTime];
NSLog(#"Update start");
NSDate *now = [NSDate dateWithTimeIntervalSinceNow:[[NSTimeZone localTimeZone] secondsFromGMT]];
// if ([now timeIntervalSinceDate:updateTime] < UPDATE_TIME_INTERVAL)
// {
// return;
// }
[self showAlertViewWithTitle:#"Update"];
//[self setManagedObjectContext:myManagedObjectContext];
[self performSelector:#selector(someMethod) withObject:nil afterDelay:0.0];
[self performSelector:#selector(someOtherMethod) withObject:nil afterDelay:0.0];
}
-(void)someOtherMethod
{
while (!updateDone) {
// NSLog(#"waiting...");
}
[alertView dismissWithClickedButtonIndex:0 animated:YES];
NSLog (#"Update done");
self.view.backgroundColor = [UIColor greenColor];
}
-(void)someMethod
{
[self performSelectorInBackground:#selector(update) withObject:nil];
}
- (void) showAlertViewWithTitle:(NSString *)title
{
alertView = [[UIAlertView alloc] initWithTitle:title message:#"Daten werden aktualisiert..." delegate:self cancelButtonTitle:nil otherButtonTitles:nil];
alertView.frame = CGRectMake(100, 100, 200, 200);
alertView.backgroundColor = [UIColor whiteColor];
[self.view addSubview:alertView];
[self.view setNeedsDisplay];
NSLog (#"AlertView shows");
}
#end
You should adjust were needed for your own purposes but it works.
You are starting a background thread and then dismissing the alert immediately. I would suggest that you might use an NSNotification, posted from the background task, and received in whichever controller starts the alert, triggering a method that dismissed the alert.
I find the UIAlertView interface unsuitable for this type of user notice, and prefer to use a semi-transparent overlay view with a UIActivityIndicatorView, plus an informing message for the user.
You are doing a:
- (void)applicationDidBecomeActive:(UIApplication *)application
Isn't it so that the alertview you want to show needs a view to be loaded which isn't active yet at this point? See: http://developer.apple.com/library/ios/#documentation/uikit/reference/UIAlertView_Class/UIAlertView/UIAlertView.html
Similar question? UIAlertView starts to show, screen dims, but it doesn't pop up until it's too late!
So, another EXC_BAD_ACCESS topic on StackOverflow, but as I'm new to Objective-C this is still a topic I don't really grasp yet. Even though I have done a lot of research about it already.
The issue is the following. I have a UIScrollView that I have overwritten using a Custom Class (named MultiSelectView). If the user taps this UIScrollView and then I want to open a view that allows him to select some data.
So I have declared a UITapGestureRecognizer that calls the openMultiSelect: method. But on the line [parent.navigationController pushViewController:view animated:YES]; I get a Program received signal: "EXC_BAD_ACCESS". error. Why o why?
- (id) initWithCoder:(NSCoder *) coder {
self = [super initWithCoder: coder];
if (self) {
// Add a Tap Gesture Recognizer to the Scrollview.
// If the user taps the view, it triggers the 'openMultiSelect' method.
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(openMultiSelect:)];
[singleTap setNumberOfTapsRequired:1];
[singleTap setNumberOfTouchesRequired:1];
[self addGestureRecognizer:singleTap];
}
return self;
}
- (void)openMultiSelect:(UIGestureRecognizer *)gesture {
//int myViewTag = gesture.view.tag; // now you know which view called
DataSelectView *view = [[DataSelectView alloc] initWithNibName:#"DataSelectView" bundle:[NSBundle mainBundle]];
view.allowMultiSelect = YES;
[parent.navigationController pushViewController:view animated:YES];
[view release];
}
So the parent that you see is a ViewController that contains the tab. Is there a better way to do this? Because for now I have thus a ViewController that contains Tabs. In its activateTab: method I thus create the tab and pass self along. I do the same in the viewDidLoad for that tab to pass the parent to the custom UIScrollView:
- (void) activateTab:(int)index {
... code ...
self.tab_Basic = [[TabBasic alloc] initWithNibName:#"TabBasic" bundle: [NSBundle mainBundle]];
self.tab_Basic.parent = self;
... code ...
}
You should make some change to your callback method. Something like that:
- (void)openMultiSelect:(UIGestureRecognizer *)gesture {
//int myViewTag = gesture.view.tag; // now you know which view called
if(gesture.state == UIGestureRecognizerStateEnded){
DataSelectView *view = [[DataSelectView alloc] initWithNibName:#"DataSelectView" bundle:[NSBundle mainBundle]];
view.allowMultiSelect = YES;
[parent.navigationController pushViewController:view animated:YES];
[view release];
}
}
What you are doing wrong is releasing the object "view" too early, don't release it until the view is popped. That should fix the problem.
- (void)openMultiSelect:(UIGestureRecognizer *)gesture {
//int myViewTag = gesture.view.tag; // now you know which view called
DataSelectView *view = [[DataSelectView alloc] initWithNibName:#"DataSelectView" bundle:[NSBundle mainBundle]];
view.allowMultiSelect = YES;
[parent.navigationController pushViewController:view animated:YES];