Подтвердить что ты не робот

Как оживить ширину и высоту UIView в Xcode?

У меня есть это subview, которое я хочу добавить к своему основному виду, но сделайте его расширяющимся из источника. Я прочитал некоторые документы Apple, но я не понимаю, где я ошибаюсь. Я могу анимировать происхождение кадра, т.е. Заставлять его перемещаться туда, где угодно, но ширина/высота не кажутся анимированными. Код выглядит следующим образом:

[UIView beginAnimations:@"animateAddContentView" context:nil];
[UIView setAnimationDuration:0.4];
customView.frame= CGRectMake(self.view.frame.origin.x +5, self.view.frame.origin.y +5, 0, 150);
[self.view addSubview:customView];

customView.frame= CGRectMake(self.view.frame.origin.x +5, self.view.frame.origin.y +5, 310, 150);
[UIView commitAnimations];

Я также попытался помещать только часть setFrame в анимацию следующим образом:

customView.frame= CGRectMake(self.view.frame.origin.x +5, self.view.frame.origin.y +5, 0, 150);
[self.view addSubview:customView];
[UIView beginAnimations:@"animateAddContentView" context:nil];
[UIView setAnimationDuration:0.4];
customView.frame= CGRectMake(self.view.frame.origin.x +5, self.view.frame.origin.y +5, 310, 150);
[UIView commitAnimations];

Но это все еще не работает!

ИЗМЕНИТЬ:

В соответствии с предложениями я переместил его в решение для анимации на основе блоков, и это точный код:

NSLog(@"yourview : %@",customView);
customView.frame= CGRectMake(self.view.frame.origin.x +5, self.view.frame.origin.y +5, 0, 150);

NSLog(@"yourview : %@",customView);
[self.view addSubview:customView];
NSLog(@"yourview : %@",customView);

//    [customView setFrame:CGRectMake( 0.0f, 480.0f, customView.frame.size.width, customView.frame.size.height)];

[UIView animateWithDuration:0.4
                      delay:0
                    options:UIViewAnimationCurveEaseInOut
                 animations:^ {
                     NSLog(@"yourview : %@",customView);

                     customView.frame = CGRectMake(self.view.frame.origin.x +5, self.view.frame.origin.y +5, 310, 150);
                     NSLog(@"yourview : %@",customView);

                 }completion:^(BOOL finished) {

                 }];

Что по какой-то причине по-прежнему не работает. Возможные проблемы, которые я вижу, следующие:

  • Я загружаю этот customView из nib, а именно 310 на 150, возможно, это вызывает проблему.
  • Я не импортирую правильные фреймворки, но поскольку я могу анимировать части frame.origin этого представления, я не уверен, что это так... У меня есть QuartzCore и Core Graphics все импортированные и другие.

В каждой точке журнала он дает правильные вещи: например, перед целевым кадром размер равен 0, 150, а после того, как я установил фрейм его 310, 150. Но анимация не работает!

4b9b3361

Ответ 1

Чтобы сделать вид "расти" на месте, не анимируйте рамку. Анимируйте преобразование.

Загрузите свой подъярус из наконечника. Установите его преобразование в шкалу 0:

view.transform = CGAffineTransformMakeScale(0,0);

Затем добавьте его в свой супервизор.

Внутри блока анимации установите для преобразования значение:

view.transform = CGAffineTransformIdentity;

И представление будет расти до нормального размера. Возможно, вам придется поиграть с точкой привязки, чтобы заставить ее расти с правой точки.

Вы также можете изменить фрейм внутри блока, но для перемещения только я предпочитаю изменять свойство центра, вы не должны пытаться установить кадр, если у вас также есть преобразование.

Для бонусных очков вы также можете анимировать несколько больше, чем 1,0, а затем вернуться к преобразованию идентичности в цепочке анимации из блока завершения. Это делает вид "pop" вне экрана, как вид предупреждения.

Ответ 2

Попробуйте использовать блок, это будет более понятно.

 // First create the view if you haven't already 
UIView *myView = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 100.0f, 100.0f)]; 
// Add it as a subview. 
[myViewController.view addSubview:myView]; 


CGRect newFrameOfMyView = CGRectMake(0.0f, 0.0f, 200.0f, 200.0f); 
/*
 * Alternatively you could just set the width/height or whatever you'd like with this: 
 * CGRect newFrameOfMyView = myView.frame; 
 * newFrameOfMyView.size.height = 200.0f; 
 * newFrameOfMyView.size.width = 200.0f; 
 */
[UIView animateWithDuration:0.3f
     animations:^{
      myView.frame = newFrameOfMyView; 
     }
     completion:^(BOOL finished){ 
     NSLog( @"woo! Finished animating the frame of myView!" ); 
}];

Ответ 3

Попробуйте следующее:

customView.frame= CGRectMake(self.view.frame.origin.x +5,self.view.frame.origin.y+5,0, 150);
[self.view addSubview:customView];
CGRect frame = customView.frame;
frame.size.width = 310;
[UIView animateWithDuration:0.4
 animations:^{
  customView.frame= frame; 
 }];

