2013-07-29 2 views
2

У меня есть большая проблема с масштабированием простого UIButton.Как плавно увеличивать и уменьшать масштаб UIButton в iOS

  • Чтобы воспроизвести проблему, просто сделать простой проект, с XIB содержащего 2 UIButtons: один, чтобы быть увеличен, другой для активации методы масштабирования.

  • UIButton для увеличения - это обычай button, с некоторым простым текстом внутри и фоновым изображением.

Затем используйте следующий код:

.h

#import <UIKit/UIKit.h> 

@interface ViewController : UIViewController { 
    UIButton* buttonToZoom; 
} 

@property (nonatomic, retain) IBOutlet UIButton* buttonToZoom; 

-(IBAction)zoomIt:(id)sender; 
CGPoint CGRectFindCenter(CGRect rect); 
- (void) zoom:(BOOL)zoomIt animated:(BOOL)animated; 

@end 

.m

#import "ViewController.h" 

@implementation ViewController 

@synthesize buttonToZoom; 

#pragma mark - View lifecycle 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    CGRect theRect = self.buttonToZoom.bounds; 

    CGRect deleteBtnMaxiRect = CGRectMake(self.view.bounds.size.width - theRect.size.width - 10, 
              10, 
              theRect.size.width, 
              theRect.size.height); 

    CGRect deleteBtnMiniRect = CGRectMake(CGRectFindCenter(deleteBtnMaxiRect).x - 1, 
              CGRectFindCenter(deleteBtnMaxiRect).y - 1, 
              2, 
              2); 

    self.buttonToZoom.frame = deleteBtnMaxiRect; // Ensures its correct size at default position 
    [self zoom:NO animated:NO]; // makes it disapear 
} 

-(IBAction)zoomIt:(id)sender { 
    static BOOL zoomInOut = YES; 

    [self zoom:zoomInOut animated:YES]; 
    zoomInOut = !zoomInOut; 
} 

CGPoint CGRectFindCenter(CGRect rect) 
{ 
    return CGPointMake(rect.origin.x + rect.size.width/2.0, rect.origin.y + rect.size.height/2.0); 
} 

- (CGAffineTransform)translatedAndScaledTransformFromRect:(CGRect)fromRect toRect:(CGRect)toRect { 

    CGSize scales = CGSizeMake(toRect.size.width/fromRect.size.width, toRect.size.height/fromRect.size.height); 
    CGPoint offset = CGPointMake(CGRectGetMidX(toRect) - CGRectGetMidX(fromRect), CGRectGetMidY(toRect) - CGRectGetMidY(fromRect)); 

    NSLog(@"scales %@", [NSValue valueWithCGSize:scales]); 

    CGAffineTransform scaleTransform = CGAffineTransformMakeScale(scales.width, scales.height); 
    CGAffineTransform offsetTransform = CGAffineTransformMakeTranslation(offset.x, offset.y); 
    return scaleTransform;// CGAffineTransformConcat(scaleTransform, offsetTransform); 

    // return CGAffineTransformMake(scales.width, 0, 0, scales.height, offset.x, offset.y); 

} 

- (void) zoom:(BOOL)zoomIt animated:(BOOL)animated 
{ 
    static CGRect theRect; 
    if (CGRectIsEmpty(theRect)) theRect = CGRectMake(0, 0, 87, 33); 

    CGRect deleteBtnMaxiRect = CGRectMake(self.view.bounds.size.width - theRect.size.width - 10, 
              10, 
              theRect.size.width, 
              theRect.size.height); 

    CGRect deleteBtnMiniRect = CGRectMake(CGRectFindCenter(deleteBtnMaxiRect).x - 1, 
              CGRectFindCenter(deleteBtnMaxiRect).y - 1, 
              2, 
              2); 

    NSLog(@"------------------------------------------------ mini %@", [NSValue valueWithCGRect:deleteBtnMiniRect]); 
    NSLog(@"------------------------------------------------ maxi %@", [NSValue valueWithCGRect:deleteBtnMaxiRect]); 

    if (animated == YES) { 
     [UIView beginAnimations:@"editingModeAnimation" context:nil]; 
     [UIView setAnimationDuration:1.3]; 
     [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut]; 
     [UIView setAnimationTransition:UIViewAnimationTransitionNone forView:self.view cache:NO]; 
     [UIView setAnimationDelegate:self]; 
    } 

    if (zoomIt == YES) { 
     if (CGRectEqualToRect(self.buttonToZoom.frame, deleteBtnMaxiRect)) return; 
     NSLog(@"Zoom"); 

     NSLog(@"################################################ before bounds %@", [NSValue valueWithCGRect:self.buttonToZoom.bounds]); 
     NSLog(@"################################################ before frame %@", [NSValue valueWithCGRect:self.buttonToZoom.frame]); 
     self.buttonToZoom.alpha = 1.0; 
     self.buttonToZoom.transform = [self translatedAndScaledTransformFromRect:deleteBtnMiniRect toRect:deleteBtnMaxiRect]; 
     [UIView setAnimationDidStopSelector:@selector(animate_EndEditing)]; 
    } 
    else { 
     if (CGRectEqualToRect(self.buttonToZoom.frame, deleteBtnMiniRect)) return; 
     NSLog(@"Reduce"); 

     NSLog(@"################################################ before bounds %@", [NSValue valueWithCGRect:self.buttonToZoom.bounds]); 
     NSLog(@"################################################ before frame %@", [NSValue valueWithCGRect:self.buttonToZoom.frame]); 
     self.buttonToZoom.alpha = 1.0; // for test 
     self.buttonToZoom.transform = [self translatedAndScaledTransformFromRect:deleteBtnMaxiRect toRect:deleteBtnMiniRect]; 
     [UIView setAnimationDidStopSelector:@selector(animate_EndEditing)]; 
    } 

    if (animated == YES) [UIView commitAnimations]; 
    else { 
      NSLog(@"################################################ after bounds %@", [NSValue valueWithCGRect:self.buttonToZoom.bounds]); 
      NSLog(@"################################################ after frame %@", [NSValue valueWithCGRect:self.buttonToZoom.frame]); 
    } 
} 

