วิธีวาด UIView แบบกำหนดเองที่เป็นวงกลม - แอพ iPhone


129

ฉันจะวาด UIView แบบกำหนดเองที่เป็นเพียงลูกบอล (วงกลม 2 มิติ) ได้อย่างไร ฉันจะแทนที่เมธอด drawRect หรือไม่ และใครช่วยแสดงรหัสสำหรับวาดวงกลมสีฟ้าได้ไหม

นอกจากนี้จะสามารถเปลี่ยนกรอบของมุมมองนั้นภายในชั้นเรียนได้หรือไม่ หรือฉันต้องเปลี่ยนเฟรมจากคลาสอื่น?

(แค่พยายามตั้งค่าลูกบอลที่กระเด้งไปมา)

คำตอบ:


209

คุณสามารถใช้ QuartzCore และทำสิ่งนี้ได้ -

self.circleView = [[UIView alloc] initWithFrame:CGRectMake(10,20,100,100)];
self.circleView.alpha = 0.5;
self.circleView.layer.cornerRadius = 50;  // half the width/height
self.circleView.backgroundColor = [UIColor blueColor];

104
FYI เพื่อให้มุมมองของคุณเป็นวงกลมโดยใช้ QuartCore รัศมีมุมของคุณจะต้องสูงครึ่งหนึ่งของความสูง / ความกว้างของเฟรม นี่เป็นวิธีที่ง่ายที่สุดในการสร้างวงกลม แต่ไม่จำเป็นต้องมีประสิทธิภาพสูงสุด หากประสิทธิภาพมีความสำคัญ drawRect อาจให้ผลลัพธ์ที่ดีกว่า
Benjamin Mayo

4
และมันก็เป็น. 100 คือความสูง / ความกว้าง
Kal

3
ใช่ขอโทษที่ไม่ได้กำกับเรื่องนั้นกับคุณ Kal ฉันพูดถึง StanLe ในกรณีที่เขาต้องการใช้มุมมองขนาดต่างๆ
Benjamin Mayo

หากขนาด circleView ของคุณไม่ใช่ 100X100 cornerRadius ควรเป็น (ขนาดใหม่) / 2
gran33

แต่ฉันสังเกตว่าวงกลมที่มีรัศมีมุมบางครั้งมี "แบน" / ขอบตัดเล็กน้อย อย่างน้อยเมื่อใช้กับเส้นขอบ มีความคิดว่าทำไม? รัศมีเท่ากับครึ่งหนึ่งของขนาดของมุมมอง ฉันคิดว่ามันอาจจะเป็นปัญหาในการตัด แต่ดูเหมือนจะไม่เป็นเช่นนั้นลองแม้จะใช้ชั้นย่อยที่เล็กกว่าก็ยังได้ผลเหมือนเดิม
Ixx

135

ฉันจะแทนที่เมธอด drawRect หรือไม่

ใช่:

- (void)drawRect:(CGRect)rect
{
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    CGContextAddEllipseInRect(ctx, rect);
    CGContextSetFillColor(ctx, CGColorGetComponents([[UIColor blueColor] CGColor]));
    CGContextFillPath(ctx);
}

นอกจากนี้จะสามารถเปลี่ยนกรอบของมุมมองนั้นภายในชั้นเรียนได้หรือไม่

ตามหลักการแล้ว แต่คุณทำได้

หรือฉันต้องเปลี่ยนเฟรมจากคลาสอื่น?

ฉันจะปล่อยให้ผู้ปกครองควบคุมสิ่งนั้น


1
ฉันจะตั้งค่าสีที่กำหนดเองไม่ใช่เฉพาะสีน้ำเงินได้อย่างไร ฉันพยายามใช้สีขาวและสีน้ำเงินแบบนี้: ([self.colorOfCircle CGColor]) แต่ไม่มีอะไรเกิดขึ้น: \
gaussblurinc

@loldop เป็น self.colorOfCircle เป็น UIColor? ตั้งไว้หรือเปล่า หากคุณวางเบรกพอยต์ในบรรทัดนั้นและดูที่ค่าเป็นสิ่งที่คุณคาดหวังหรือไม่? หากคุณตั้งค่าตามความเป็นจริงคุณจะต้องทำให้ส่วนของมุมมองที่มีแวดวงนั้นเป็นโมฆะ
สตีฟ

9
การใช้ @gaussblurinc CGContextSetFillColorWithColor(ctx, self.colorOfCircle.CGColor);วิธีการที่เสนอในโซลูชันCGColorGetComponentsใช้ได้กับบางสีเท่านั้นดูstackoverflow.com/questions/9238743/…
yonilevy

หมายเหตุสำหรับใครก็ตามที่ติดอยู่กับสิ่งนี้ แทนที่จะrectใช้self.frameเป็นวงรีโดยไม่ได้ตั้งใจ self.boundsค่าที่ถูกต้องคือ D'โอ้! :)
Olie

31

นี่เป็นอีกวิธีหนึ่งในการใช้ UIBezierPath (อาจจะสายเกินไป ^^) สร้างวงกลมและมาสก์ UIView ด้วยดังต่อไปนี้:

UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)];
view.backgroundColor = [UIColor blueColor];

CAShapeLayer *shape = [CAShapeLayer layer];
UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:view.center radius:(view.bounds.size.width / 2) startAngle:0 endAngle:(2 * M_PI) clockwise:YES];
shape.path = path.CGPath;
view.layer.mask = shape;

