一半屏幕无法点击

Posted

技术标签:

【中文标题】一半屏幕无法点击【英文标题】:Half of screen is unclickable 【发布时间】:2013-12-21 02:16:22 【问题描述】:

我有一个非常令人困惑的问题。我有一个UIView,上面有几个按钮。无论出于何种原因,当您旋转视图(模拟器或设备)时,屏幕右半部分的按钮变得无法点击。不可点击的区域类似于刚刚旋转的方向的大小。例如,如果您的 iPhone 处于纵向模式并将其转为横向模式,则不可点击区域大约是 iPhone 纵向屏幕的宽度。起初我认为它们一定是屏幕上拦截点击的那部分顶部的不可见元素,但后来我将屏幕上所有内容的 alpha 设置为 1 并设置每个元素的边框颜色(通过CALayer)所以我可以检查。令人惊讶的是,一切都在它应该在的地方,而且它们没有(我能找到)覆盖按钮。我什至尝试通过[self.view bringSubviewToFront:self.BUTTON]将按钮放在前面

我有一个函数可以在加载或旋转视图时处理设置所有内容的框架。这个函数调用是我的旋转函数和viewWillAppear 函数中唯一的东西。无法点击的按钮问题仅在设备旋转时发生。例如,如果您将设备从纵向旋转到横向并且按钮变得无法点击,那么您所要做的就是从底部的选项卡栏中选择另一个选项卡以加载另一个视图,然后当您用查看这个奇怪的问题(没有旋转任何东西),按钮都是可点击的并且按预期工作。关于这个问题我无法理解的是,在viewWillAppeardidRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation 中调用了完全相同的代码,但只有在旋转设备并单击按钮时,这些按钮才无法单击。如果用户单击另一个选项卡,然后返回存在此问题的选项卡,则按钮现在可以按预期工作。

更复杂的是,这个问题只发生在 ios7 上。在 ios6 上一切都很好。

我已经尝试了所有我能想到的方法,但我不知道为什么会发生这种情况。

以下是部分代码:

-(void)loadCorrectElements

    if(self.interfaceOrientation == UIInterfaceOrientationPortrait || self.interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown)

        //portrait
        int amountToSubtract = ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0)?20:0;
        int distanceBetweenLabels = (self.view.bounds.size.height - amountToSubtract) / 5;
        self.viewForLabels.frame = CGRectMake(0, distanceBetweenLabels, self.view.bounds.size.width, distanceBetweenLabels*3);

        int heightOfLabels = (self.viewForLabels.bounds.size.height / 3) - 20;
        int ycoordOfLongitudeLabel = (self.viewForLabels.bounds.size.height / 3) + 10;
        int ycoordOfAltitudeLabel = ((self.viewForLabels.bounds.size.height / 3) * 2) + 10;
        self.latitudeLabel.frame = CGRectMake(10, 10, self.view.bounds.size.width-20, heightOfLabels);
        self.longitudeLabel.frame = CGRectMake(10, ycoordOfLongitudeLabel, self.view.bounds.size.width-20, heightOfLabels);
        self.altitudeLabel.frame = CGRectMake(10, ycoordOfAltitudeLabel, self.view.bounds.size.width-20, heightOfLabels);

        self.optionsButton.frame = CGRectMake(self.view.bounds.size.width-36, self.view.bounds.size.height-36, 26, 26);

        int ycoordForSpeakButton = self.viewForLabels.frame.origin.y + self.viewForLabels.frame.size.height + 10;
        self.speakButton.frame = CGRectMake(self.view.bounds.size.width - 40, ycoordForSpeakButton, 30, 25);

        int heightOfRecordLabel = ((self.view.bounds.size.height - (self.viewForLabels.frame.origin.y + self.viewForLabels.frame.size.height))) / 2;
        int yCoordForRecordButton = self.viewForLabels.frame.origin.y + self.viewForLabels.frame.size.height + (((self.view.bounds.size.height - (self.viewForLabels.frame.origin.y + self.viewForLabels.frame.size.height)) / 2) - (heightOfRecordLabel / 2));
        self.recordButton.frame = CGRectMake((self.view.bounds.size.width / 2) - (self.view.bounds.size.width / 4) / 2, yCoordForRecordButton, self.view.bounds.size.width / 4, heightOfRecordLabel);

        int ycoordForOldCoordsButton = self.viewForLabels.frame.origin.y + self.viewForLabels.frame.size.height + (((self.view.bounds.size.height - (self.viewForLabels.frame.origin.y + self.viewForLabels.frame.size.height))) / 2 - 12);
        self.oldCoordsButton.frame = CGRectMake(10, ycoordForOldCoordsButton, 24, 24);
    else

        //landscape
        int amountToSubtract = ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0)?20:0;
        self.viewForLabels.frame = CGRectMake(5, 5 + amountToSubtract, self.view.bounds.size.width-10, self.view.bounds.size.height - 60);

        int heightOfLabels = (self.viewForLabels.bounds.size.height - amountToSubtract) / 3;
        int ycoordOfLongitudeLabel = (self.viewForLabels.bounds.size.height / 3);
        int ycoordOfAltitudeLabel = ((self.viewForLabels.bounds.size.height / 3) * 2);

        self.latitudeLabel.frame = CGRectMake(5, 0, self.view.bounds.size.width-20, heightOfLabels);
        self.longitudeLabel.frame = CGRectMake(5, ycoordOfLongitudeLabel, self.view.bounds.size.width-20, heightOfLabels);
        self.altitudeLabel.frame = CGRectMake(5, ycoordOfAltitudeLabel, self.view.bounds.size.width-20, heightOfLabels);

        int yCoordForOptionsButton = self.viewForLabels.frame.origin.y + self.viewForLabels.frame.size.height + (((self.view.bounds.size.height - (self.viewForLabels.frame.origin.y + self.viewForLabels.frame.size.height)) / 2) - 13);
        self.optionsButton.frame = CGRectMake(self.view.bounds.size.width - 31, yCoordForOptionsButton, 26, 26);

        self.speakButton.frame = CGRectMake(self.optionsButton.frame.origin.x - 40, self.optionsButton.frame.origin.y, 30, 25);

        int heightOfRecordLabel = ((self.view.bounds.size.height - (self.viewForLabels.frame.origin.y + self.viewForLabels.frame.size.height))) / 2;
        int yCoordForRecordButton = self.viewForLabels.frame.origin.y + self.viewForLabels.frame.size.height + (((self.view.bounds.size.height - (self.viewForLabels.frame.origin.y + self.viewForLabels.frame.size.height)) / 2) - (heightOfRecordLabel / 2));
        self.recordButton.frame = CGRectMake((self.view.bounds.size.width / 2) - (self.view.bounds.size.width / 4) / 2, yCoordForRecordButton, self.view.bounds.size.width / 4, heightOfRecordLabel);
        int ycoordForOldCoordsButton = self.viewForLabels.frame.origin.y + self.viewForLabels.frame.size.height + (((self.view.bounds.size.height - (self.viewForLabels.frame.origin.y + self.viewForLabels.frame.size.height))) / 2 - 12);
        self.oldCoordsButton.frame = CGRectMake(10, ycoordForOldCoordsButton, 24, 24);

    //end if

    [self setLabelText:self.latitudeLabel text:self.latitudeLabel.text];
    [self setLabelText:self.longitudeLabel text:self.longitudeLabel.text];
    [self setLabelText:self.altitudeLabel text:self.altitudeLabel.text];

    self.mainContainer.frame = CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height);

