Як намалювати користувацький UIView, який є лише колом - додаток iPhone


129

Як би я подумав про те, щоб намалювати користувальницький UIView, який буквально є лише кулькою (2D-коло)? Чи просто би я перекрив метод 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, ймовірно, дасть кращі результати.
Бенджамін Майо

4
І воно є. 100 - висота / ширина.
Кал

3
Так, вибачте, що не спрямував це на вас, Кал. Я згадував про це StanLe у випадку, якщо він захотів використовувати різні розміри поглядів.
Бенджамін Майо

Якщо розмір вашого колаView не 100X100, кутомRadius має бути (новий розмір) / 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'oh! :)
Олі,

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
Насправді не потрібно робити цей шар форми маскою; ви можете просто використовувати шар форми безпосередньо як шар перегляду та надати йому колір заливки. Маска, мабуть, значно дорожча.
Джессі Русак

Шар UIView - це CALayer, тож як ми можемо намалювати форму на цьому шарі. Я думаю, що ми додаємо шар форми для перегляду шару, не маскуючи його ??
Gintama

1
Ви можете підкласировать UIView і замінити layerClassметод класу, щоб зробити його шаром форми.
Джессі Русак

@JesseRusak, проблема, яку я маю з вашою пропозицією (встановити форму на самому шарі UIView), полягає в тому, що ви не повинні правильно використовувати backgroundColor. Вам потрібно буде застосувати fillColor і встановити backgroundColor на clearColor, а це означає, що користувач UIView не зможе встановити backgroundColor.
Річард Венебл

25

Мій внесок із розширенням Swift:

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

Просто зателефонуйте myView.asCircle()


Встановити masksToBoundsна істину та використовувати self- у цій відповіді необов’язково, але це все-таки найкоротше та найкраще рішення
Макс Десятов

17

Swift 3 - спеціальний клас, який легко використовувати повторно. Він використовує backgroundColorнабір у конструкторі інтерфейсу

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 ключовий шлях для перегляду в Інтерфейсі . Наприклад, якщо ваш перегляд має ширину = висоту 48 , встановіть layer.cornerRadius = 24:

введіть тут опис зображення

Однак це працює лише в тому випадку, якщо ви маєте статичний розмір представлення, (width/height is fixed)і він не показує коло в конструкторі інтерфейсів.


1

Швидкий 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        
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.