无法点击4“左侧的按钮。苹果手机 [英] Can't tap buttons on the left side of 4" iPhone

查看:70
本文介绍了无法点击4“左侧的按钮。苹果手机的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这绝对令人困惑。在3.5英寸的iPhone模拟器上,我的应用程序上的所有UIButton工作正常。但是,当我在4英寸iPhone模拟器上启动时,应用程序左侧的所有UIButton都不会收到任何点击事件。



以下是3.5英寸大小和4英寸大小的屏幕截图。在4大小,我添加了一行。在该行的左边,没有按钮接收点击事件。在该行的右边,所有按钮都表现正常。按钮2,5和8的左侧做不响应点击,但这些按钮的右侧确实响应。







UPDATE ----
感谢@iccir,我发现了更多信息。显然,我的UIWindow只有320x480而不是应该是568x320。我没有在我的代码中触摸UIWindow,只是让它变得键和可见。在我的MainWindow.xib中,我将它的IBOutlet连接到我的rootViewController。

 < UIWindow:0xc097d50; frame =(0 0; 320 480); opaque = NO; autoresize = RM + BM; gestureRecognizers =< NSArray:0xc098460> ;; layer =< UIWindowLayer:0xc097e70>> 

我很乏味。知道为什么UIWindow的大小不正确吗?

解决方案

这是一个非常常见的问题:你的UIButton超出了一个范围它的超级视图。如果 clipsToBounds / masksToBounds 设置为NO(默认值),您的UIButton仍将显示,但触摸事件不会发送给它。



让我们简化这种情况。假设一个视图控制器具有以下代码:

   - (void)viewDidLoad 
{
[super viewDidLoad ]。

UIColor * fadedRedColor = [UIColor colorWithRed:1绿色:0蓝色:0 alpha:0.25];
UIColor * fadedBlueColor = [UIColor colorWithRed:0绿色:0蓝色:1 alpha:0.25];

CGRect containerFrame = CGRectMake(25,25,100,100);
CGRect buttonFrame = CGRectMake(100,100,64,44);

UIView * container = [[UIView alloc] initWithFrame:containerFrame];

UIButton * button = [UIButton buttonWithType:UIButtonTypeSystem];
[button setTitle:@ButtonforState:UIControlStateNormal];
[button setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
[button setFrame:buttonFrame];
[button addTarget:self action:@selector(_handleButton :) forControlEvents:UIControlEventTouchUpInside];

[container setBackgroundColor:fadedRedColor];
[button setBackgroundColor:fadedBlueColor];

[container addSubview:button];

[[self view] addSubview:container];
}

- (void)_handleButton:(id)sender
{
NSLog(@Moooooo!);
}

看起来像这样:



该按钮包含在容器中,但它位于容器的边界之外(容器宽100像素,高100像素,按钮的原点是 100,100 )。 / p>

当你触摸屏幕时,UIKit将从视图层次结构(UIWindow)的顶部开始并调用 - [UIView hitTest:withEvent: ] 递归,直到找到应该处理触摸的视图。但是,在这个例子中,UIKit永远不会进入容器(因为你触及它的边界之外),因此按钮子视图不会被击中。



如果我们改为将 buttonFrame 更改为 50,50 ,它看起来像这样:



按钮与容器重叠的部分将响应触摸事件。位于容器外部的部分不会:





要调试不完全可触摸的视图,您可以尝试以下调试功能:

  static void sDebugViewThatIsntTouchable(UIView * view)
{
UIView * superview = [view superview];

while(superview){
CGRect rectInSuperview = [view convertRect:[view bounds] toView:superview];

CGPoint topLeft = CGPointMake(CGRectGetMinX(rectInSuperview),CGRectGetMinY(rectInSuperview));
CGPoint topRight = CGPointMake(CGRectGetMaxX(rectInSuperview),CGRectGetMinY(rectInSuperview));
CGPoint bottomLeft = CGPointMake(CGRectGetMinX(rectInSuperview),CGRectGetMaxY(rectInSuperview));
CGPoint bottomRight = CGPointMake(CGRectGetMaxX(rectInSuperview),CGRectGetMaxY(rectInSuperview));

if(![superview pointInside:topLeft withEvent:nil]){
NSLog(@左上角的观点%@不在superview%@里面,查看,superview);
}

if(![superview pointInside:topRight withEvent:nil]){
NSLog(@右上角的观点%@不在superview%@内,查看,superview);
}

if(![superview pointInside:bottomLeft withEvent:nil]){
NSLog(@左下角的观点%@不在superview%@里面,查看,superview);
}

if(![superview pointInside:bottomRight withEvent:nil]){
NSLog(@右下角%@不在superview%@里面,查看,superview);
}

superview = [superview superview];
}
};






编辑:
如你所说评论,罪魁祸首视图是主UIWindow,其大小为320x480而不是320x568。 在xib中启用启动时全屏修复此



当然,问题是:为什么? :)



如果你在文本编辑器中提取你的xib文件,你会发现宽度为320,高度为480的硬编码到窗口。当xib在启动时被解码时,窗口最初是用这个320x480帧构建的。



UIKit然后查询 - [UIWindow resizesToFullScreen] (私有方法)。如果返回YES,则UIWindow相当于 [self setFrame:[[self window] bounds]]



