I subclassed a UIImageView. When it is double tapped, it will enlarge itself by 40%. I also have a UILabel that i place in the custom UIImageView and would like it to enlarge by 40%.
i can't seem to get it to animate correctly.
-(void)enlargeImage
{
CGPoint pointCenter = self.center;
CGPoint labelCenter = self.displayNameLabel.center;
[UIView animateWithDuration:1
delay:0
options:(UIViewAnimationOptionAllowUserInteraction)
animations:^{
self.frame = CGRectMake(self.frame.origin.x,
self.frame.origin.y,
self.frame.size.width * (1 + self.sizeMultiplier),
self.frame.size.height * (1 + self.sizeMultiplier));
// Commented out after setting the autoresizeMask on the label
/*
self.displayNameLabel.frame = CGRectMake(self.displayNameLabel.frame.origin.x,
self.displayNameLabel.frame.origin.y,
self.displayNameLabel.frame.size.width * (1 + self.sizeMultiplier),
self.displayNameLabel.frame.size.height * (1 + self.sizeMultiplier));
*/
self.layer.shadowOpacity = 1;
}
completion:^(BOOL finished)
{
[self callDelegateSelect];
}];
self.center = pointCenter;
//self.displayNameLabel.center = labelCenter;
//self.displayNameLabel.center = CGPointMake((self.frame.size.width / 2), (self.frame.size.height / 2));
self.isSelected = TRUE;
}
-(void)shrinkImageWithZoomScale:(float)zoomScale
{
CGPoint pointCenter = self.center;
CGPoint labelCenter = self.displayNameLabel.center;
[UIView animateWithDuration:1
delay:0
options:(UIViewAnimationOptionAllowUserInteraction)
animations:^{
self.frame = CGRectMake(self.frame.origin.x,
self.frame.origin.y,
(self.originalHeight / zoomScale),
(self.originalHeight / zoomScale));
// Commented out after setting the autoresizeMask on the label
/*
self.displayNameLabel.frame = CGRectMake(self.displayNameLabel.frame.origin.x,
self.displayNameLabel.frame.origin.y,
((self.originalLableHeight) / zoomScale),
((self.originalLableHeight) / zoomScale));
*/
self.layer.shadowOpacity = 0;
}
completion:^(BOOL finished)
{
[self callDelegateDeselect];
}];
self.center = pointCenter;
//self.displayNameLabel.center = labelCenter;
//self.displayNameLabel.center = CGPointMake((self.frame.size.width / 2), (self.frame.size.height / 2));
self.isSelected = FALSE;
}
the custom UIImageView animates exactly how i want it too, but the UILabel misbehaves.
unselected (UILabel's background is set to orange):
selected:
i'm guessing since the UIImageView's point reference is changing, its messing up the points i'm telling the UILabel to be?
EDIT:
the custom UIImageView's:
self.autoresizesSubviews = TRUE;
the subview UILabel:
self.displayNameLabel.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
this solves the sizing issue, but it does not grow from the center; when growing, it shifts right and animates left to the center. when shrinking, it shifts left and animates right to the center. I also commented out setting the label's frame in the animation code.
If the UILabel is a subview of the UIImageView, you could try to set the autoresizing options of the UILabel so that it resizes automatically when its superview does.
Also, make sure the autoresizesSubviews property of the UIImageView is set to YES (which is the default by the way).
Related
In my application i have webview and some items above the webview.when i scroll the webview i want to scroll these items also.i tried so many thing it is not possible in scrollViewDidScroll.i need something else.I tried these codes but it is not working efficiently..
- (void)scrollViewDidScroll:(UIScrollView *)sender {
CGRect webViewFrame = self.contentWebView.frame;
webViewFrame.origin.y -= 3;
CGRect imageViewFrame = self.featuredImageView.frame;
imageViewFrame.origin.y -= 3;
CGRect overlayFrame = self.overlayView.frame;
overlayFrame.origin.y -= 3;
[UIView animateWithDuration:0.001 animations:^{
self.contentWebView.frame = webViewFrame;
self.featuredImageView.frame = imageViewFrame;
self.overlayView.frame = overlayFrame;
}completion:^(BOOL finished) {
CGPoint offset2 = sender.contentOffset;
offset2.y = 0;
sender.contentOffset = offset2;
}];
}
Try to add subView (Other items) to your webView.scrollView ;)
Example: [myWebView.scrollView addSubView: myItem];
I am using storyboard and have implemented a custom UIVIew which draws concentric circles. I am using constraints to keep the UIView horizontally centric and this is working fine when I rotate my device. But my shape layers are not adjust properly on rotation. I tried printing the self.frame and when I launch the app being in landscape mode, the UIView frame it assumes is that of Portrait mode though my UIView is rotate properly (checked by keeping background color to black). I am calling setNeedsDisplay in handleViewRotation below which brings the view to correct mode if I rotate the device. But once it is in that view and I go out of the current screen and rotate the device and come back then UIView gets adjusted but layers remains on the same place (with previous orientation assumption).
Any idea how to fix this and adjust layers.
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(didRotate:) name:UIDeviceOrientationDidChangeNotification object:nil];
- (void)didRotate:(NSNotification *)iNotification {
[self.myView handleViewRotation];
}
- (CAShapeLayer *)circleForRadius:(CGFloat)iRadius withColor:(CGColorRef)iColor andDashPattern:(BOOL)isDashPattern {
CAShapeLayer *aSignalcircle = [CAShapeLayer layer];
aSignalcircle.path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(self.frame.size.width / 2.0, 0.0, 2.0 * iRadius, 2.0 * iRadius) cornerRadius:iRadius].CGPath;
aSignalcircle.position = CGPointMake(0.0 - iRadius, 0.0 - iRadius);
aSignalcircle.fillColor = [UIColor clearColor].CGColor;
aSignalcircle.strokeColor = iColor;
aSignalcircle.lineWidth = kPSSignalStrokeWidth;
if (self.enableShadow) {
aSignalcircle.shadowColor = [UIColor blackColor].CGColor;
aSignalcircle.shadowOpacity = 0.5;
aSignalcircle.shadowOffset = CGSizeMake(0, 0.25);
aSignalcircle.shadowRadius = 0.5;
}
if (isDashPattern) {
aSignalcircle.lineDashPattern = #[#1, #1];
}
return aSignalcircle;
}
The issue was that core graphics draws faster than than UI orientation notification. Using next run loop to draw the UI and fading effect makes it look better.
I added below piece of code to make it work:
- (void)viewDidAppear:(BOOL)iAnimated {
[super viewDidAppear:iAnimated];
double delayInSeconds = 0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
[self.myView handleViewRotation];
});
[UIView animateWithDuration:1.0 delay:0.0 options:UIViewAnimationOptionCurveEaseOut animations:^{
self.beaconView.alpha = 1.0;
} completion:nil];
I've got an image editor window. After drag event I minimize my window to miniature in the bottom left corner, after drop on the miniature I return window back. Above the miniature I change cursor to operationNotAllowedCursor.
The problem is: NSWindow does not change the cursor on miniature after the first draggingEntered (after the second and more everything's fine). Moreover, after drop on the miniature NSWindow does not receive any events until a click on any area of it.
Code for minimizing window (in NSWindow subclass):
-(void)minimize
{
const double miniSize = 240;
MSDraggingMiniature *mini = [[MSDraggingMiniature alloc] init];
[mini setMiniImage:[[MSScreenMaker getInstance] makeEditorScreen:(int)[self windowNumber]]];
_mainContentView = self.contentView;
_oldFrame = [self frame];
[self setStyleMask:NSBorderlessWindowMask];
self.contentView = mini;
NSRect drect = [[self screen] frame];
double width, height;
if (self.frame.size.width < self.frame.size.height) {
height = miniSize;
width = self.frame.size.width / self.frame.size.height * miniSize;
} else {
width = miniSize;
height = self.frame.size.height / self.frame.size.width * miniSize;
}
_anima = MSEditorResizeAnimationMinimize;
[self setFrame:NSMakeRect(drect.origin.x + 20, drect.origin.y + 20 , width, height) display:YES animate:YES];
}
-(void)deminimize
{
self.contentView = _mainContentView;
[self setStyleMask:NSTitledWindowMask];
_anima = MSEditorResizeAnimationDeminimize;
[self setFrame:_oldFrame display:YES animate:YES];
[self makeKeyWindow];
[self makeMainWindow];
}
After lots of variants I found the answer. It seems that area, acting like Dragging Source, must be just NSView, not a subclass of NSButton, which I had.
I rewrote my Dragging Source class - now everything works fine.
In my app I have a scrollview and when I press a button it is hidden when I press again it shows up.
I use scrollview.hidden = YES (or NO) to do it.
But I want to do it with an animation. For example, it may disappear from the bottom of the screen by moving and shows up with the same way. How can I do that?
edit:
[UIView beginAnimations:#"myAnimation" context:nil];
CGRect Frame = bottomScroller.frame;
if(Frame.origin.y == 380){
Frame.origin.y = 460;
}else{
Frame.origin.y = 380;
}
bottomScroller.frame = Frame;
[UIView commitAnimations];
This solved my problem...
You may check UIView animations. It's pretty easy. For example to animate translation you may use something like:
[UIView beginAnimations:#"myAnimation" context:nil];
CGRect Frame = yourView.frame;
Frame.origin.y = 0;
yourView.frame = Frame;
[UIView commitAnimations];
Then to move it back:
[UIView beginAnimations:#"myAnimation" context:nil];
CGRect Frame = yourView.frame;
Frame.origin.y = 100;
yourView.frame = Frame;
[UIView commitAnimations];
Changes in frame, alpha and some other parameters will be automatically animated.
You can use animations like so:-
[UIView animateWithDuration:2.0 animations:^{
[scrollview setframe:CGRectMake(xpos, ypos, width, height)];
}];
If you want to slide the scrollview on or off the screen set its y position - the bottom of the view is you want to hide it, the normal y position if you want to show it.
The 2.0 is an animation length, this can be changed to whatever you need it to be!
You can do this by using simple view animations. Here's an example of how you might do this:
// myScrollView is your scroll view
-(void)toggleShow{
CGFloat targetAlpha = myScrollView.alpha == 1 ? 0 : 1;
CGFloat yPosition = targetAlpha == 1 ? 0 : self.view.frame.size.height;
[UIView animateWithDuration:1.0 animations:^{
myScrollView.frame = CGRectMake(myScrollView.frame.origin.x, yPosition, myScrollView.frame.size.width, myScrollView.frame.size.height);
myScrollView.alpha = targetAlpha;
}];
}
targetAlpha will always be the opposite of the current state (1 or 0), and if it's 0 then the y position will be set to the bottom of the parent view. Using the new-school UIView animations API with blocks we can execute these changes to the scroll view over 1 second (in my example).
ScrollView appers from down side of screen with animation. I think this up-animation is what you want.
// ScrollView appearing animation
- (void)ScrollViewUpAnimation
{
// put the scroll view out of screen
CGRect frame = ScrollView.frame;
[self.view addSubview:ScrollView];
ScrollView.frame = CGRectMake(0, 460, frame.size.width, frame.size.height);
// setting for animation
CGPoint fromPt = ScrollView.layer.position;
CGPoint toPt = CGPointMake(fromPt.x, fromPt.y - frame.size.height - 44);
CABasicAnimation* anime =
[CABasicAnimation animationWithKeyPath:#"position"];
anime.duration = 0.2;
anime.fromValue = [NSValue valueWithCGPoint:fromPt];
anime.toValue = [NSValue valueWithCGPoint:toPt];
// change the position of Scroll View when animation start
[ScrollView.layer addAnimation:anime forKey:#"animatePosition"];
ScrollView.layer.position = toPt;
}
The following code is a method I created inside a UIViewController to popup/down a "reader" overlay on top of the controller's own view. The intention is for the reader to begin as transparent, size zero, at a specific point. "Popup" is then animated as increasing in opacity and size, and shifts towards an application frame central position. "Popdown" is subsequently animated as the reverse, shrinking back whilst moving toward a specified location, fading out.
The popup code works exactly as desired. However, the popdown version (i.e. code executed if isPopup == NO) immediately changes the bounds rather than doing so gradually. Thus the popdown animation shows from the beginning a 1 pixel square view moving towards its destination and fading out.
-(void)popupReader:(BOOL)isPopup from:(CGPoint)loc {
CGFloat newAlpha = 0.0f;
CGPoint newCenter = CGPointZero;
CGRect newBounds = CGRectZero;
CGRect appFrame = [UIScreen mainScreen].applicationFrame;
CGSize readerSize = [self viewSize];
if (isPopup) {
newAlpha = 1.0f;
newCenter = CGPointMake(appFrame.origin.x+appFrame.size.width/2,
appFrame.origin.y+appFrame.size.height/2);
newBounds = CGRectMake(0,0,readerSize.width,readerSize.height);
[self.view setAlpha:0.0f];
[self.view setCenter:loc];
[self.view setBounds:CGRectMake(0, 0, 0, 0)];
} else {
newCenter = loc;
newBounds = CGRectMake(0,0,1,1);
}
const CGFloat animDur = 0.3f;
[UIView transitionWithView:self.view
duration:animDur
options:UIViewAnimationOptionTransitionNone|UIViewAnimationOptionCurveEaseOut
animations:^{
self.view.alpha = newAlpha;
self.view.center = newCenter;
self.view.bounds = newBounds;
}
completion:nil];
}
I've already tried animating just the frame, rather than bounds and center, but the result was identical.
Does anyone know why this is happening, and how I can overcome this problem?
Many thanks for your time.
from the docs:
UIViewAnimationOptionTransitionNone -
An option for specifying that no transition should occur.
try one of:
UIViewAnimationOptionTransitionFlipFromLeft
UIViewAnimationOptionTransitionFlipFromRight
UIViewAnimationOptionTransitionCurlUp
UIViewAnimationOptionTransitionCurlDown
Edit:
Or if you're just looking to animate those values, try
[UIView animateWithDuration:(NSTimeInterval)duration
animations:(void (^)(void))animations
completion:(void (^)(BOOL finished))completion];