//end method

-(void)viewWillAppear:(BOOL)animated
    [self loadCorrectElements];
//end function

-(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
    [self loadCorrectElements];
//end function

这是 ViewDidLoad 中的按钮声明

 //create options button
        self.optionsButton = [UIButton buttonWithType:UIButtonTypeCustom];
        [self.optionsButton setImage:[UIImage imageNamed:@"Share.png"] forState:UIControlStateNormal];
        [self.optionsButton addTarget:self action:@selector(shareButtonPressed) forControlEvents:UIControlEventTouchUpInside];
        [self.mainContainer addSubview:self.optionsButton];

        //create speak button
        self.speakButton = [UIButton buttonWithType:UIButtonTypeCustom];
        [self.speakButton setImage:[UIImage imageNamed:@"Sound.png"] forState:UIControlStateNormal];
        [self.speakButton addTarget:self action:@selector(speakButtonPressed) forControlEvents:UIControlEventTouchUpInside];
        [self.mainContainer addSubview:self.speakButton];

        //create record button
        self.recordButton = [UIButton buttonWithType:UIButtonTypeCustom];
        self.recordButton.backgroundColor = self.blueColor;
        [self.recordButton setTitle:NSLocalizedString(@"RECORD", nil) forState:UIControlStateNormal];
        self.recordButton.layer.cornerRadius = 3.0f;
        [self.recordButton addTarget:self action:@selector(recordButtonClicked) forControlEvents:UIControlEventTouchUpInside];
        [self.recordButton setTitleColor:[UIColor lightGrayColor] forState:UIControlStateHighlighted];
        [self.mainContainer addSubview:self.recordButton];

        //set up old coord button
        self.oldCoordsButton = [UIButton buttonWithType:UIButtonTypeCustom];
        [self.oldCoordsButton setImage:[UIImage imageNamed:@"Clock.png"] forState:UIControlStateNormal];
        [self.oldCoordsButton addTarget:self action:@selector(oldCoordsButtonClicked) forControlEvents:UIControlEventTouchUpInside];
        [self.mainContainer addSubview:self.oldCoordsButton];

【问题讨论】:

【参考方案1】:

看起来 viewController 的视图或 mainWindow 没有在旋转时调整大小。

正如 Jesse Rusak 在他的回答中提到的那样,在代码中进行如此多的计算来设置按钮来处理旋转确实没有任何意义。

使用 AutoResizingMask。它可以取出数以亿计的代码行。一旦你掌握了它,你就可以转到自动布局。

您的自动调整大小掩码可以像这样设置

self.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | 
                             UIViewAutoresizingFlexibleHeight |  
                             UIViewAutoresizingFixedBottomMargin |
                             UIViewAutoresizingFixedLeftMargin |        
                             UIViewAutoresizingFixedRightMargin | 
                             UIViewAutoresizingFixedTopMargin;

同样,您可以为按钮设置自动调整大小的掩码。它会负责旋转定位。尝试几个不同的选项,您很快就会掌握窍门。

【讨论】:

【参考方案2】:

在我看来,您的按钮的超级视图可能没有正确调整大小。 (视图仍然可以在其父视图之外可见,但它们不会是交互式的。)

我建议使用Reveal 或Spark Inspector 之类的工具来查看旋转后视图的位置,以便找出未正确调整视图的大小。

顺便说一句,您可能希望将来考虑在布局中使用 nib 和自动布局,因为它会消除上述所有代码。

【讨论】:

以上是关于一半屏幕无法点击的主要内容,如果未能解决你的问题,请参考以下文章

如何将最小高度设置为查看屏幕的 100% 和页面的一半?

重新定位超出屏幕框架的视图

HTML 编写页面在手机中无法全屏显示

为啥 ViewController 只占屏幕的一半?

ios中给uiscrollview添加的全屏子视图为啥宽度只显示屏幕的一半

安卓手机上一个5.0寸按竖屏屏幕的一半屏幕分辨率约是多少乘多少