點擊按鈕,在當前視圖中間彈出一個半屏大小的綠色 UIView。
- (IBAction)showHalfScreenView:(UIButton *)sender {
CGFloat width = self.view.bounds.size.width * 0.9;
CGFloat height = self.view.bounds.size.height * 0.5;
CGFloat x = (self.view.bounds.size.width - width) * 0.5;
CGFloat y = (self.view.bounds.size.height - height) * 0.5;
UIView *customView = [[UIView alloc] initWithFrame:CGRectMake(x, y, width, height)];
customView.backgroundColor = [UIColor greenColor];
customView.layer.cornerRadius = 12;
customView.layer.masksToBounds = YES;
// 添加關閉按鈕示例
UIButton *closeBtn = [UIButton buttonWithType:UIButtonTypeSystem];
closeBtn.frame = CGRectMake(width - 50, 10, 40, 40);
[closeBtn setTitle:@"×" forState:UIControlStateNormal];
[closeBtn addTarget:self action:@selector(dismissCustomView:) forControlEvents:UIControlEventTouchUpInside];
[customView addSubview:closeBtn];
// 彈出動畫
customView.alpha = 0;
customView.transform = CGAffineTransformMakeScale(0.8, 0.8);
[self.view addSubview:customView];
[UIView animateWithDuration:0.25 animations:^{
customView.alpha = 1;
customView.transform = CGAffineTransformIdentity;
}];
}
- (void)dismissCustomView:(UIButton *)btn {
UIView *customView = btn.superview;
[UIView animateWithDuration:0.2 animations:^{
customView.alpha = 0;
customView.transform = CGAffineTransformMakeScale(0.8, 0.8);
} completion:^(BOOL finished) {
[customView removeFromSuperview];
}];
}
bounds 而非 frame 適配旋轉/安全區。addSubview 置於頂層;若需模態效果,可先添加半透明遮罩 UIView *mask = [[UIView alloc] initWithFrame:self.view.bounds]; mask.backgroundColor = [UIColor blackColor]; mask.alpha = 0.4;。transform 縮放 + alpha 淡入,體驗優於直接顯示。superview 找到容器移除,避免強引用循環。| 方案 | 適用場景 | 優勢 |
|---|---|---|
| UIPresentationController | 複雜轉場、適配尺寸類、iPad 分屏 | 系統級模態管理、自適應佈局 |
| UIAlertController (自定義 view) | 簡單彈窗、行動表單 | 零樣板代碼、語義清晰 |
| SwiftUI .sheet / .fullScreenCover | 新專案/混編 | 聲明式、狀態驅動 |
幾行代碼即可實現動態 UIView 彈出,核心在於 Frame 精確計算、層級正確添加、動畫提升體驗。複雜業務建議升級至 UIPresentationController 或 SwiftUI。