- (void) animate_EndEditing 
{ 
    NSLog(@"################################################ after bounds %@", [NSValue valueWithCGRect:self.buttonToZoom.bounds]); 
    NSLog(@"################################################ after frame %@", [NSValue valueWithCGRect:self.buttonToZoom.frame]); 
} 

@end 

Это дает следующие журналы:

Нажмите для увеличения:

Launch 

2013-07-30 00:42:31.008 test[651:207] ------------------------------------------------ mini NSRect: {{265.5, 25.5}, {2, 2}} 
2013-07-30 00:42:31.009 test[651:207] ------------------------------------------------ maxi NSRect: {{223, 10}, {87, 33}} 
2013-07-30 00:42:31.010 test[651:207] Reduce 
2013-07-30 00:42:31.010 test[651:207] ################################################ before bounds NSRect: {{0, 0}, {141, 37}} 
2013-07-30 00:42:31.011 test[651:207] ################################################ before frame NSRect: {{169, 10}, {141, 37}} 
2013-07-30 00:42:31.011 test[651:207] scales NSSize: {0.022988506, 0.060606062} 
2013-07-30 00:42:31.011 test[651:207] ################################################ after bounds NSRect: {{0, 0}, {141, 37}} 
2013-07-30 00:42:31.012 test[651:207] ################################################ after frame NSRect: {{237.8793, 27.378788}, {3.2413793, 2.2424242}} 



Zoom in 

2013-07-30 00:43:09.497 test[651:207] ------------------------------------------------ mini NSRect: {{265.5, 25.5}, {2, 2}} 
2013-07-30 00:43:09.498 test[651:207] ------------------------------------------------ maxi NSRect: {{223, 10}, {87, 33}} 
2013-07-30 00:43:09.498 test[651:207] Zoom 
2013-07-30 00:43:09.499 test[651:207] ################################################ before bounds NSRect: {{0, 0}, {141, 37}} 
2013-07-30 00:43:09.500 test[651:207] ################################################ before frame NSRect: {{237.8793, 27.378788}, {3.2413793, 2.2424242}} 
2013-07-30 00:43:09.500 test[651:207] scales NSSize: {43.5, 16.5} 
2013-07-30 00:43:10.801 test[651:207] ################################################ after bounds NSRect: {{0, 0}, {141, 37}} 
2013-07-30 00:43:10.802 test[651:207] ################################################ after frame NSRect: {{-2827.25, -276.75}, {6133.5, 610.5}} 



Zoom Out 

2013-07-30 00:43:29.889 test[651:207] ------------------------------------------------ mini NSRect: {{265.5, 25.5}, {2, 2}} 
2013-07-30 00:43:29.890 test[651:207] ------------------------------------------------ maxi NSRect: {{223, 10}, {87, 33}} 
2013-07-30 00:43:29.890 test[651:207] Reduce 
2013-07-30 00:43:29.891 test[651:207] ################################################ before bounds NSRect: {{0, 0}, {141, 37}} 
2013-07-30 00:43:29.892 test[651:207] ################################################ before frame NSRect: {{-2827.25, -276.75}, {6133.5, 610.5}} 
2013-07-30 00:43:29.892 test[651:207] scales NSSize: {0.022988506, 0.060606062} 
2013-07-30 00:43:31.193 test[651:207] ################################################ after bounds NSRect: {{0, 0}, {141, 37}} 
2013-07-30 00:43:31.194 test[651:207] ################################################ after frame NSRect: {{237.8793, 27.378788}, {3.2413793, 2.2424242}} 

И следующие визуальные эффекты:

После масштабирования в

enter image description here

After Уменьшить

enter image description here

если я пытаюсь заставить этот код просто АВЭК NSLog из мини и макси прямоугольникам:

