代碼邏輯正確,UIButton 已 addSubview 到 popUp 視圖,但按鈕不顯示。
popUp.layer.masksToBounds = YES; // 關鍵問題行
masksToBounds = YES 會裁剪超出父視圖 bounds 範圍的子視圖。按鈕 frame 為 CGRectMake(0, 0, 100, 30),而 popUp 的 frame 為 CGRectMake(x, y, 125, 75),按鈕理應在範圍內,但:
popUp 可能有 cornerRadius 導致邊緣圓角裁剪(0,0) 在左上角,可能被圓角遮擋
-(void)popUpWithX:(int)x andY:(int)y {
CGRect popUpRect = CGRectMake(x, y, 125, 75);
popUp = [[UIView alloc] initWithFrame:popUpRect];
popUp.backgroundColor = [UIColor whiteColor];
popUp.layer.cornerRadius = 7.5f;
popUp.layer.masksToBounds = NO; // 關鍵修改:關閉裁剪
[self.view addSubview:popUp];
UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
button.frame = CGRectMake(12.5f, 22.5f, 100, 30); // 居中偏移
[button setTitle:@"Click me!" forState:UIControlStateNormal];
button.titleLabel.font = [UIFont systemFontOfSize:16];
[button setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
[popUp addSubview:button];
}
-(void)popUpWithX:(int)x andY:(int)y {
popUp = [[UIView alloc] initWithFrame:CGRectMake(x, y, 125, 75)];
popUp.backgroundColor = [UIColor whiteColor];
popUp.layer.cornerRadius = 7.5f;
popUp.layer.masksToBounds = YES; // 保持圓角裁剪
[self.view addSubview:popUp];
UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
// 使用 AutoLayout 確保按鈕在安全區域內
button.translatesAutoresizingMaskIntoConstraints = NO;
[button setTitle:@"Click me!" forState:UIControlStateNormal];
[popUp addSubview:button];
// 約束:按鈕居中,邊距 10pt
[NSLayoutConstraint activateConstraints:@[
[button.centerXAnchor constraintEqualToAnchor:popUp.centerXAnchor],
[button.centerYAnchor constraintEqualToAnchor:popUp.centerYAnchor],
[button.leadingAnchor constraintGreaterThanOrEqualToAnchor:popUp.leadingAnchor constant:10],
[button.trailingAnchor constraintLessThanOrEqualToAnchor:popUp.trailingAnchor constant:-10]
]];
}
| 屬性 | masksToBounds = YES | masksToBounds = NO |
|---|---|---|
| 子視圖裁剪 | 超出 bounds 裁剪 | 超出 bounds 仍顯示 |
| 圓角效果 | ✅ 生效 | ❌ 失效 (需配合 maskLayer) |
| 陰影效果 | ❌ 失效 (被裁剪) | ✅ 生效 |
| 性能影響 | 觸發離屏渲染 | 正常渲染 |
| 適用場景 | 圖片圓角、內容裁剪容器 | 需陰影、子視圖超出邊界 |
// 父視圖:負責陰影,不裁剪
popUp.layer.cornerRadius = 7.5f;
popUp.layer.masksToBounds = NO;
popUp.layer.shadowColor = [UIColor blackColor].CGColor;
popUp.layer.shadowOpacity = 0.3;
popUp.layer.shadowOffset = CGSizeMake(0, 2);
popUp.layer.shadowRadius = 4;
popUp.layer.shadowPath = [UIBezierPath bezierPathWithRoundedRect:popUp.bounds cornerRadius:7.5f].CGPath;
// 子容器:負責圓角裁剪內容
UIView *contentContainer = [[UIView alloc] initWithFrame:popUp.bounds];
contentContainer.layer.cornerRadius = 7.5f;
contentContainer.layer.masksToBounds = YES;
contentContainer.backgroundColor = [UIColor whiteColor];
[popUp addSubview:contentContainer];
// 按鈕添加到 contentContainer
[contentContainer addSubview:button];
popUp.layer.borderWidth = 1; popUp.layer.borderColor = [UIColor redColor].CGColor;NSLog(@"popUp: %@, button: %@", NSStringFromCGRect(popUp.frame), NSStringFromCGRect(button.frame));button.backgroundColor = [UIColor redColor]; 確認位置大小masksToBounds=YES 且 shadowXxx 同時設置 → 陰影消失CGRectZero → AutoLayout 未生效或未設置 framebutton.titleLabel.text = @\"Title\" → 錯誤寫法,必須用 setTitle:forState:translatesAutoresizingMaskIntoConstraints → 手動 frame 與 AutoLayout 衝突