1
ไม่จำเป็นต้องทำให้เลเยอร์รูปร่างนั้นเป็นหน้ากาก คุณสามารถใช้เลเยอร์รูปร่างโดยตรงเป็นเลเยอร์ของมุมมองและให้สีเติม หน้ากากอาจมีราคาแพงกว่าอย่างเห็นได้ชัด
Jesse Rusak

เลเยอร์ของ UIView คือ CALayer ดังนั้นเราจะวาดรูปร่างบนเลเยอร์นี้ได้อย่างไร ฉันคิดว่าเราเพิ่มเลเยอร์รูปร่างเพื่อดูเลเยอร์ของโดยไม่ปิดบัง ??
Gintama

1
คุณสามารถ subclass UIView และลบล้างlayerClassเมธอดคลาสเพื่อทำให้เป็นเลเยอร์รูปร่างได้
Jesse Rusak

@JesseRusak ปัญหาที่ฉันมีกับคำแนะนำของคุณ (ในการกำหนดรูปร่างบนเลเยอร์ของ UIView เอง) คือคุณต้องใช้ backgroundColor ไม่ถูกต้อง คุณจะต้องใช้ FillColor และตั้งค่า backgroundColor เป็น clearColor ซึ่งหมายความว่าผู้ใช้ UIView จะไม่สามารถตั้งค่า backgroundColor ตามธรรมชาติได้
Richard Venable

25

การมีส่วนร่วมของฉันกับส่วนขยาย Swift:

extension UIView {
    func asCircle() {
        self.layer.cornerRadius = self.frame.width / 2;
        self.layer.masksToBounds = true
    }
}

เพียงโทร myView.asCircle()


การตั้งค่าmasksToBoundsเป็นจริงและการใช้งานselfเป็นทางเลือกทั้งหมดในคำตอบนี้ แต่ก็ยังเป็นทางออกที่สั้นและดีที่สุด
Max Desiatov

17

Swift 3 - คลาสที่กำหนดเองและใช้ซ้ำได้ง่าย ใช้backgroundColorชุดในตัวสร้าง UI

import UIKit

@IBDesignable
class CircleBackgroundView: UIView {

    override func layoutSubviews() {
        super.layoutSubviews()
        layer.cornerRadius = bounds.size.width / 2
        layer.masksToBounds = true
    }

}

1
ยอดเยี่ยม นี่คือแนวทางที่ถูกต้องและปรับเปลี่ยนได้
Womble

14

คลาสSwift 3 :

import UIKit

class CircleView: UIView {

    override func draw(_ rect: CGRect) {
        guard let context = UIGraphicsGetCurrentContext() else {return}

        context.addEllipse(in: rect)
        context.setFillColor(.blue.cgColor)
        context.fillPath()
    }           
}

6

อีกวิธีหนึ่งในการเข้าใกล้วงกลม (และรูปร่างอื่น ๆ ) คือการใช้มาสก์ คุณวาดวงกลมหรือรูปทรงอื่น ๆ โดยขั้นแรกสร้างมาสก์ของรูปทรงที่คุณต้องการอันดับสองใส่สี่เหลี่ยมของสีของคุณและอย่างที่สามใช้มาสก์กับสี่เหลี่ยมสีเหล่านั้น คุณสามารถเปลี่ยนหน้ากากหรือสีเพื่อรับวงกลมที่กำหนดเองใหม่หรือรูปร่างอื่น ๆ

#import <QuartzCore/QuartzCore.h>

@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIView *area1;
@property (weak, nonatomic) IBOutlet UIView *area2;
@property (weak, nonatomic) IBOutlet UIView *area3;
@property (weak, nonatomic) IBOutlet UIView *area4;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    self.area1.backgroundColor = [UIColor blueColor];
    [self useMaskFor: self.area1];

    self.area2.backgroundColor = [UIColor orangeColor];
    [self useMaskFor: self.area2];

    self.area3.backgroundColor = [UIColor colorWithRed: 1.0 green: 0.0 blue: 0.5 alpha:1.0];
    [self useMaskFor: self.area3];

    self.area4.backgroundColor = [UIColor colorWithRed: 1.0 green: 0.0 blue: 0.5 alpha:0.5];
    [self useMaskFor: self.area4];        
}

- (void)useMaskFor: (UIView *)colorArea {        
    CALayer *maskLayer = [CALayer layer];
    maskLayer.frame = colorArea.bounds;
    UIImage *maskImage = [UIImage imageNamed:@"cirMask.png"];
    maskLayer.contents = (__bridge id)maskImage.CGImage;
    colorArea.layer.mask = maskLayer;
}

@end

นี่คือผลลัพธ์ของโค้ดด้านบน:

สี่วงกลม


2

มีทางเลือกอื่นสำหรับคนขี้เกียจ คุณสามารถตั้งค่าlayer.cornerRadius เส้นทางสำคัญสำหรับมุมมองของคุณในInterface Builder ตัวอย่างเช่นหากมุมมองของคุณมีความกว้าง = ความสูง 48ให้ตั้งค่าlayer.cornerRadius = 24:

ป้อนคำอธิบายภาพที่นี่

อย่างไรก็ตามสิ่งนี้ใช้ได้เฉพาะเมื่อคุณมีขนาดคงที่ของมุมมอง(width/height is fixed)และไม่แสดงวงกลมในตัวสร้างอินเทอร์เฟซ


1

Swift 3 - Xcode 8.1

@IBOutlet weak var myView: UIView!

override func viewDidLoad() {
    super.viewDidLoad() 

    let size:CGFloat = 35.0
    myView.bounds = CGRect(x: 0, y: 0, width: size, height: size)
    myView.layer.cornerRadius = size / 2
    myView.layer.borderWidth = 1
    myView.layer.borderColor = UIColor.Gray.cgColor        
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.