设备旋转后iOS按钮点击区域

时间:2013-04-19 16:02:41

标签: ios uibutton screen-rotation

旋转后我遇到了几个按钮的问题。在纵向模式下,按钮堆叠在屏幕底部。在横向时,它们会被移动并调整大小并排在屏幕底部。这一切都很好,按钮行为正常。但是,如果手机然后旋转回肖像,则按钮的分接区域是错误的 - 只有左侧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 bounds origin.y,但是如果我尝试设置它,事情就搞砸了 - 按钮突然出现在屏幕的顶部。按钮边界足够宽。

我错过了什么?

更新:我错过了这样一个事实:我在IB中为封闭视图设置了struts和一个弹簧,这与我设置视图框架的代码作斗争。我删除了代码以设置框架,让IB完成工作,并摆弄按钮的偏移。不是最漂亮的解决方案,但我需要释放它。

2 个答案:

答案 0 :(得分:4)

移动按钮不应导致修改按钮的“可点击”区域。我认为会导致这种情况发生的唯一原因是:

  1. 您有一个透明视图,覆盖了部分按钮 回转。如果您有透明视图,请创建其背景 颜色为红色,看看旋转后会发生什么。

  2. 如果您的按钮不是主视图的子项,请启用“剪辑” 子视图“在xib文件中设置或打开clipsToBounds 按钮父视图的代码中的属性。如果你的按钮 在旋转过程中被剪裁,这可能是你的另一个原因 问题。

  3. 如果有任何帮助,请告诉我。

答案 1 :(得分:2)

这并不能解释为什么你会得到这种行为,但你可能会更好地为UIView创建子类,将布局代码放在那里,然后在视图控制器中使用UIView子类。我在我自己的应用程序中为按钮设置了相当多的动画,并且子类化UIView导致了关于旋转的最小量的头部划痕。

... 您的viewButtons.origin.y问题可能与您获取屏幕尺寸的方式有关。也许。试试这个

UIView *rootView = [[[UIApplication sharedApplication] keyWindow] 
                                   rootViewController].view;
CGRect originalFrame = [[UIScreen mainScreen] bounds];
CGRect adjustedFrame = [rootView convertRect:originalFrame fromView:nil];