Или если вы хотите использовать метод beginAnimation вместо блока Methos, используйте это:

UIView *customView=[[UIView alloc]initWithFrame:CGRectMake(self.view.frame.origin.x +5,self.view.frame.origin.y+5,0, 150)];
[self.view addSubview:customView];
CGRect frame = customView.frame;
frame.size.width = 310;
[UIView beginAnimations:@"animateAddContentView" context:nil];
[UIView setAnimationDuration:0.4];
customView.frame= frame;
[UIView commitAnimations];

Ответ 4

Важные моменты

1) Добавьте к родительскому представлению представление перед анимацией со стартовым фреймом.

2) Затем просто укажите целевой кадр внутри блока анимации

Вам больше не нужно это, так как вы добавляете представление из nib..

//UIVIew yourView  = [[UIView alloc] initWithFrame:YOUR_STARTING_FRAME];
//[self.view addSubview:yourView];

.........
.........
.........

просто укажите код анимации в вашем представлении. Убедитесь, что вашView не ноль (кажется мне так..)

NSLog(@"yourview : %@",yourView);
[UIView animateWithDuration:your_duration 
                      delay:your_starting_delay 
                    options:UIViewAnimationCurveEaseInOut 
                 animations:^ {
                     yourView.frame = YOUR_TARGET_FRAME;
                 }completion:^(BOOL finished) {

                 }];

Ответ 5

Вот забавный способ оживить ваши взгляды. В моем примере у меня есть действие касания, которое выполнит анимацию блока и BOOL, чтобы убедиться, что reset представления возвращаются к их исходным состояниям.

Сначала вы положили 2 UIViews на UIViewController (вы можете покрасить их разными цветами для контраста). Подключите их к вашему файлу "MainViewController.h", который вы создаете для управления большим представлением. Файл .h должен выглядеть следующим образом:

#import <UIKit/UIKit.h>

@interface MainViewController : UIViewController
@property (weak, nonatomic) IBOutlet UIView *topView;
@property (weak, nonatomic) IBOutlet UIView *bottomView;

@end

и ваш .m файл должен выглядеть так:

#import "MainViewController.h"
#define kViewAnimateWithDuration 0.35f
#define kViewDelay 0.05f

@interface MainViewController ()
@property (nonatomic) BOOL setTouch;
@end

@implementation MainViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
        self.setTouch = NO;
    }
    return self;
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
    UITouch *touch = [touches anyObject];
    CGPoint touchLocation = [touch locationInView:self.view];

    float width_tp = self.topView.frame.size.width;
    float height_tp = self.topView.frame.size.height;

    float width_b = self.bottomView.frame.size.width;
    float height_b = self.bottomView.frame.size.height;

    if ((CGRectContainsPoint(self.bottomView.frame, touchLocation)) && !self.setTouch){

        [UIView animateWithDuration:kViewAnimateWithDuration
                              delay:kViewDelay
                            options:UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionAllowUserInteraction
                         animations:^{
                             //Move frame or transform view
                             [self.topView setFrame:CGRectMake(self.topView.frame.origin.x, self.topView.frame.origin.y, width_tp, height_tp + 171)];

                             [self.bottomView setFrame:CGRectMake(self.bottomView.frame.origin.x, self.bottomView.frame.origin.y +171, width_b, height_b -171)];

                         } completion:^(BOOL finished) {
                             self.setTouch = YES;
                         }];



    }
    if ((CGRectContainsPoint(self.bottomView.frame, touchLocation)) && self.setTouch) {
        [UIView animateWithDuration:kViewAnimateWithDuration
                              delay:kViewDelay
                            options:UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionAllowUserInteraction
                         animations:^{
                             //Move frame or transform view
                             [self.topView setFrame:CGRectMake(self.topView.frame.origin.x, self.topView.frame.origin.y, width_tp, height_tp - 171)];

                             [self.bottomView setFrame:CGRectMake(self.bottomView.frame.origin.x, self.bottomView.frame.origin.y -171, width_b, height_b +171)];

                         } completion:^(BOOL finished) {
                             self.setTouch = NO;
                         }];
    }

}

Так что просто убедитесь, что у topView есть небольшие размеры, такие как x: 0, y: 0 width: 320 height: 43 и bottomView like x: 0 y: 40 width: 320 height: 528. Не забудьте покрасить фон разными цветами. Затем просто запустите программу, и вы увидите анимацию.

Для меня я думаю, что одна из наиболее важных строк в коде - setFrame:, которая позволяет мне автоматически преобразовывать прямоугольник, не используя метод DrawRect. Установка свойства изменяет точку, заданную свойством центра, и размер в прямоугольнике границ соответственно.

Конечно, есть и другие интересные способы сделать это, но я надеюсь, что это поможет кому-то сделать iOS выглядеть волшебным, как это должно быть! Счастливые путешествия!

Ответ 6

Если ваш viewcontrollers viewWillLayoutSubviews (или такой) устанавливает "начальный" кадр вашегоView, то это, по-видимому, вызывается во время цикла анимации, и поэтому reset кадр, заданный анимацией.