I have a problem that I can't find the errors as titled. And I have searched so many times that similar or related questions, that can't solve.
I am building an App that can change the Image of A UIImageView with a button. everything is fine until I use another button to change the size of imageView (with UIView animateWithDuration + CGAffineTransformMakeRotation), then use that button for changing image.
strange output with no errors happen! the imageview size change back and the position move to other places.
Sorry about my poor english.
with graphics,
I have this view [no size changed view][1]
I use animateWithDuration + CGAffineTransformMakeRotation change the size & orientations, to make the view fullscreen like this [size changed view][2]
Then I change this image of this view by imageView.image = newImage(UIImage)
However, the view change to this [strange view][3] either the size or position are changed!
But, there's nothing if I change the image at Step 1 (no orientation & set frame)
Please help, I can't find the errors because there only one place that change the size&orientation of the view.
I wonder there is something UIImage would affect the UIImageView. But I can't find the answer.
(the photos are down below)
this is the code to rotate the image ivew
if there is already set image, after rotation, the image is also fine
But problem get after rotation, and then set the new image to the image view
-(void)transformToDirection:(NSInteger)dir
{
rotation = M_PI_2;
CGFloat screenW = [[UIScreen mainScreen] bounds].size.width;
CGFloat screenH = [[UIScreen mainScreen] bounds].size.height;
CGRect portraitFrame = _imageVIew.frame;
CGRect landscapeFrame = CGRectMake(0, 0, screenW, screenH);
switch (dir) {
case UIInterfaceOrientationPortrait:
{
[UIView animateWithDuration:1 delay:0 options:0 animations:^{
_imageVIew.transform = CGAffineTransformMakeRotation(3/4 * rotation);
[_imageVIew setFrame:portraitFrame];
}completion:^(BOOL finished){
isFullScreen = false;
}];
}
break;
case UIInterfaceOrientationLandscapeRight:
{
[UIView animateWithDuration:1 delay:0 options:0 animations:^{
_imageVIew.transform = CGAffineTransformMakeRotation(rotation);
[_imageVIew setFrame:landscapeFrame];
}completion:^(BOOL finished){
isFullScreen = true;
}];
}
break;
case UIInterfaceOrientationLandscapeLeft:
{
[UIView animateWithDuration:TIME_ANIMATE_FULLSCREEN delay:0 options:0 animations:^{
_imageVIew.transform = CGAffineTransformMakeRotation(-rotation);
[_imageVIew setFrame:landscapeFrame];
}completion:^(BOOL finished){
isFullScreen = true;
}];
}
break;
default:
break;
}
}
this is the image view set image (all new images are the same size), which is called by a button.
dispatch_async(dispatch_get_main_queue(), ^{
if (loadedimage) {
self.imageVIew.image = loadedimage;
} else {
self.PBMainImageVIew.image = nil;
dlog(#"request image failed");
}
});
Related
I have iAds working almost perfectly using a modified version of UITabBarController-iAds. The only issue I have is on the very first load of an advert my view gets covered. Once the ad refreshes after 30 seconds the view resizes just fine.
I'm using the following code:
- (void)layoutBanner
{
float height = 0.0;
ADBannerView *_banner = (ADBannerView *)[self.view viewWithTag:12];
CGRect bounds = [UIScreen mainScreen].bounds;
if (UIInterfaceOrientationIsPortrait(self.interfaceOrientation)) {
_banner.currentContentSizeIdentifier = ADBannerContentSizeIdentifierPortrait;
} else {
_banner.currentContentSizeIdentifier = ADBannerContentSizeIdentifierLandscape;
}
//When compiling against iOS 8 SDK this needs to be height, regardless of the actual device orientation
height = bounds.size.height;
CGSize bannerSize = [ADBannerView sizeFromBannerContentSizeIdentifier:_banner.currentContentSizeIdentifier];
//Get content view
UIView *_contentView = self.selectedViewController.view;
CGRect contentFrame = _contentView.frame;
CGRect bannerFrame = _banner.frame;
if (_banner.isBannerLoaded) {
if (iOS7) {
contentFrame.size.height = height - bannerSize.height;
bannerFrame.origin.y = contentFrame.size.height - self.tabBar.frame.size.height;
} else {
contentFrame.size.height = height - self.tabBar.frame.size.height - bannerSize.height;
bannerFrame.origin.y = contentFrame.size.height;
}
} else {
if (iOS7) {
contentFrame.size.height = height;
bannerFrame.origin.y = bounds.size.height;
} else {
contentFrame.size.height = height - self.tabBar.frame.size.height;
bannerFrame.origin.y = bounds.size.height;
}
}
[UIView animateWithDuration:0.25 animations:^{
_banner.frame = bannerFrame;
_contentView.frame = contentFrame;
} completion:^(BOOL finished) {
[self.view bringSubviewToFront:_banner];
}];
}
- (void)bannerViewDidLoadAd:(ADBannerView *)banner
{
NSLog(#"Did load");
[self layoutBanner];
}
Any ideas?
I managed to fix this issue by playing around with the animation block. I moved the content view line and it resolved the issue
[UIView animateWithDuration:0.25 animations:^{
_banner.frame = bannerFrame;
} completion:^(BOOL finished) {
_contentView.frame = contentFrame;
[self.view bringSubviewToFront:_banner];
}];
I'm not 100% sure, but I suppose the problem is related to:
[self.view bringSubviewToFront:_banner];
The whole animation:
[UIView animateWithDuration:0.25 animations:^{
_banner.frame = bannerFrame;
_contentView.frame = contentFrame;
} completion:^(BOOL finished) {
[self.view bringSubviewToFront:_banner];
}];
is a little strange, because at the completion block you are bringing the banner view to front, so I can suppose that before animation did start - the banner was covered by some other view or views - what is the reason of frame animation if banner view is covered - thus cannot be seen while animation is in progress?
Of course the issue applies only for the first run.
as of iOs8 [[UIScreen mainScreen]bounds] has changed.. previously it would always return portrait (where H > W ) values, regardless of interfaceOrientation, but it now appears to respect interface orientation... (which is not a bad thing, unless you're taking previous behaviour for granted)
Why don't you try CGRectGetMinY(CGRect aRect) ..
eg. (Im assuming from your code the banner goes along the screen bottom, and your TAbBar across the top. (which I think is weird..) )
//once you have calculated bannerFrame
contentFrame.size.height = ( CGRectGetMinY(bannerFrame) - CGRectGetMinY (contentView.frame) );
contentFrame.origin.y = CGRectGetMaxY(self.tabbar.frame);
Do you have any constraints / resizingMasks set? when you load a second ad the view controller's view has already been resized to fit an ad, presumably the first ad is the one trying to change things..
Hi maybe this is a duplicated question and I just don't know the keyword to describe my question, if this is the case please point out.
I'm currently implementing a transition between two view, as the second view shows, it should looked like it's zoomed into the screen from outside, kind of fall on the screen. My idea is to zoom the second view 9 * original size and place the origin to -original_width, -original_height, and set alpha to 0. At the end I set alpha to 1 and show the original size.
so the following code is not working, the subviews are not resized. Could anyone tell me what I miss here or better show me some API which do the task?
[toVC.view setFrame:CGRectMake(0-fromVC.view.frame.size.width, 0-screenRect.size.height, fromVC.view.frame.size.width*3, fromVC.view.frame.size.height*3)];
for (UIView* view in toVC.view.subviews) {
CGRect frame = view.frame;
[view setFrame:CGRectMake(frame.origin.x*3, frame.origin.y*3, frame.size.width*3, frame.size.height*3)];
}
[toVC.view layoutIfNeeded];
[toVC.view setAlpha:0.1];
[UIView animateWithDuration:duration*5
animations:^{
[toVC.view setAlpha:1.0];
[toVC.view setFrame:CGRectMake(0, 0, fromVC.view.frame.size.width, fromVC.view.frame.size.height)];
for (UIView* view in toVC.view.subviews) {
CGRect frame = view.frame;
[view setFrame:CGRectMake(frame.origin.x/3, frame.origin.y/3, frame.size.width/3, frame.size.height/3)];
}
}
completion:^(BOOL finished) {
[transitionContext completeTransition:YES];
}];
You could just set the view transform prior and after the transition:
CGAffineTransform scaleTransform = CGAffineTransformIdentity;
scaleTransform = CGAffineTransformScale(rotationTransform, 9., 9.);
view.transform = scaleTransform;
view.alpha = 0;
[UIView animateWithDuration:duration*5
animations:^{
view.transform = CGAffineTransformIdentity;
view.alpha = 1.;
}
}
completion:^(BOOL finished) {
}];
I have tried to scale a UIImageView that is running an image sequence using imageView.animationImages and calling [self.imageView startAnimating];
- (void) updateViewSizeWithScale:(float) scale
{
// calculate the new size based on the scale
int newSize = originalSize * scale;
[UIView animateWithDuration:0.4 delay:0.0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
self.imageView.frame = CGRectMake(self.imageView.frame.origin.x, self.imageView.frame.origin.y, newSize, newSize);
} completion:^(BOOL finished) {
}];
This does not scale the UIImageView as while the animating images are running. I have tried to set the self.frame in the animation block (self is a UIView subclass) but it does not scale the imageview.
What would be the best way to run a sequence of images inside a container view and scale the container so that the images scale while the sequence is running?
Should I use layers or a lower level API?
I had the same problem yesterday, and it worked after setting two things:
self.imageView.clipsToBounds = YES;
self.imageView.contentMode = UIViewContentModeScaleAspectFit;
Hope it works for you.
Consider using CGAffine Transformation to do the job:
[UIView animateWithDuration:0.4 delay:0.0 UIViewAnimationOptionCurveEaseInOut animations:^{
CGAffineTransform newScale = CGAffineTransformMakeScale(2.0, 2.0);
CGAffineTransform newTranslate = CGAffineTransformMakeTranslation(10.0, 10.0);
self.myImageView.transform = CGAffineTransformConcat(newScale, newTranslate);
}
completion:^(BOOL finished) {
}
];
The following code works. It animates all those components nicely
CGRect logoRect = self.logoImageView.frame;
CGRect loginBackgroundRect = self.loginControlsBkImageView.frame;
CGRect loginButtonRect = self.loginButton.frame;
CGRect tableViewRect = self.tableView.frame;
CGRect forgotPasswordRect = self.forgotButton.frame;
CGRect signupButtonRect = self.signUpButton.frame;
if (!iPhone) {
// ipad keyboard-on-screen re-layout
logoRect.origin.y-= 60;
loginBackgroundRect.origin.y-= 110;
loginButtonRect.origin.y-=110;
tableViewRect.origin.y-=110;
forgotPasswordRect.origin.y-=110;
signupButtonRect.origin.y-=200;
}
else {
// iphone keyboard-on-screen re-layout
if (portrait) {
logoRect.origin.y-=17;
logoRect.origin.x-=50;
loginBackgroundRect.origin.y-= 70;
loginButtonRect.origin.y-=70;
tableViewRect.origin.y-=70;
forgotPasswordRect.origin.y-=70;
//signupButtonRect.origin.y+=200; // get off screen!
} else {
logoRect.origin.y-= 30;
loginBackgroundRect.origin.y-= 25;
loginButtonRect.origin.y-=25;
tableViewRect.origin.y-=25;
}
}
[UIView animateWithDuration:0.2f
delay:0.0f
options:UIViewAnimationOptionCurveEaseIn
animations:^(void) {
self.logoImageView.frame = logoRect;
self.loginControlsBkImageView.frame = loginBackgroundRect;
self.loginButton.frame = loginButtonRect;
self.tableView.frame = tableViewRect;
self.forgotButton.frame = forgotPasswordRect;
self.signUpButton.frame = signupButtonRect;
}
completion:NULL];
Take the following code and add one line (see below) to animate the WIDTH of the logoImageView... and puff... only the logoImageView animation works - the rest simply doesn't move. as if the frame size animation causes everything else not to animate if in the same animation block.
if (portrait) {
logoRect.origin.y-=17;
logoRect.origin.x-=50;
loginBackgroundRect.origin.y-= 70;
loginButtonRect.origin.y-=70;
tableViewRect.origin.y-=70;
forgotPasswordRect.origin.y-=70;
//signupButtonRect.origin.y+=200; // get off screen!
} else {
logoRect.origin.y-= 30;
logoRect.size.width-= 30; // <------- LINE BEING ADDED HERE
loginBackgroundRect.origin.y-= 25;
loginButtonRect.origin.y-=25;
tableViewRect.origin.y-=25;
}
I'm at a loss here. Does anyone know what's going on?
Try to change whole frame, not just width. It should work.
Put these lines before commiting animation (not in block):
self.logoImageView.frame = logoRect;
etc.
And instead of using animate method try to use commit animations this way:
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.75];
// Here some more animation settings
// Here your animations
[UIView commitAnimations];
I have a heads up display (HUD) that I'm trying to get to properly rotate with the view. I created a function orientationWillChange that is supposed to rotate the view and that works fine, just requires a little more programming on the side of the view controller implementing it.
My main problem is that it rotates when it closes. It does some other transformations when it closes (shrinking/fading it so it disappears), but it seems to be rotating it back to "normal".
I don't want to rotate the view another 90 degrees, I just want to make sure it stays in the rotation it is at. How do I do that?
My closing function is as follows:
- (void)close {
_windowIsShowing = NO;
[UIView animateWithDuration:0.125 animations:^{
hudView.transform = CGAffineTransformMakeRotation(rotationDegrees * M_PI / 180);
hudView.transform = CGAffineTransformMakeScale(1.1, 1.1);
} completion:^(BOOL finished) {
[UIView animateWithDuration:0.15 animations:^{
hudView.transform = CGAffineTransformMakeScale(0.4, 0.4);
hudView.alpha = 0.0;
backgroundColorView.alpha = 0.0;
} completion:^(BOOL finished) {
[hudWindow resignKeyWindow];
[self release];
}];
}];
}
(fyi this is based on CloudApp's HUD)