I am struggling to hide a banner view when a purchase is made.
I have 2 separate versions, one is an Admob banner (bannerView_), the other is actually a view which I called _adView they share the same place but rotate around depending on what is viewing.
Anyhow, the Admob banner hides no problem, but the _adView does not, here is hiding code;
-(void)removeBanner:(NSNotification *) notify {
NSLog(#"Removing:");
if ([MKStoreManager isFeaturePurchased:#"com.fredsworld.ubercool.removeads"]) {
[bannerView_ setHidden:YES];
[_adView setHidden:YES];
NSLog(#"Removed:");
}
}
Basically that runs on a purchase, so it updates the screen instantly,
The _adView code to call it in the viewDidLoad is;
CGFloat y = self.view.frame.size.height - 50.0;
TapForTapAdView *adView = [[TapForTapAdView alloc] initWithFrame: CGRectMake(0, y, 320, 50) delegate: self];
[self.view addSubview: adView];
I have synthesized adView and created it as an object, but still no joy, it does not disappear when the purchase is made.
Although, it DOES work, as if you close the app, then re open, it has gone but obviously I want it to disappear immediately upon purchase.
Any ideas?
it was solved by removing the TapForTapAdView *adView on line 2 and simply changing to self.adView =
Related
I have a UIViewController with a UIScrollView in it. When running in the simulator, I drag the UIScrollView and it starts moving correctly, but when I release the drag, there's a small delay (around half a second) then the view continues moving to finish the momentum.
This delay only happens when the touch release happens in the view. So if I drag and release outside the simulator, there is no delay.
Here's the code for creating the UIScrollView:
scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
scrollView.pagingEnabled = YES;
scrollView.showsHorizontalScrollIndicator = NO;
//scrollView.delaysContentTouches = NO;
//scrollView.userInteractionEnabled = YES;
scrollView.delegate = self;
[self.view addSubview:scrollView];
// Add some sub views here
// ...
// 2 pages
scrollView.contentSize = CGSizeMake(self.view.frame.size.width*2, self.view.frame.size.height);
I have not overridden any touch events in the app.
I have not implemented any of the UIScrollViewDelegate methods.
Enabling and disabling paging doesn't make a difference.
I have not run this on a physical device, just in the simulator.
What's the problem?
Thanks.
Answering my own question in case someone else was wondering.
This is a side effect of using the touchpad on the MacBook. When doing three-finger dragging, the OS adds a delay after releasing to allow you to take your fingers up and quickly put them back down to continue dragging. This doesn't happen when using a mouse.
No problem with code or the simulator.
Silly me :)
I want to show a status bar in the bottom of the iPhone like the one in Gmail account that is appear to indicate that it is checking mail. I have tried the following solution in this thread
Adding view on StatusBar in iPhone
but the status bar didn't appear, then i used the same code without any modification to show it in the top of the default status bar and it also didn't appear.
i have tried also another solution using MTStatusBarOverlay, when i tried to change its frame to be at the bottom i got a black rectangl in the middle of the screen
any help?
here is the code
// new class i have created
#interface BottomStatusBarOverlay : UIWindow
#end
#implementation BottomStatusBarOverlay
- (id)initWithFrame:(CGRect)frame {
if ((self = [super initWithFrame:frame])) {
// Place the window on the correct level and position
self.windowLevel = UIWindowLevelStatusBar+1.0f;
self.frame = [[UIApplication sharedApplication] statusBarFrame];
self.alpha = 1;
self.hidden = NO;
// Create an image view with an image to make it look like a status bar.
UIImageView *backgroundImageView = [[UIImageView alloc] initWithFrame:self.frame];
backgroundImageView.image = [[UIImage imageNamed:#"statusBarBackgroundGrey.png"] stretchableImageWithLeftCapWidth:2.0f topCapHeight:0.0f];
[self addSubview:backgroundImageView];
}
return self;
}
#end
// usage in my view controller in a button action
#implementation MainViewController
-(IBAction)showBottomStatusbar:(id)sender {
BottomStatusBarOverlay *bottomStatusBarOverlay = [[BottomStatusBarOverlay alloc] init];
bottomStatusBarOverlay.hidden = NO;
}
The code you posted shows that your showBottomStatusbar method creates a BottomStatusBarOverlay instance, but you never actually add it as a subview to anything.
I don't use the Gmail app on iPhone. So, I'm not sure what it looks like or how it functions. However, I have create a notification bar in the past that seems similar to what you described. It animates on to the bottom of the screen, shows a message for three seconds, and then slides back off. I accomplished this by adding the bar to the application's window, which will ensure it overlays any view the application is currently showing. You could, however, add the bar to any view that is currently active, if you don't need a global bar within your app. Here's how you get the app's window reference:
UIApplication* app = [UIApplication sharedApplication];
UIWindow* appWin = app.delegate.window;
To animate, you can use animateWithDuration, like so:
[UIView animateWithDuration:0.3
animations:^ {
// However you want to animate on to the screen.
// This will slide it up from the bottom, assuming the
// view's start position was below the screen.
view.frame = CGRectMake(0,
winHeight - viewHeight,
winWidth,
viewHeight);
}
completion:^(BOOL finished) {
// Schedule a timer to call a dismiss method after
// a set period of time, which would probably perform
// an animation off the screen.
dismissTimer = [NSTimer
scheduledTimerWithTimeInterval:3
target:globalMessage
selector:#selector(dismiss)
userInfo:nil
repeats:NO];
}];
Hope this helps.
Is it possible to add a UIView on the staus bar of size (320 x 20)? I don't want to hide the status bar, I only want to add it on top of the status bar.
You can easily accomplish this by creating your own window above the existing status bar.
Just create a simple subclass of UIWindow with the following override of initWithFrame:
#interface ACStatusBarOverlayWindow : UIWindow {
}
#end
#implementation ACStatusBarOverlayWindow
- (id)initWithFrame:(CGRect)frame {
if ((self = [super initWithFrame:frame])) {
// Place the window on the correct level and position
self.windowLevel = UIWindowLevelStatusBar+1.0f;
self.frame = [[UIApplication sharedApplication] statusBarFrame];
// Create an image view with an image to make it look like a status bar.
UIImageView *backgroundImageView = [[UIImageView alloc] initWithFrame:self.frame];
backgroundImageView.image = [UIImage imageNamed:#"statusBarBackground.png"];
[self addSubview:backgroundImageView];
[backgroundImageView release];
// TODO: Insert subviews (labels, imageViews, etc...)
}
return self;
}
#end
You can now, for example in a view controller in your application, create an instance of your new class and make it visible.
overlayWindow = [[ACStatusBarOverlayWindow alloc] initWithFrame:CGRectZero];
overlayWindow.hidden = NO;
Be aware of messing with the window key status by using - (void)makeKeyAndVisible or similar. If you make your main window (the UIWindow in your Application Delegate) loose key status, you will encounter problems with scrolling scrollviews to top when tapping the status bar etc.
I wrote a static library mimicing Reeders status bar overlay, you can find it here: https://github.com/myell0w/MTStatusBarOverlay
It currently supports iPhone and iPad, default and opaque black status bar styles, rotation, 3 different anymation modes, history-tracking and lots of more goodies!
Feel free to use it or send me a Pull Request to enhance it!
All answers looks like working, but in iOS6.0 I have next problems:
1/ Rotations looks bad
2/ Window (status bar is kind of Window) needed rootViewController
I'm using answer from myell0w, but rotate works not good. I've just remove one extra window and using UIWindow from AppDelegate to implement status bar.
May be this solution is ok only for one UIViewController-app...
Ive implemented by the next way:
1/ In ApplicationDelegate:
self.window.windowLevel = UIWindowLevelStatusBar + 1;
self.window.backgroundColor = [UIColor clearColor];
self.window.rootViewController = _journalController;
2/ Create custom UIView and implement all that you need inside:
For an example touchable statusbar:
#interface LoadingStatusBar : UIControl
And easily create and add to your controller view:
_loadingBar = [[LoadingStatusBar alloc] initWithFrame:topFrame];
[self addSubview:_loadingBar];
3/ Some magic when add your controller view (in initWithFrame:)
CGRect mainFrame = self.bounds;
mainFrame.origin.y = 20;
self.bounds = mainFrame;
Your controller view will has 2 views - content view and status bar view. You can show status bar, or hide it when you want.
Frame of content view will be:
_contentView.frame = CGRectMake(0, 20, self.bounds.size.width, self.bounds.size.height);
4/ And one last magic here :)
To detect touches in non touchable area I've used:
-(id)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
if (point.y < 20) return _loadingBar;
return [super hitTest:point withEvent:event];
}
For now it works fine on iPad/iPhone and all iOS's from 4 to 6.
Just to dismiss the "You cannot do this comments"...
I don't know how but I know it is doable. The Feed reader app called Reeder does that.
As you can see from the screenshot, Reeder puts a small dot on the top right of the screen. When you tap it. The bar will fill the whole statusbar until you tap it again to make it small.
First of all, a big thank you to #Martin Alléus for providing the code for this implementation.
I'm just posting for a problem that I faced and the solution I used, as I believe others might experience the same issue.
If the App is started while an call is in place, the status bar height will be 40 pixels and this means that the custom status bar will be initialized with that height.
But if the call is ended while you are still in the app, the status bar height will remain still 40 pixels and it will look weird.
So the solution is simple: I've used the Notification center to subscribe to the status bar frame change delegate of the app and adjust the frame:
- (void)application:(UIApplication *)application didChangeStatusBarFrame:(CGRect)oldStatusBarFrame {
//an in call toggle was done
//fire notification
[[NSNotificationCenter defaultCenter] postNotificationName:kStatusBarChangedNotification object:[NSValue valueWithCGRect:oldStatusBarFrame]];
}
And in the ACStatusBarOverlayWindow we subscribe to the notification:
-(id)initWithFrame:(CGRect)frame
{
if ((self = [super initWithFrame:frame]))
{
// Place the window on the correct level & position
self.windowLevel = UIWindowLevelStatusBar + 1.0f;
self.frame = [UIApplication sharedApplication].statusBarFrame;
self.backgroundColor = [UIColor blackColor];
//add notification observer for in call status bar toggling
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(statusBarChanged:) name:kStatusBarChangedNotification object:nil];
}
return self;
}
and our code to adjust the frame:
- (void)statusBarChanged:(NSNotification*)notification {
//adjust frame...
self.frame = [UIApplication sharedApplication].statusBarFrame;
//you should adjust also the other controls you added here
}
The kStatusBarChangedNotification is just a constant I've used for easy referrence, you can simply replace it with a string, or declare the constant globally.
I'm testing iAds in XCode 4.
Everything works fine, until the first time a bannerView:didFailToReceiveAdWithError: is received, which I react to by sliding the banner off the screen.
//move the ad back off the screen if an error occurs
- (void)bannerView:(ADBannerView *)banner didFailToReceiveAdWithError:(NSError *)error {
if (self.bannerIsInScreenBounds)
{
[UIView beginAnimations:#"animateAdBannerOff" context:NULL];
// move the banner view off the screen.
banner.frame = CGRectOffset(banner.frame, 320, 0);
[UIView commitAnimations];
}
}
After that, no more bannerViewDidLoadAd: messages are sent to the ADBannerViewDelegate. I'm logging that method right at the top, it's not being called any more.
I'm not releasing the banner or anything, and the ADBannerViewDelegate class is still there and doing other stuff.
What could be wrong?
Thanks.
Why do you expect it load adverts after an error has happened - I think this is the correct behavior.
Looking at the comments it show that the error is "The operation couldn’t be completed. Ad inventory unavailable".
How do you expect it to give you adverts if it can't find any adverts to give ;)
OK, not an ideal solution but here's what I ended up doing.
Whenever I get a didFailToReceiveAdWithError, I wait 10 seconds (to avoid spamming with failures) then recreate the banner.
-(void)replaceAdView {
UIView *adViewSuperview = [adView superview];
[adView removeFromSuperview];
[adView release];
//starting off the screen again
adView = [[NSClassFromString(#"ADBannerView") alloc] initWithFrame:CGRectMake(320, 382, 320, 50)];
adView.delegate = self;
if (adViewSuperview) {
[adViewSuperview addSubview:adView];
}
self.bannerIsInScreenBounds = NO;
}
As my comment at how to implement AdBannerview and ADBannerview delegate, running iphone app in ipad simulator I got didFailToReceiveAdWithError immediately on setting the ADBannerView delegate, and never another delegate call. Running it on the iphone simulator (or changing the app target to universal) the delegate only got called after adding ADBannerView as a subview, and then delegate calls every 30 secs after that.
I've coded a "generic" ads management class for all my applications and i have an issue. This class can add an ads view to any view of my application, randomly; in order to do so, my idea is to resize the frame of my current view to reduce its height (let's say 50 pixels less) and add my ads view in the free space i created. This way, i don't have to bother modifying my views for ads integrations, everything is done automatically. It's working well but my ads aren't responding to touch events. I guess it's because this ads view is "outside" the frame of my controller.
It is possible to reduce the height of my view frame and raise its bounds so my ads subview is really part of my view?
Thanks a lot :)
UIView *adView = [[UIView alloc] init];
adView.frame = CGRectMake(0,267,320,100);
adView.backgroundColor = [UIColor grayColor];
adView.tag = 123456;
adView.userInteractionEnabled = YES;
CGRect myFrame = [self.view frame];
myFrame.size.height = myFrame.size.height - 100;
[self.view setFrame:myFrame];
[self.view addSubview:adView];
Here's a picture representing what i would like to do :
http://i49.tinypic.com/2iw7lz4.jpg
This is not an answer but I do not have option to post a comment to your question.
Can you please post the code you have in your touchesBegan method?
I think there can be the problem
Regards
Alejandra