iAd frame returning wrong height on iPhone - ios

I have an iAd which I am trying to position at the bottom of the screen though when I try to get the height of the ad so that I can put it at the bottom. This error only occurs when I enter the screen in a landscape orientation as the ad is taller in the portrait orientation and only on the iPhone simulator as on an ipad the ads are the same height.
The method I am using to put the add at the bottom is by setting the y value of the ad frame to the height of the view minus the height of the ad.
Here is the code that I am currently using:
- (void)viewWillAppear:(BOOL)animated
{
CGRect adFrame = banner.frame;
adFrame.origin.y = screenHeight - banner.frame.size.height;
adFrame.size.width = screenWidth;
banner.frame = adFrame;
[banner setAutoresizingMask:UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleWidth];
}
- (void)viewDidLoad
{
[super viewDidLoad];
banner.frame = CGRectZero;
}
Any help would be much appreciated.

I would take a look at Apple's sample code
for integrating iAD exactly how you describe, particularly in ContainerBanner/ContainerBanner/BannerViewController.m. What you are looking for is ADBannerView's - (CGSize)sizeThatFits:(CGSize)size.
CGRect adRect = CGRectZero;
CGRect contentFrame = self.view.bounds;
adRect.size = [banner sizeThatFits:contentFrame.size];
adRect.origin.y = CGRectGetHeight(contentFrame) - CGRectGetHeight(adRect);
banner.frame = adRect;

Related

iOS 13 UITabBar RePosition to Top

I have followed this answer to reposition my tabbar to top of the page. It was working perfect until iOS 13 release. In iOS 13 the tabbar is visible on bottom of the screen. Any other workaround should i have to use?
Does anyone faced the same problem?
Update:
Below piece of code i have used in my app:
- (void) viewWillLayoutSubviews {
[super viewWillLayoutSubviews];
[self.tabBar invalidateIntrinsicContentSize];
// Just a quick fix for making this to happen for iOS versions between 11.0 to 11.1
// Updating the frame in Main queue.
dispatch_async(dispatch_get_main_queue(), ^{
[self changeTabBarPosition];
});
// Set the translucent property to NO then back to YES to
// force the UITabBar to reblur, otherwise part of the
// new frame will be completely transparent if we rotate
// from a landscape orientation to a portrait orientation.
self.tabBar.translucent = NO;
self.tabBar.translucent = YES;
}
- (void)changeTabBarPosition {
CGFloat tabSize = 44.0;
UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
if (UIInterfaceOrientationIsLandscape(orientation)) {
tabSize = 32.0;
}
CGRect tabFrame = self.tabBar.frame;
tabFrame.size.height = tabSize;
tabFrame.origin.y = [UIApplication sharedApplication].statusBarFrame.size.height;
self.tabBar.frame = tabFrame;
}
I found the solution with the help of #Thanh Vu mentioned in his/her answer. Below piece of code fixed my issue.
- (void) viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
[self.tabBar invalidateIntrinsicContentSize];
CGRect tabFrame = self.tabBar.frame;
tabFrame.size.height = 44.0;
tabFrame.origin.y = 0;
self.tabBar.frame = tabFrame;
// Set the translucent property to NO then back to YES to
// force the UITabBar to reblur, otherwise part of the
// new frame will be completely transparent if we rotate
// from a landscape orientation to a portrait orientation.
self.tabBar.translucent = NO;
self.tabBar.translucent = YES;
}
I just test bellow code on iOS 13. It still work.
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
self.tabBarController.tabBar.frame = CGRectMake(0, 0, self.view.frame.size.width, self.tabBarController.tabBar.frame.size.height);
}
I get this solution after a lot struggle too, with Swift5 + IOS13.2Sdk. Follow this answer.
class MyUITabBarController:UITabBarController{
override func viewDidLayoutSubviews(){
super.viewDidLayoutSubviews()
var frame = self.tabBar.frame
frame.origin.y = 0
self.tabBar.frame = frame
}
}

Objective C - Cannot zoom UIImageView that is embedded into UIScrollView

