Sadece bir daire olan özel bir UIView nasıl çizilir - iPhone uygulaması


129

Kelimenin tam anlamıyla bir top (2B daire) olan özel bir UIView çizmeye nasıl başlayabilirim? DrawRect yöntemini geçersiz kılar mıyım? Ve birisi bana mavi bir daire çizmenin kodunu gösterebilir mi?

Ayrıca, bu görüşün çerçevesini sınıfın içinde değiştirmek doğru olur mu? Yoksa farklı bir sınıftan çerçeveyi değiştirmem gerekiyor mu?

(sadece etrafta zıplayan bir top kurmaya çalışıyorum)

Yanıtlar:


209

QuartzCore'u kullanabilir ve bunu yapabilirsiniz -

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
Bilginize, QuartCore kullanarak görünümünüzün bir daire olması için, köşe yarıçapınızın çerçeve yüksekliğiniz / genişliğinizin yarısı olması gerekir. Bu, bir çember oluşturmanın en kolay yoludur, ancak mutlaka en verimli yol değildir. Performans hayati önem taşıyorsa, drawRect muhtemelen daha iyi sonuçlar verecektir.
Benjamin Mayo

4
Ve budur. 100 yükseklik / genişliktir.
Kal

3
Evet, bunu sana yöneltmediğim için üzgünüm Kal. StanLe'ye farklı boyutlarda görünümler kullanmak istemesi ihtimaline karşı bahsediyordum.
Benjamin Mayo

CircleView boyutunuz 100X100 değilse, cornerRadius (yeni boyut) / 2
gran33

Ancak köşe yarıçapı olan dairenin bazen biraz "düz" / kırpılmış kenarları olduğunu fark ettim. En azından bordür ile kullanıldığında. Herhangi bir fikrin neden? Yarıçap, tam olarak görüş boyutunun yarısı kadardır. Kırpma sorunu olabileceğini düşündüm, ancak öyle görünmüyor, daha küçük bir alt katmanla bile denendi - hala aynı etkiye sahip.
Ixx

135

DrawRect yöntemini geçersiz kılar mıyım?

Evet:

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

Ayrıca, bu görüşün çerçevesini sınıfın içinde değiştirmek doğru olur mu?

İdeal olarak hayır, ama yapabilirsin.

Yoksa farklı bir sınıftan çerçeveyi değiştirmem gerekiyor mu?

Ebeveynin bunu kontrol etmesine izin verirdim.


1
Yalnızca mavi değil, özel renkleri nasıl ayarlayabilirim? Beyaz ve maviyi şu şekilde kullanmaya çalışıyorum: ([self.colorOfCircle CGColor]) ama hiçbir şey olmuyor: \
gaussblurinc

@loldop self.colorOfCircle bir UIColor mu? Ayarlandı mı? Bu satıra bir kesme noktası koyarsanız ve değere bakarsanız, beklediğiniz bu mu? Bunu gerçeğin ardından ayarlarsanız, görünümünüzün daireyi içeren kısmını geçersiz kılmanız gerekir.
Steve

9
@gaussblurinc kullanımı CGContextSetFillColorWithColor(ctx, self.colorOfCircle.CGColor);, çözümde önerilen yöntem CGColorGetComponentsyalnızca bazı renklerle çalışır, bkz. stackoverflow.com/questions/9238743/…
yonilevy

Bu konuda takılıp kalan herkese not alın. Bunun yerine rect, yanlışlıkla self.frameelips için kullandım . Doğru değer self.bounds. D'oh! :)
Olie

31

İşte UIBezierPath'i kullanmanın başka bir yolu (belki çok geç ^^) Bir daire oluşturun ve aşağıdaki gibi UIView maskeleyin:

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
O şekil katmanını maske yapmaya gerçekten gerek yok; şekil katmanını doğrudan görünüm katmanı olarak kullanabilir ve ona bir dolgu rengi verebilirsiniz. Maske muhtemelen çok daha pahalıdır.
Jesse Rusak

UIView katmanı CALayer'dır, bu yüzden bu katmana nasıl şekil çizebiliriz. Görüntünün katmanına maskelemeden şekil katmanı eklediğimizi varsayıyorum ??
Gintama

1
layerClassBir şekil katmanı yapmak için UIView öğesini alt sınıflandırabilir ve sınıf yöntemini geçersiz kılabilirsiniz .
Jesse Rusak

@JesseRusak, önerinizle ilgili yaşadığım sorun (şekli UIView katmanının kendisine ayarlamak için), backgroundColor'ı düzgün kullanamamanız gerektiğidir. Bir fillColor uygulamanız ve backgroundColor öğesini clearColor olarak ayarlamanız gerekir; bu, UIView kullanıcısının backgroundColor değerini doğal olarak ayarlayamayacağı anlamına gelir.
Richard Venable

25

Swift uzantısı ile katkım:

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

Sadece ara myView.asCircle()


ayarını masksToBoundstrue ve kullanan selfbu cevabı tüm isteğe bağlıdır, ama yine de en kısa ve en iyi çözümdür
Max Desiatov

17

Swift 3 - özel sınıf, yeniden kullanımı kolay. backgroundColorUI oluşturucudaki seti kullanır

import UIKit

@IBDesignable
class CircleBackgroundView: UIView {

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

}

1
Mükemmel. Bu doğru, uyarlanabilir yaklaşımdır.
Womble

14

Swift 3 sınıfı:

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

Daire (ve diğer şekiller) çizimine yaklaşmanın bir başka yolu da maske kullanmaktır. Önce ihtiyacınız olan şekillerin maskelerini yaparak daireler veya başka şekiller çizersiniz, ikinci olarak renginizin karelerini sağlarsınız ve üçüncüsü bu renk karelerine maskeler uygularsınız. Yeni bir özel daire veya başka bir şekil elde etmek için maskeyi veya rengi değiştirebilirsiniz.

#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

İşte yukarıdaki kodun çıktısı:

dört daire


2

Tembel insanlar için başka bir alternatif var. Görünümünüz için layer.cornerRadius anahtar yolu Arayüz Oluşturucu'da ayarlayabilirsiniz . Örneğin, görünümünüzün genişliği = yüksekliği 48 ise , layer.cornerRadius = 24şunları ayarlayın :

görüntü açıklamasını buraya girin

Ancak, bu yalnızca görünümün statik boyutuna sahipseniz (width/height is fixed)ve arayüz oluşturucudaki daireyi göstermiyorsa işe yarar .


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        
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.