Что-то кроме snapToPoint управляет макетом в UISnapBehavior
Я новичок в анимации и пытаюсь понять, почему UIAnimation и UISnapBehavior смещают кнопки UIB вне центра. Ясно, что есть что-то, управляющее макетом помимо того, что в моем коде. Может быть, кто-то может сказать мне, что я скучаю.
Первоначально в моем ViewController было пять программных UIB-кнопок, размещенных программным способом (то есть без файла XIB) по окружности круга, как показано на рисунке A. При редактировании моего приложения я ввел анимацию привязки, чтобы переместить UIB-кнопки в положение от центральной точки. На рисунке B показана центральная точка, где начинается анимация. На рисунке C показаны пять UIB-кнопок, которые смещаются после завершения анимации, даже если CGPoints используются для snapToPoint:
точно такие же, как CGPoints, используемые для размещения кнопок UIB.
Когда я щелкнул в черной прямоугольной области внизу экрана, я заметил сообщение в отчете unexpected nil window in _UIApplicationHandleEventFromQueueEvent
который включал свойства размера кадра. Это говорит о том, что рамки или границы могут быть причиной того, что кнопки UIB смещаются от центра после анимации.
Вот последняя версия кода, который я использовал, чтобы продемонстрировать, что происходит. Я верю, что это правильно, даже если он не выиграет призов в конкурсе "Объектно-ориентированная красота":-)
Во-первых, пять кнопок без анимации показаны на рисунке А.
- (void)viewDidLoad {
NSLog(@"load GlobalView");
CGRect dot1 = (CGRect) { .origin.x = 38.0f, .origin.y = 263.0f, .size.width = 80.0f, .size.height = 80.0f,};
CGRect dot2 = (CGRect) { .origin.x = 207.0f, .origin.y = 263.0f, .size.width = 80.0f, .size.height = 80.0f,};
CGRect dot3 = (CGRect) { .origin.x = 123.0f, .origin.y = 320.0f, .size.width = 80.0f, .size.height = 80.0f,};
CGRect dot4 = (CGRect) { .origin.x = 170.0f, .origin.y = 167.0f, .size.width = 80.0f, .size.height = 80.0f,};
CGRect dot5 = (CGRect) { .origin.x = 70.0f, .origin.y = 167.0f, .size.width = 80.0f, .size.height = 80.0f,};
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~
РЕДАКТИРОВАТЬ. Следующие строки кода переопределяют origin
так CGRect
центрируется по окружности круга. Они заменяют строки выше, которые определяют origin
как верхняя левая вершина CGRect
, Анимация теперь размещает кнопки UIB в соответствии с макетом, показанным на рисунке A.
*/
float width = 80.0f;
float height = 80.0f;
CGRect dot1 = (CGRect) { .origin.x = 38.0f + width/2, .origin.y = 263.0f + width/2, width, height};
CGRect dot2 = (CGRect) { .origin.x = 207.0f + width/2, .origin.y = 263.0f + width/2, width, height};
CGRect dot3 = (CGRect) { .origin.x = 123.0f + width/2, .origin.y = 320.0f + width/2, width, height};
CGRect dot4 = (CGRect) { .origin.x = 170.0f + width/2, .origin.y = 167.0f + width/2, width, height};
CGRect dot5 = (CGRect) { .origin.x = 70.0f + width/2, .origin.y = 167.0f + width/2, width, height};
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~
// Insert global rings
UIView *ringView = [[UIView alloc] initWithFrame:CGRectMake(60.0f, 178.0f, 200.0f, 200.0f)];
UIImage *ringImage = [UIImage imageNamed:@"GlobalRings.png"];
UIImageView *imageView = [[UIImageView alloc] initWithImage:ringImage];
imageView.frame = ringView.bounds; // frame imageView in ringView and fill ringView
[ringView addSubview:imageView]; // add the imageview to the superview
[self.view addSubview:ringView]; //add the view to the main view
// place 5 UIButtons
UIButton *navigationButton1 = [UIButton buttonWithType:UIButtonTypeCustom];
[navigationButton1 setTitleColor:[UIColor blackColor] forState: UIControlStateNormal];
navigationButton1.frame = CGRectMake(38.0, 263.0, 80.0, 80.0);
[navigationButton1 setImage:[UIImage imageNamed:@"Dot1.png"] forState:UIControlStateNormal];
[navigationButton1 addTarget:self action:@selector(goToVenue1) forControlEvents:UIControlEventTouchUpInside];
UIButton *navigationButton2 = [UIButton buttonWithType:UIButtonTypeCustom];
[navigationButton2 setTitleColor:[UIColor blackColor] forState: UIControlStateNormal];
navigationButton2.frame = CGRectMake(207.0, 263.0, 80.0, 80.0);
[navigationButton2 setImage:[UIImage imageNamed:@"Dot2.png"] forState:UIControlStateNormal];
[navigationButton2 addTarget:self action:@selector(goToVenue2) forControlEvents:UIControlEventTouchUpInside];
UIButton *navigationButton3 = [UIButton buttonWithType:UIButtonTypeCustom];
[navigationButton3 setTitleColor:[UIColor blackColor] forState: UIControlStateNormal];
navigationButton3.frame = CGRectMake(123.0, 320.0, 80.0, 80.0);
[navigationButton3 setImage:[UIImage imageNamed:@"Dot3.png"] forState:UIControlStateNormal];
[navigationButton3 addTarget:self action:@selector(goToVenue3) forControlEvents:UIControlEventTouchUpInside];
UIButton *navigationButton4 = [UIButton buttonWithType:UIButtonTypeCustom];
[navigationButton4 setTitleColor:[UIColor blackColor] forState: UIControlStateNormal];
navigationButton4.frame = CGRectMake(170.0, 167.0, 80.0, 80.0);
[navigationButton4 setImage:[UIImage imageNamed:@"Dot4.png"] forState:UIControlStateNormal];
[navigationButton4 addTarget:self action:@selector(goToVenue4) forControlEvents:UIControlEventTouchUpInside];
UIButton *navigationButton5 = [UIButton buttonWithType:UIButtonTypeCustom];
[navigationButton5 setTitleColor:[UIColor blackColor] forState: UIControlStateNormal];
navigationButton5.frame = CGRectMake(70.0, 167.0, 80.0, 80.0);
[navigationButton5 setImage:[UIImage imageNamed:@"Dot5.png"] forState:UIControlStateNormal];
[navigationButton5 addTarget:self action:@selector(goToVenue5) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:navigationButton1];
[self.view addSubview:navigationButton2];
[self.view addSubview:navigationButton3];
[self.view addSubview:navigationButton4];
[self.view addSubview:navigationButton5];
[super viewDidLoad];
}
Затем, чтобы поместить пять кнопок UIB в центр перед началом анимации, я выровнял каждую кнопку UIB по центру кадра, добавив
CGRect preSnap = (CGRect) { .origin.x = 120.0f, .origin.y = 240.0f, .size.width = 80.0f, .size.height = 80.0f,};
а затем изменив каждый кадр кнопки (ниже), чтобы установить начальную точку для анимации
navigationButton1.frame = preSnap;
navigationButton2.frame = preSnap;
navigationButton3.frame = preSnap;
navigationButton4.frame = preSnap;
navigationButton5.frame = preSnap;
Потом я добавил UISnapBehaviour
к анимации, вставив указатели сразу после viewDidLoad
UIDynamicAnimator* _animator1;
UIDynamicAnimator* _animator2;
UIDynamicAnimator* _animator3;
UIDynamicAnimator* _animator4;
UIDynamicAnimator* _animator5;
UISnapBehavior* _snap1;
UISnapBehavior* _snap2;
UISnapBehavior* _snap3;
UISnapBehavior* _snap4;
UISnapBehavior* _snap5;
и добавление UIDynamicAnimator
а также UISnapBehavior
методы перед [super viewDidLoad];
в результате чего UIButton
макет показан на рисунке C
_animator1 = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
_snap1 = [[UISnapBehavior alloc] initWithItem:navigationButton1 snapToPoint: dot1.origin];
[_animator1 addBehavior:_snap1];
_animator2 = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
_snap2 = [[UISnapBehavior alloc] initWithItem:navigationButton2 snapToPoint: dot2.origin];
[_animator2 addBehavior:_snap2];
_animator3 = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
_snap3 = [[UISnapBehavior alloc] initWithItem:navigationButton3 snapToPoint: dot3.origin];
[_animator3 addBehavior:_snap3];
_animator4 = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
_snap4 = [[UISnapBehavior alloc] initWithItem:navigationButton4 snapToPoint: dot4.origin];
[_animator4 addBehavior: _snap4];
_animator5 = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
_snap5 = [[UISnapBehavior alloc] initWithItem:navigationButton5 snapToPoint: dot5.origin];
[_animator5 addBehavior:_snap5];
[super viewDidLoad];
}
Наконец, я добавил пять методов, чтобы убедиться, что все кнопки работают
- (void)goToVenue1 {
NSLog(@"Button 1 worked");
}
- (void)goToVenue2 {
NSLog(@"Button 2 worked");
}
- (void)goToVenue3 {
NSLog(@"Button 3 worked");
}
- (void)goToVenue4 {
NSLog(@"Button 4 worked");
}
- (void)goToVenue5 {
NSLog(@"Button 5 worked");
}
1 ответ
Проблема решена. В более ранних редакциях origin
координаты были те, что в верхней левой вершине. Надо было переопределить origin
так CGRect
центрируется по окружности круга.