CGAffineTransform
을 사용하여 프로그래밍 방식으로 willRotateToInterfaceOrientation
함수에서 회전하는 iOS 앱에 UIToolbar
이 있습니다. 변환에는 스케일링, 회전 및 변환이 필요합니다. 스케일 및 회전 매개 변수를 계산하는 방법을 알고 있지만 뷰가 올바른 위치에 있도록 변환 매개 변수를 계산하는 방법을 파악하지 못하는 것 같습니다. 많은 시행 착오 끝에 iPad의 적절한 위치로보기를 이동시키기 위해 정확한 숫자를 결정했으나 코드가 너무 장치에 의존하지 않도록 숫자를 하드 코딩하지 않기를 바랍니다. 번역 매개 변수는 어떻게 계산합니까?iOS에서보기를 회전 할 때 어파 인 변환 매개 변수는 어떻게 계산합니까?
여기 내 도구 모음이 들어있는보기 컨트롤러에서 내 willRotateToInterfaceOrientation
함수입니다. 값을 하드 코딩하는 대신 tx
및 ty
을 계산하는 방법을 알고 싶습니다. 도구 모음 및 창 크기의 다양한 기능을 사용하여 시도했지만 도구 모음은 항상 창의 아래쪽이 아닌 이상한 위치의 창이나 창 외부에 겹쳐서 나타납니다.
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
if (UIInterfaceOrientationIsLandscape(toInterfaceOrientation))
{
// First, apply identify transformation to simplify later calculations and also because we need the toolbar's frame and Apple's docs say you cannot use a view's frame if the transform property is not the identity matrix.
self.toolbar.transform = CGAffineTransformIdentity;
// Calculate affine parameters.
// Expand width to the window's height when in landscape mode, leaving the toolbar's height unchanged.
UIWindow *window = [[UIApplication sharedApplication] keyWindow];
CGFloat sx = 1.0;
CGFloat sy = window.frame.size.height/window.frame.size.width;
// Rotate 90 degrees in either direction depending on the orientation direction change.
CGFloat rotate = M_PI_2;
if (toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft)
{
rotate = -M_PI_2;
}
// Reposition the toolbar.
// TODO: Calculate values rather than hard-coding them. Why is tx not something like ((window.frame.size.width/2) - (self.toolbar.frame.size.height/2))?
// Note that these values work for both the original iPad and iPad Retina, presumably because the values represent points not pixels.
CGFloat tx = -365.5;
CGFloat ty = 359.5;
if (toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft)
{
tx = -tx;
}
// Apply affine transformation.
CGAffineTransform transform = CGAffineTransformMakeScale(sx, sy);
transform = CGAffineTransformRotate(transform, rotate);
transform = CGAffineTransformTranslate(transform, tx, ty);
[UIView animateWithDuration:duration
animations:^{
self.toolbar.transform = transform;
}
completion:NULL
];
}
else if (toInterfaceOrientation == UIInterfaceOrientationPortrait)
{
[UIView animateWithDuration:duration
animations:^{
self.toolbar.transform = CGAffineTransformIdentity;
}completion:NULL
];
}
else if (toInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown)
{
NSLog(@"Upside-down orientation not supported");
}
}
또한 내 툴바의 선언과 기본 초기화가 있습니다. 내 애플 리케이션은 루트보기 컨트롤러로 UITabBarController
을 가지고 있기 때문에 메인 윈도우에 서브뷰로 툴바를 추가하고 수동으로 회전을 처리한다는 것을 알아 두십시오. 이것은 툴바를 탭 바 위에 표시 할 수있는 유일한 방법이었습니다.
// The toolbar is strong since this controller must maintain ownership as the toolbar is removed from the parent view when this view disappears.
@property (strong, nonatomic) IBOutlet UIToolbar *toolbar;
UIWindow *window = [[UIApplication sharedApplication] keyWindow];
CGFloat height = CGRectGetHeight(self.tabBarController.tabBar.frame); // Completely cover the tab bar.
CGFloat x = window.frame.origin.x;
CGFloat y = window.frame.size.height - height;
CGFloat width = window.frame.size.width;
self.toolbar.frame = CGRectMake(x, y, width, height);
[window addSubview:self.toolbar];
마지막으로, ARC 활성화와 엑스 코드 4.5.1을 사용하고 아이 패드 (망막 및 비 망막) 5.1 및 6.0 시뮬레이터 모두 테스트입니다.
응답 해 주셔서 감사합니다. 내 이해가 아닌 (CGAffineTransformMakeTranslate 대신 CGAffineTransformTranslate) 기능을 기존의 아핀 변환 주어진 된 매개 변수를 적용하여 새 변환 행렬을 구성합니다. – user19480
@ user19480 당신은 완전히 틀렸어. 실수했다. 나는 그것이 Make 유형이 아니라는 사실을 놓쳤다. 사과. – WDUK