在Interface Builder中切换启动时全屏标志直接切换私有 UIWindow.resizesToFullScreen 标志。 / p>

This is absolutely confusing. On a 3.5" iPhone simulator, all of the UIButtons on my app work just fine. However, when I launch on the 4" iPhone simulator, all of the UIButtons on the left side of the app do not receive any click events.

Below are screenshots of the 3.5" size and the 4" size. On the 4" size, I've added a line. Left of that line, none of the buttons receive click events. To the right of that line, all buttons behave normally. The left side of buttons 2, 5, and 8 do not respond to clicks, but the right sides of those buttons do respond.

UPDATE---- Thanks to @iccir, I've discovered more info. Apparently, my UIWindow is only 320x480 instead of 568x320 as it should be. I'm not touching the UIWindow in my code except to make it key and visible. In my MainWindow.xib I connect its IBOutlet to my rootViewController.

<UIWindow: 0xc097d50; frame = (0 0; 320 480); opaque = NO; autoresize = RM+BM; gestureRecognizers = <NSArray: 0xc098460>; layer = <UIWindowLayer: 0xc097e70>>

I'm flabberghasted. Any idea why the UIWindow is incorrectly sized?

解决方案

This is a pretty common issue: Your UIButton is outside of the bounds of one of its superviews. If clipsToBounds/masksToBounds is set to NO (the default), your UIButton is still going to show up, but touch events aren't going to be sent to it.

Let's simplify this case. Suppose a view controller with the following code:

- (void) viewDidLoad
{
    [super viewDidLoad];

    UIColor *fadedRedColor  = [UIColor colorWithRed:1 green:0 blue:0 alpha:0.25];
    UIColor *fadedBlueColor = [UIColor colorWithRed:0 green:0 blue:1 alpha:0.25];

    CGRect containerFrame = CGRectMake(25,  25,  100, 100);
    CGRect buttonFrame    = CGRectMake(100, 100, 64,  44);

    UIView *container = [[UIView alloc] initWithFrame:containerFrame];

    UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
    [button setTitle:@"Button" forState:UIControlStateNormal];
    [button setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
    [button setFrame:buttonFrame];
    [button addTarget:self action:@selector(_handleButton:) forControlEvents:UIControlEventTouchUpInside];

    [container setBackgroundColor:fadedRedColor];
    [button    setBackgroundColor:fadedBlueColor];

    [container addSubview:button];

    [[self view] addSubview:container];
}

- (void) _handleButton:(id)sender
{
    NSLog(@"Moooooo!");
}

Which looks like this:

The button is contained in container, but it resides outside of the container's bounds (the container is 100 pixels wide and 100 pixels tall, the button's origin is at 100, 100).

When you touch the screen, UIKit is going to start at the top of the view hierarchy (UIWindow) and call -[UIView hitTest:withEvent:] recursively until it finds the view that should handle the touch. However, in this example, UIKit will never descend into the container (since you touched outside its boundary), and thus the button subview will not be hit.

If we instead change the buttonFrame to be 50, 50, it looks like this:

The part of the button that overlaps with the container will respond to touch event. The part that resides outside of the container will not:

To debug a view that isn't fully touchable, you can try a debugging function like the following:

static void sDebugViewThatIsntTouchable(UIView *view)
{
    UIView *superview = [view superview];

    while (superview) {
        CGRect rectInSuperview = [view convertRect:[view bounds] toView:superview];

        CGPoint topLeft     = CGPointMake(CGRectGetMinX(rectInSuperview), CGRectGetMinY(rectInSuperview));
        CGPoint topRight    = CGPointMake(CGRectGetMaxX(rectInSuperview), CGRectGetMinY(rectInSuperview));
        CGPoint bottomLeft  = CGPointMake(CGRectGetMinX(rectInSuperview), CGRectGetMaxY(rectInSuperview));
        CGPoint bottomRight = CGPointMake(CGRectGetMaxX(rectInSuperview), CGRectGetMaxY(rectInSuperview));

        if (![superview pointInside:topLeft withEvent:nil]) {
            NSLog(@"Top left point of view %@ not inside superview %@", view, superview);
        }

        if (![superview pointInside:topRight withEvent:nil]) {
            NSLog(@"Top right point of view %@ not inside superview %@", view, superview);
        }

        if (![superview pointInside:bottomLeft withEvent:nil]) {
            NSLog(@"Bottom left point of view %@ not inside superview %@", view, superview);
        }

        if (![superview pointInside:bottomRight withEvent:nil]) {
            NSLog(@"Bottom right point of view %@ not inside superview %@", view, superview);
        }

        superview = [superview superview];
    }
};


Edit: As you mentioned in the comments, the culprit view was the main UIWindow, which was sized to 320x480 rather than 320x568. Turning on "Full Screen at Launch" in the xib fixed this.

Of course, the question is: "Why?" :)

If you pull up your xib file in a text editor, you will notice that a width of 320 and height of 480 are hardcoded to the window. When the xib is decoded at launch time, the window is initially constructed with this 320x480 frame.

UIKit then queries -[UIWindow resizesToFullScreen] (a private method). If this returns YES, the UIWindow does the equivalent of [self setFrame:[[self window] bounds]].

Toggling the "Full Screen at Launch" flag in Interface Builder directly toggles the private UIWindow.resizesToFullScreen flag.

这篇关于无法点击4“左侧的按钮。苹果手机的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