这绝对令人困惑.在3.5英寸iPhone模拟器上,我的应用程序上的所有UIButton工作正常.但是,当我在4英寸iPhone模拟器上启动时,应用程序左侧的所有UIButton都不会收到任何点击事件.
以下是3.5英寸大小和4英寸大小的屏幕截图.在4"大小,我添加了一行.在该行的左边,没有任何按钮接收点击事件.在该行的右侧,所有按钮都表现正常.按钮2,5和8的左侧做不响应点击,但这些按钮的右侧确实响应.
更新----感谢@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>>
Run Code Online (Sandbox Code Playgroud)
我很乏味.知道为什么UIWindow的大小不正确吗?
这是一个非常常见的问题:您的UIButton超出了其中一个超级视图的范围.如果clipsToBounds
/ masksToBounds
设置为NO(默认值),您的UIButton仍将显示,但触摸事件不会发送给它.
让我们简化这种情况.假设一个视图控制器具有以下代码:
- (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!");
}
Run Code Online (Sandbox Code Playgroud)
看起来像这样:
该按钮包含container
在内,但它位于容器边界之外(容器宽100像素,高100像素,按钮的原点位于100, 100
).
当您触摸屏幕时,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(@"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];
}
};
Run Code Online (Sandbox Code Playgroud)
编辑:正如您在评论中提到的,罪魁祸首视图是主UIWindow,其大小为320x480而不是320x568. 在xib中打开"启动时全屏"修复此问题.
当然,问题是:"为什么?" :)
如果您在文本编辑器中提取xib文件,您会注意到宽度为320,高度为480的硬编码到窗口.当xib在发射时被解码时,窗口最初是用这个320x480帧构建的.
然后UIKit查询-[UIWindow resizesToFullScreen]
(私有方法).如果返回YES,则UIWindow执行相应的操作[self setFrame:[[self window] bounds]]
.
在Interface Builder中切换"启动时全屏"标志直接切换私有UIWindow.resizesToFullScreen
标志.
归档时间: |
|
查看次数: |
3684 次 |
最近记录: |