I'm a new kid on the block here. Nice to meet you all.
I'm trying to implement Ray Wenderlich's zooming of an UIScrollView that was described here:
http://www.raywenderlich.com/10518/how-to-use-uiscrollview-to-scroll-and-zoom-content
But it seemed like it didn't work for me. What I would like to do is:
Create the UIImageView from a nib.
Add UIImageView to the UIScrollView.
Zoom it in from the center of the image with the scale of 2 at the start of the view if the app is executed from an iPad.
Here's my code:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
//Hide the status bar
[[UIApplication sharedApplication] setStatusBarHidden:YES];
//------------------------------
//Initialize the image view of the home screen
_mapView = (TM_MapView *)[[[NSBundle mainBundle]loadNibNamed:#"MapView" owner:self options:nil]objectAtIndex:0];
// set the content size to be the size our our whole frame
mapScrollView.contentSize = _mapView.imageView.image.size;
[mapScrollView setScrollEnabled:YES];
//set the selector for the buttons in the map view
[self setButtonsSelector];
// now add our scroll view to the main view
[mapScrollView addSubview:_mapView];
//------------------------------
NSLog(#"_mapView.imageView.frame: %#", NSStringFromCGRect( _mapView.imageView.frame));
NSLog(#"_mapView.imageView.image.size: %#", NSStringFromCGSize( _mapView.imageView.image.size));
NSLog(#"mapScrollView.contentSize: %#", NSStringFromCGSize( mapScrollView.contentSize));
}
-(void)viewWillAppear:(BOOL)animated
{
mapScrollView.minimumZoomScale = 1.0f;
mapScrollView.maximumZoomScale = 2.5f;
mapScrollView.zoomScale = 1.0f;
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
{
[self zoomOnStart];
}
}
-(void)zoomOnStart
{
NSLog(#"Zooming on start");
CGPoint zoomPoint = CGPointMake(512.0f, 384.0f);
CGFloat newZoomScale = 2.0f;
CGSize scrollViewSize = self.mapScrollView.bounds.size;
CGFloat w = scrollViewSize.width / newZoomScale;
CGFloat h = scrollViewSize.height / newZoomScale;
CGFloat x = zoomPoint.x - (w/2.0f);
CGFloat y = zoomPoint.y - (h/2.0f);
CGRect rectToZoomTo = CGRectMake(x, y, w, h);
//CGRect rectToZoomTo = CGRectMake(300, 300, 200, 100);
NSLog(#"rectToZoomTo: %#", NSStringFromCGRect(rectToZoomTo));
[self.mapScrollView zoomToRect:rectToZoomTo animated:YES];
}
#pragma mark - Delegates
-(UIView*)viewForZoomingInScrollView:(UIScrollView*)scrollView
{
NSLog(#"Scroll View viewForZoomingInScrollView");
return _mapView;
}
-(void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(CGFloat)scale
{
NSLog(#"Scroll View End Zooming!");
}
-(void)scrollViewDidZoom:(UIScrollView *)scrollView
{
NSLog(#"Scroll View Zoom changed to: %f", scrollView.zoomScale);
}
As you can see, I've logged some of the frames and delegates to see the input for the zooming and to see whether or not we are zooming. Here's the console logs:
2014-10-09 17:24:18.507 TrueMuzeiOS[13268:60b] _mapView.imageView.frame: {{0, 0}, {1024, 768}}
2014-10-09 17:24:18.511 TrueMuzeiOS[13268:60b] _mapView.imageView.image.size: {1024, 768}
2014-10-09 17:24:18.513 TrueMuzeiOS[13268:60b] mapScrollView.contentSize: {1024, 768}
2014-10-09 17:24:18.519 TrueMuzeiOS[13268:60b] Zooming on start
2014-10-09 17:24:18.521 TrueMuzeiOS[13268:60b] rectToZoomTo: {{320, 128}, {384, 512}}
As you can see, the logs inside viewForZoomingInScrollView:, scrollViewDidEndZooming:withView:atScale:, and scrollViewDidZoom: didn't get called, meaning we are not zooming at all (CMIIW). I've added the UIScrollViewDelegate so it should've worked.
So, can you guys help me here? I've followed the steps correctly, IMHO. So I'm lost now. Thanks a lot in advance.
do you set the delegate property of the UIScrollView?
I donĀ“t see this on the code you published although you could have done it on Interface Builder.
If this the case, simply this would make your methods get called:
mapScrollView.delegate = self;
Check the UIScrollView documentation on the delegate property section to more information.
https://developer.apple.com/library/ios/documentation/uikit/reference/uiscrollview_class/index.html#//apple_ref/occ/instp/UIScrollView/delegate

How to bind a vertical constraint programatically to a view?

I am reading into implementing iAd into my application.
Apple has provided a basic banner sample code.
I have a problem porting the solution to my UITableViewController. Since I don't use any xib file in order to bind the introduced NSLayoutConstraint to my tableview:
#property (nonatomic, strong) IBOutlet NSLayoutConstraint *bottomConstraint;
If this isn't bound properly, I wont be able to shrink the view according to the ad's size:
- (void)layoutAnimated:(BOOL)animated
{
CGRect contentFrame = self.view.bounds;
// all we need to do is ask the banner for a size that fits into the layout area we are using
CGSize sizeForBanner = [_bannerView sizeThatFits:contentFrame.size];
// compute the ad banner frame
CGRect bannerFrame = _bannerView.frame;
if (_bannerView.bannerLoaded) {
// bring the ad into view
contentFrame.size.height -= sizeForBanner.height; // shrink down content frame to fit the banner below it
bannerFrame.origin.y = contentFrame.size.height;
bannerFrame.size.height = sizeForBanner.height;
bannerFrame.size.width = sizeForBanner.width;
// if the ad is available and loaded, shrink down the content frame to fit the banner below it,
// we do this by modifying the vertical bottom constraint constant to equal the banner's height
//
NSLayoutConstraint *verticalBottomConstraint = self.bottomConstraint;
verticalBottomConstraint.constant = sizeForBanner.height;
[self.view layoutSubviews];
} else {
// hide the banner off screen further off the bottom
bannerFrame.origin.y = contentFrame.size.height;
}
[UIView animateWithDuration:animated ? 0.25 : 0.0 animations:^{
_contentView.frame = contentFrame;
[_contentView layoutIfNeeded];
_bannerView.frame = bannerFrame;
}];
}
The question is how do I bind programatically the bottomConstraint to the vertical bottom of my view in order to shrink it afterwards?

How to get zooming, panning, and rotating to work for image in scrollview

So I want to display an image that a user can zoom, pan, and rotate.
I want the image to fit to the screen (i.e. aspect ratio is maintained, the entire image is visible on the screen, and 2 opposite edges of the image are touching the edge of the screen).
When the screen rotates I would like the behaviour to be maintained.
I've played around with quite a few settings but can't get the perfect behaviour.
What I currently have:
A UIScrollView with a UIImageView as its child.
- (void)viewDidLoad
{
[super viewDidLoad];
self.imageView.image = [UIImage imageNamed:#"test2.jpg"];
self.imageView.contentMode = UIViewContentModeScaleAspectFit;
self.imageView.clipsToBounds = YES;
}
- (void) didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
CGFloat width = self.scrollView.frame.size.width;
CGFloat height = self.scrollView.frame.size.height;
UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
if (UIInterfaceOrientationIsLandscape(orientation))
{
NSLog(#"Screen rotated to landscape orientation.");
self.scrollView.frame = CGRectMake(0, 0, height, width);
[self.scrollView setZoomScale:1 animated:YES];
}
else
{
NSLog(#"Screen rotated to portrait orientation.");
self.scrollView.frame = CGRectMake(0, 0, width, height);
[self.scrollView setZoomScale:1 animated:YES];
}
}
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
return self.imageView;
}
The behaviour of this current code works quite well for me when in portrait mode. The image fits to the screen and is centred. The behaviour for landscape just doesn't work the way I want it to.
I don't really understand why [self.scrollView setZoomScale:1 animated:YES]; works at all. It seems to work for images of any size. Maybe I don't quite understand what the zoomScale does/is?
I just put a a repo on GitHub that does just that. It is in Swift but it should do
PhotoSlideShow-Swift

Rotate UIImageView inside UIScrollView issue

I have to implement the rotate works like the photo app. Having the UIImageView inside a UIScrollView. and when device rotate, I want the image to rotate to landscape like Photo's. If the image is landscape-one, then it will fill the whole UIScrollView's width with the rotation animation. When the following code
[UIView animateWithDuration:0.36
animations:^(void){
[_imageView setTransform:CGAffineTransformMakeRotation(M_PI*90/180)];
_imageView.frame = CGRectMake(0, 0, 480, 320); //set the frame after the rotate
self.contentSize = CGSizeMake(480, 320); //set the content-size of the scrollview
}
completion:^(BOOL complete){
}];
But this does not work. rotate happens, but the position of the _imageView is not correct, or the image did not fill the width. Even I change the order frame and content-size before transform, still not correct.
What will be the correct approach to have this?
The WWDC 2010 Video: Designing Apps with Scrolls Views shows you exactly how to do this.
The correct answer, in my opinion, is to not animate the rotation yourself at all.
If you work according to the latest iOS 6 guidelines, then you just rearrange your views in the ViewController its layoutSubviews() method.
The source code that #CoDEFRo refers to is similar to the following, but here I've put it into the UIScrollView's delegate method scrollViewDidScroll:.
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
CGSize boundsSize = scrollView.bounds.size;
CGRect frameToCenter = self.imageView.frame;
if (frameToCenter.size.width < boundsSize.width)
frameToCenter.origin.x = (boundsSize.width - frameToCenter.size.width) / 2;
else
frameToCenter.origin.x = 0;
if (frameToCenter.size.height < boundsSize.height)
frameToCenter.origin.y = (boundsSize.height - frameToCenter.size.height) / 2;
else
frameToCenter.origin.y = 0;
self.imageView.frame = frameToCenter;
}

Resources