Cara menggambar UIView khusus yang hanya sebuah lingkaran - aplikasi iPhone

129

Bagaimana saya bisa menggambar UIView khusus yang benar-benar hanya bola (lingkaran 2D)? Apakah saya akan mengganti metode drawRect? Dan bisakah seseorang menunjukkan kode untuk menggambar lingkaran biru?

Juga, apakah tidak apa-apa untuk mengubah bingkai pandangan itu di dalam kelas itu sendiri? Atau apakah saya perlu mengubah frame dari kelas yang berbeda?

(Hanya mencoba mengatur bola memantul)

StanLe
sumber

Jawaban:

209

Anda dapat menggunakan QuartzCore dan melakukan sesuatu ini -

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];
Kal
sumber
104
FYI, agar tampilan Anda menjadi lingkaran menggunakan QuartCore, jari-jari sudut Anda harus setengah tinggi / lebar bingkai Anda. Ini adalah cara termudah untuk membuat lingkaran, tetapi belum tentu yang paling efisien. Jika kinerja sangat penting, drawRect mungkin akan menghasilkan hasil yang lebih baik.
Benjamin Mayo
4
Dan itu. 100 adalah tinggi / lebar.
Kal 5'11
3
Ya, maaf tidak mengarahkan itu padamu, Kal. Saya menyebutkan bahwa untuk StanLe kalau-kalau dia ingin menggunakan tampilan ukuran yang berbeda.
Benjamin Mayo
Jika ukuran circleView Anda tidak 100X100, cornerRadius harus menjadi (size baru) / 2
gran33
Tetapi saya perhatikan bahwa lingkaran dengan cornerradius kadang-kadang sedikit "rata" / pinggirannya terpotong. Setidaknya saat digunakan dengan pembatas. Ada yang tahu kenapa? Jari-jari persis setengah dari ukuran tampilan. Saya pikir itu mungkin masalah kliping, tetapi tidak tampak seperti itu, mencoba bahkan dengan sublapisan yang lebih kecil - masih memiliki efek yang sama.
Ixx
135

Apakah saya akan mengganti metode drawRect?

Iya:

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

Juga, apakah tidak apa-apa untuk mengubah bingkai pandangan itu di dalam kelas itu sendiri?

Idealnya tidak, tetapi Anda bisa.

Atau apakah saya perlu mengubah frame dari kelas yang berbeda?

Saya akan membiarkan orang tua mengendalikan itu.

Steve
sumber
1
Bagaimana saya bisa mengatur warna khusus, tidak hanya biru? Saya mencoba menggunakan putih dan biru seperti ini: ([self.colorOfCircle CGColor]) tetapi tidak ada yang terjadi: \
gaussblurinc
@loldop adalah self.colorOfCircle a UIColor? Apakah sudah diatur? Jika Anda meletakkan breakpoint pada garis itu dan melihat nilainya, apakah itu yang Anda harapkan? JIKA Anda menetapkan bahwa setelah fakta, Anda harus membatalkan bagian tampilan Anda yang berisi lingkaran.
Steve
9
@gaussblurinc digunakan CGContextSetFillColorWithColor(ctx, self.colorOfCircle.CGColor);, metode yang diusulkan dalam solusi CGColorGetComponentshanya bekerja dengan beberapa warna, lihat stackoverflow.com/questions/9238743/…
yonilevy
Catatan untuk siapa saja yang terjebak dalam hal ini. Alih-alih rect, saya tidak sengaja menggunakan self.frameelips. Nilai yang benar adalah self.bounds. Doh! :)
Olie
31

Berikut cara lain dengan menggunakan UIBezierPath (mungkin sudah terlambat ^^) Buat lingkaran dan tutupi UIView dengannya, sebagai berikut:

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;
Gintama
sumber
1
Sebenarnya tidak ada kebutuhan untuk membuat lapisan itu menjadi topeng; Anda bisa menggunakan layer bentuk secara langsung sebagai layer view dan memberinya warna isian. Topeng mungkin jauh lebih mahal.
Jesse Rusak
Lapisan UIView adalah CALayer jadi bagaimana kita bisa menggambar bentuk pada lapisan ini. Saya kira kita menambahkan lapisan bentuk ke lapisan tampilan tanpa menutupinya ??
Gintama
1
Anda bisa subkelas UIView dan mengganti layerClassmetode kelas untuk menjadikannya lapisan bentuk.
Jesse Rusak
@ JesseRusak, masalah yang saya alami dengan saran Anda (untuk mengatur bentuk pada lapisan UIView itu sendiri) adalah bahwa Anda harus tidak dapat menggunakan backgroundColor dengan benar. Anda perlu menerapkan fillColor dan mengatur backgroundColor menjadi clearColor, yang berarti pengguna UIView tidak akan dapat secara alami mengatur backgroundColor.
Richard Venable
25

Kontribusi saya dengan ekstensi Swift:

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

Panggil saja myView.asCircle()

Kevin ABRIOUX
sumber
pengaturan masksToBoundske true dan using selfsemuanya opsional dalam jawaban ini, tetapi masih merupakan solusi terpendek dan terbaik
Max Desiatov
17

Swift 3 - kelas khusus, mudah digunakan kembali. Menggunakan backgroundColorset in builder UI

import UIKit

@IBDesignable
class CircleBackgroundView: UIView {

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

}
Maciej
sumber
1
Luar biasa. Ini adalah pendekatan adaptif yang benar.
Womble
14

Kelas 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()
    }           
}
Vyacheslav
sumber
6

Cara lain untuk mendekati menggambar lingkaran (dan bentuk lain) adalah dengan menggunakan topeng. Anda menggambar lingkaran atau bentuk lain dengan, pertama, membuat topeng dari bentuk yang Anda butuhkan, kedua, menyediakan kotak warna Anda dan, ketiga, menerapkan topeng ke kotak warna itu. Anda dapat mengubah topeng atau warna untuk mendapatkan lingkaran khusus atau bentuk lainnya.

#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

Ini adalah output dari kode di atas:

empat lingkaran

matrix3003
sumber
2

Ada alternatif lain untuk orang malas. Anda bisa mengatur layer.cornerRadius jalur kunci untuk tampilan Anda di Interface Builder . Misalnya, jika tampilan Anda memiliki lebar = tinggi 48 , setel layer.cornerRadius = 24:

masukkan deskripsi gambar di sini

Namun, ini hanya berfungsi jika Anda memiliki ukuran tampilan statis (width/height is fixed)dan tidak menunjukkan lingkaran di pembuat antarmuka.

pengguna8675
sumber
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        
}
Mohammad Razipour
sumber