Как оживить ширину и высоту 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. Но анимация не работает!
Ответы
Ответ 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 кадр, заданный анимацией.