在 drawRect: 中繪製貝塞爾路徑、設置填充顏色、圖片圖案,結果顯示為黑色矩形,而非預期圖形。
CGRectMake(280.0, 3.0, 30, 30),若 View 寬度小於 310pt,繪圖區域超出邊界,被裁剪或異常渲染。drawRect: 的參數 rect 即當前需繪製區域 (通常等於 self.bounds),所有繪圖座標應相對於此區域計算。CGContextSetPatternPhase 配合硬編碼座標易產生不可預期結果。- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
// 1. 顏色定義
UIColor *fillColor = [UIColor colorWithRed:0.102 green:0.737 blue:0.612 alpha:1];
UIColor *strokeColor = [UIColor colorWithRed:0.925 green:0.941 blue:0.945 alpha:0.004]; // 極低透明度,幾乎透明
// 2. 圖片圖案 (確保圖片存在)
UIImage *image = [UIImage imageNamed:@"image"];
if (!image) {
NSLog(@"圖片 'image' 未找到,使用純色填充");
// 降級處理
}
UIColor *patternColor = image ? [UIColor colorWithPatternImage:image] : fillColor;
// 3. 動態計算繪圖區域 (相對於 rect/bounds)
CGFloat buttonSize = 30.0;
CGFloat margin = 10.0;
CGFloat x = rect.size.width - buttonSize - margin; // 右側邊距
CGFloat y = margin; // 頂部邊距
CGRect buttonRect = CGRectMake(x, y, buttonSize, buttonSize);
// 4. 繪製主按鈕背景
UIBezierPath *buttonPath = [UIBezierPath bezierPathWithRect:buttonRect];
[fillColor setFill];
[buttonPath fill];
[strokeColor setStroke];
buttonPath.lineWidth = 1;
[buttonPath stroke];
// 5. 繪製圖片圖案覆蓋層 (同樣區域)
if (image) {
UIBezierPath *patternPath = [UIBezierPath bezierPathWithRect:buttonRect];
CGContextSaveGState(context);
// 圖案相位可根據需求設置,通常用 (0,0) 或按鈕原點
CGContextSetPatternPhase(context, CGSizeMake(buttonRect.origin.x, buttonRect.origin.y));
[patternColor setFill];
[patternPath fill];
CGContextRestoreGState(context);
[strokeColor setStroke];
[patternPath stroke];
}
}
| 原代碼問題 | 修正方案 |
|---|---|
硬編碼 CGRectMake(280, 3, 30, 30) | 動態計算:x = rect.size.width - size - margin |
| 未檢查圖片是否存在 | 添加 if (!image) 降級處理 |
| Stroke 顏色 alpha=0.004 (幾乎透明) | 確認是否為預期,建議 alpha=1.0 可見邊框 |
| Pattern Phase 硬編碼 (86, 33) | 相對於繪圖區域原點設置 |
drawRect: 開頭打印 NSLog(@"drawRect: %@", NSStringFromCGRect(rect)) 確認實際繪製區域大小。UIColor.redColor.setFill; UIRectFill(rect); 先填充整個區域驗證 View 可見範圍。rect (即 bounds) 計算**,不依賴固定像素值。CAShapeLayer、CAGradientLayer 等 Core Animation 圖層,性能更優且易維護。遵循「座標相對化、資源驗證、邊界感知」三原則,可避免 90% 的 drawRect: 異常渲染問題。