Область нажатия кнопки iOS после поворота устройства
У меня проблемы с парой кнопок после поворота. В портретном режиме кнопки расположены в нижней части экрана. В альбомной ориентации они перемещаются и изменяют размеры, чтобы быть рядом друг с другом в нижней части экрана. Все это прекрасно работает, и кнопки ведут себя правильно. Однако, если телефон повернуть обратно в портретное положение, область нажатия кнопок будет неправильной - только левая 1/3 кнопок может быть нажата.
Вот код, который делает вращение. (Я также называю его в viewWillAppear, поэтому он всегда выполняется при отображении представления, если представление уже в альбомной ориентации.) Я поместил кнопки в их собственное внутреннее представление.
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
duration:(NSTimeInterval)duration {
// determine our dimensions based on orientation
CGRect mainRect = [[UIScreen mainScreen] bounds];
CGFloat maxWidthHeight = MAX(mainRect.size.width, mainRect.size.height);
CGFloat minWidthHeight = MIN(mainRect.size.width, mainRect.size.height);
CGFloat _windowWidth = (UIDeviceOrientationIsPortrait(toInterfaceOrientation)) ? minWidthHeight : maxWidthHeight;
// get the current sizes of the things we are moving
CGRect saveRect = self.viewButtons.frame;
CGRect addLocRect = self.buttonAddLocation.frame;
CGRect connectRect = self.buttonConnect.frame;
// This will be set below in one of the if-else branches
CGFloat buttonWidth = 0;
// determine the offset from the left/right based on device and orientation
int offset = 0;
if ([self isIphone]) {
offset = (UIDeviceOrientationIsPortrait(toInterfaceOrientation)) ? OFFSET_LEFT_PORTRAIT_IPHONE : OFFSET_LEFT_LANDSCAPE_IPHONE;
} else {
offset = (UIDeviceOrientationIsPortrait(toInterfaceOrientation)) ? OFFSET_LEFT_PORTRAIT_IPAD : OFFSET_LEFT_LANDSCAPE_IPAD;
}
// change the size & location of the button frame to just the button height to maximize the area for the location list
// no matter what orientation, the button frame will fill the bottom of the screen
saveRect.size.width = _windowWidth - 2*offset;
saveRect.origin.x = offset;
// for Landscape, move the buttons to side-by-side at the bottom of the window
if (UIInterfaceOrientationIsLandscape(toInterfaceOrientation)) {
// size & move the buttons to fit side-by-side
buttonWidth = (saveRect.size.width)*.4;
addLocRect.origin.x += offset;
addLocRect.origin.y = saveRect.size.height - addLocRect.size.height ;
connectRect.origin.x = saveRect.size.width - buttonWidth - offset;
connectRect.origin.y = saveRect.size.height - connectRect.size.height;
} else { // Portrait
// move the buttons down to the bottom of the frame, stacked
// size the buttons to be fully across the screen
buttonWidth = saveRect.size.width;
addLocRect.origin.y = 0 ; // at the top of the button view
addLocRect.origin.x = 0;
connectRect.origin.y = saveRect.size.height - connectRect.size.height;
connectRect.origin.x = 0;
}
connectRect.size.width = buttonWidth;
addLocRect.size.width = buttonWidth;
self.buttonAddLocation.frame = addLocRect;
self.buttonConnect.frame = connectRect;
self.viewButtons.frame = saveRect;
}
Я добавил некоторые записи, чтобы определить, что происходит с рамками и границами в конце поворота:
NSLog(@"Post rotation:");
NSLog(@"AddLocation bounds: w=%f, h=%f, x=%f, y=%f", self.buttonAddLocation.frame.size.width, self.buttonAddLocation.frame.size.height,
self.buttonAddLocation.frame.origin.x, self.buttonAddLocation.frame.origin.y);
NSLog(@"AddLocation frame: w=%f, h=%f, x=%f, y=%f", self.buttonAddLocation.bounds.size.width, self.buttonAddLocation.bounds.size.height,
self.buttonAddLocation.bounds.origin.x, self.buttonAddLocation.bounds.origin.y);
NSLog(@"viewButtons bounds: w=%f, h=%f, x=%f, y=%f", self.viewButtons.frame.size.width, self.viewButtons.frame.size.height,
self.viewButtons.frame.origin.x, self.viewButtons.frame.origin.y);
NSLog(@"viewButtons frame: w=%f, h=%f, x=%f, y=%f", self.viewButtons.bounds.size.width, self.viewButtons.bounds.size.height,
self.viewButtons.bounds.origin.x, self.viewButtons.bounds.origin.y);
В результате чего:
Post rotation: (NOTE: Portrait, initial appearance)
AddLocation bounds: w=272.000000, h=55.000000, x=0.000000, y=0.000000
AddLocation frame: w=272.000000, h=55.000000, x=0.000000, y=0.000000
viewButtons bounds: w=272.000000, h=120.000000, x=24.000000, y=374.000000
viewButtons frame: w=272.000000, h=120.000000, x=0.000000, y=374.000000
Post rotation: (NOTE: rotate to Landscape)
AddLocation bounds: w=217.600006, h=55.000000, x=12.000000, y=65.000000
AddLocation frame: w=217.600006, h=55.000000, x=0.000000, y=0.000000
viewButtons bounds: w=544.000000, h=120.000000, x=12.000000, y=374.000000
viewButtons frame: w=544.000000, h=120.000000, x=0.000000, y=374.000000
Post rotation: (NOTE: back to Portrait)
AddLocation bounds: w=272.000000, h=55.000000, x=0.000000, y=0.000000
AddLocation frame: w=272.000000, h=55.000000, x=0.000000, y=0.000000
viewButtons bounds: w=272.000000, h=120.000000, x=24.000000, y=138.000000
viewButtons frame: w=272.000000, h=120.000000, x=0.000000, y=374.000000
Единственное различие, которое я вижу от начального до конечного, заключается в том, что viewButtons ограничивает origin.y, но если я попытаюсь установить это, все будет испорчено - кнопки внезапно появятся в верхней части экрана. Границы кнопок достаточно широки.
Что мне не хватает?
ОБНОВЛЕНО: мне не хватало того факта, что я установил распорки и пружину в IB для ограждающего вида, который боролся с кодом, который я установил для рамки вида. Я удалил код, чтобы установить фрейм, позволяя IB делать всю работу, и возился со смещениями для кнопок. Не самое красивое решение, но мне нужно его выпустить.
2 ответа
Перемещение кнопок не должно приводить к изменению области нажатия кнопки. Единственная причина, по которой я могу подумать, что это может вызвать что-то подобное:
У вас есть прозрачный вид, покрывающий части ваших кнопок после поворота. Если у вас есть прозрачные виды, сделайте их фон красным и посмотрите, что происходит после поворота.
Если ваши кнопки не являются дочерними элементами основного вида, включите параметр "Clips Subviews" в xib-файле или включите свойство clipsToBounds в коде родительского представления кнопки. Если ваши кнопки защелкиваются во время вращения, это может быть еще одной причиной вашей проблемы.
Дайте мне знать, если это поможет.
Это не совсем объяснение того, почему вы получаете такое поведение, но вам, вероятно, повезет, если вы подклассифицируете UIView, поместите туда код макета, а затем используете подкласс uiview в вашем контроллере представления. Я немного оживляю кнопки в своем собственном приложении, и использование подклассов uiview привело к наименьшему количеству царапин в отношении вращения.
… Ваша проблема viewButtons.origin.y может быть связана с тем, как вы получаете размеры экрана. Может быть. Попробуй это
UIView *rootView = [[[UIApplication sharedApplication] keyWindow] rootViewController].view; CGRect originalFrame = [[UIScreen mainScreen] bounds]; CGRect AdjustFrame = [rootView convertRect:originalFrame fromView:nil];