if (zoomIt) { 
    self.buttonToZoom.bounds = CGRectMake(0, 0, deleteBtnMiniRect.size.width, deleteBtnMiniRect.size.height); 
    self.buttonToZoom.center = CGRectFindCenter(deleteBtnMiniRect); 
} 
else { 
    self.buttonToZoom.bounds = CGRectMake(0, 0, deleteBtnMaxiRect.size.width, deleteBtnMaxiRect.size.height); 
    self.buttonToZoom.center = CGRectFindCenter(deleteBtnMaxiRect); 
} 

Увеличение в порядке, но уменьшить (уменьшить тег) делает Диковины вещи:

2013-07-30 01:11:19.988 test[1210:207] ######################################################################################### 
2013-07-30 01:11:19.990 test[1210:207] ------------------------------------------------ mini NSRect: {{265.5, 25.5}, {2, 2}} 
2013-07-30 01:11:19.990 test[1210:207] ------------------------------------------------ maxi NSRect: {{223, 10}, {87, 33}} 
2013-07-30 01:11:19.991 test[1210:207] Reduce 
2013-07-30 01:11:19.991 test[1210:207] ################################################ before bounds NSRect: {{0, 0}, {87, 33}} 
2013-07-30 01:11:19.992 test[1210:207] ################################################ before frame NSRect: {{223, 10}, {87, 33}} 
2013-07-30 01:11:19.992 test[1210:207] scales NSSize: {0.022988506, 0.060606062} 
2013-07-30 01:11:19.993 test[1210:207] ################################################ after bounds NSRect: {{0, 0}, {87, 33}} 
2013-07-30 01:11:19.993 test[1210:207] ################################################ after frame NSRect: {{265.5, 25.5}, {2, 2}} 
2013-07-30 01:11:21.730 test[1210:207] ######################################################################################### 
2013-07-30 01:11:21.730 test[1210:207] ------------------------------------------------ mini NSRect: {{265.5, 25.5}, {2, 2}} 
2013-07-30 01:11:21.731 test[1210:207] ------------------------------------------------ maxi NSRect: {{223, 10}, {87, 33}} 
2013-07-30 01:11:21.731 test[1210:207] Zoom 
2013-07-30 01:11:21.732 test[1210:207] ################################################ before bounds NSRect: {{0, 0}, {2, 2}} 
2013-07-30 01:11:21.733 test[1210:207] ################################################ before frame NSRect: {{266.47702, 26.439394}, {0.045977011, 0.12121212}} 
2013-07-30 01:11:21.733 test[1210:207] scales NSSize: {43.5, 16.5} 
2013-07-30 01:11:23.034 test[1210:207] ################################################ after bounds NSRect: {{0, 0}, {2, 2}} 
2013-07-30 01:11:23.035 test[1210:207] ################################################ after frame NSRect: {{223, 10}, {87, 33}} 
2013-07-30 01:11:24.858 test[1210:207] ######################################################################################### 
2013-07-30 01:11:24.858 test[1210:207] ------------------------------------------------ mini NSRect: {{265.5, 25.5}, {2, 2}} 
2013-07-30 01:11:24.859 test[1210:207] ------------------------------------------------ maxi NSRect: {{223, 10}, {87, 33}} 
2013-07-30 01:11:24.860 test[1210:207] Reduce 
2013-07-30 01:11:24.860 test[1210:207] ################################################ before bounds NSRect: {{0, 0}, {87, 33}} 
2013-07-30 01:11:24.860 test[1210:207] ################################################ before frame NSRect: {{-1625.75, -245.75}, {3784.5, 544.5}} 
2013-07-30 01:11:24.861 test[1210:207] scales NSSize: {0.022988506, 0.060606062} 
2013-07-30 01:11:26.162 test[1210:207] ################################################ after bounds NSRect: {{0, 0}, {87, 33}} 
2013-07-30 01:11:26.163 test[1210:207] ################################################ after frame NSRect: {{265.5, 25.5}, {2, 2}} 

проблемы

  1. Почему рендеринг рендеринга дает такое большое изображение? Это действительно далеко от ожидаемого прямоугольника 87x33.

  2. Почему кнопка никогда не достигает размера 2, 2?

  3. Почему границы никогда не меняются и остаются на первоначальном размере кнопки, определенной в xib?

+1

Есть причина, вы используете старую школу стиля код анимации, а не UIView анимации блоков? – Jsdodgers

+0

@ Jsdodgers: Нет, нет причин, кроме быстрого написания примера. – Oliver

ответ

6

Пожалуйста, используйте UIView блочные методы, основанные на анимации, чтобы сделать это ..

//for zoom in 
[UIView animateWithDuration:0.5f animations:^{ 
    self.btn.transform = CGAffineTransformMakeScale(1.5, 1.5); 
}]; 

// for zoom out 
[UIView animateWithDuration:0.5f animations:^{ 
    self.btn.transform = CGAffineTransformMakeScale(1, 1); 
}];