Kakao Dokunuşu: UIView'in Kenarlık Rengi ve Kalınlığı Nasıl Değiştirilir?


Yanıtlar:


596

Border özelliğini ayarlamak için görünümün katmanını kullanmanız gerekir. Örneğin:

#import <QuartzCore/QuartzCore.h>
...
view.layer.borderColor = [UIColor redColor].CGColor;
view.layer.borderWidth = 3.0f;

Bu işlevselliğe erişmek için QuartzCore.framework ile de bağlantı kurmanız gerekir.


Her taraf için farklı genişlik / renk ayarlamanın bir yolu var mı?
lluismontero

2
@lluismontero Korkarım drawRect ile özel UIView yapmak zorunda kalacaksınız: Bunun için yöntem
Vladimir

1
Bunu yaparsam ve bu görünümün üstünde, bir mod UINavigationController'ın işten çıkarılması gibi bir animasyonum varsa, çok fazla aksaklık olduğunu görüyorum, tanımlaması zor. Sınırları devre dışı bırakırsam, her şey normale döner.
Nicu Surdu

5
Sadece diğerleri için bir kafa. Xcode, UIColor'u CGColorRef olarak köprülemeyi önerir __bridge CGColorRef. Bu çalışmıyor. Cevapta [UIColor blackColor].CGColorbelirtildiği gibi olmalıdır .
GoodSp33d

6
#import <QuartzCore/QuartzCore.h>artık gerekli değil.
anlam önemlidir

43

Xcode 6 güncellemesi

Xcode'un en yeni sürümünden bu yana daha iyi bir çözüm var:

İle @IBInspectabledoğrudan 'dan Öznitelikler'i ayarlayabilirsiniz içindeAttributes Inspector .

Özel Görünümüm @IBInspectable Öznitelikleri

Bu User Defined Runtime Attributessizin için ayarlar :

resim açıklamasını buraya girin

Bunu ayarlamak için iki yaklaşım vardır:

Seçenek 1 (Storyboard'da canlı güncelleme ile)

  1. Oluşturun MyCustomView.
  2. Bu, miras alır UIView.
  3. Ayarla @IBDesignable(bu, Görünüm güncellemesini canlı yapar). *
  4. Çalışma Zamanı Niteliklerinizi (kenarlık vb.) @IBInspectable
  5. Views Sınıfınızı olarak değiştirin MyCustomView
  6. Özellikler Panelinde düzenleyin ve Öykü Panosundaki değişiklikleri görün :)

'

@IBDesignable
class MyCustomView: UIView {
    @IBInspectable var cornerRadius: CGFloat = 0 {
        didSet {
            layer.cornerRadius = cornerRadius
            layer.masksToBounds = cornerRadius > 0
        }
    }
    @IBInspectable var borderWidth: CGFloat = 0 {
        didSet {
            layer.borderWidth = borderWidth
        }
    }
    @IBInspectable var borderColor: UIColor? {
        didSet {
            layer.borderColor = borderColor?.CGColor
        }
    }
}

* @IBDesignablesadece başlangıçta ayarlandığında çalışırclass MyCustomView

Seçenek 2 (Swift 1.2'den beri çalışmıyor, yorumlara bakın)

UIView Sınıfınızı genişletin:

extension UIView {
    @IBInspectable var cornerRadius: CGFloat = 0 {
        didSet {
            layer.cornerRadius = cornerRadius
            layer.masksToBounds = cornerRadius > 0
        }
    }
    @IBInspectable var borderWidth: CGFloat = 0 {
        didSet {
            layer.borderWidth = borderWidth
        }
    }
    @IBInspectable var borderColor: UIColor? {
        didSet {
            layer.borderColor = borderColor?.CGColor
        }
    }
}

Bu şekilde, varsayılan Görünümünüzde her zaman bu ek düzenlenebilir alanlar bulunur Attributes Inspector. Diğer bir avantaj da sınıfı MycustomViewher seferinde değiştirmek zorunda kalmamanızdır. Ancak bunun bir dezavantajı, değişikliklerinizi yalnızca uygulamanızı çalıştırdığınızda görmenizdir.


1
Uzantınız bugün itibariyle Xcode'un en son sürümünde çalışmıyor.
Edgar Aroutiounian

1
@EdgarAroutiounian'ı sadece Swift 1.2'de ikinci yaklaşımın artık işe
yaramadığını söyleyeceğim

Objective-C ne olacak?
Nik Kov

Aşağıda spencery2'nin cevabına göz atın , Objective-C'de yazmak için zaman
ayırdı

bir değeri saklamamak için uzantıyı güncelleyin ve katmana doğrudan erişmek için {} set (value) kullanın ve {} kullanın, sonra çalışır.
19:18

17

İstediğiniz renge sahip kenarlık da oluşturabilirsiniz ..

view.layer.borderColor = [UIColor colorWithRed:r/255.0 green:g/255.0 blue:b/255.0 alpha:1.0].CGColor;

* r, g, b, 0 ila 255 arasındaki değerlerdir.


6
Bu fazlalaştı r, gve bmuhtemelen yüzer olmalıdır; bölenler de yüzer olmalıdır: r / 255.0.

hayır, C sözdizimi dediğiniz gibi değil. r, g ve b int olabilir, çünkü C (ve objC IS C) promosyonları int r = 128 değerini iki katına çıkarır: r / 255.0. Bu arada ikiniz var ve Clang CGFloat'a yayınlanacak.
ingconti

10

UIView uzantısında aşağıdaki @IBInspectables ekle

extension UIView {

  @IBInspectable var borderWidth: CGFloat {
    get {
      return layer.borderWidth
    }
    set(newValue) {
      layer.borderWidth = newValue
    }
  }

  @IBInspectable var borderColor: UIColor? {
    get {
      if let color = layer.borderColor {
        return UIColor(CGColor: color)
      }
      return nil
    }
    set(newValue) {
      layer.borderColor = newValue?.CGColor
    }
  }
}

Ve sonra borderColor ve borderWidth niteliklerini doğrudan Nitelik denetçisinden ayarlayabilmelisiniz. Ekteki resme bakın

Öznitelik Müfettişi


8

Vladimir'in CALayer çözümünü kullandığımda ve görünümün üstünde, kalıcı bir UINavigationController'ın işten çıkarılması gibi bir animasyonum var, performans sorunları ile ilgili birçok sorun görüyorum.

Yani, bunu başarmanın başka bir yolu, ancak aksaklıklar ve performans kaybı olmadan, özel bir UIView yapmak ve drawRectmesajı şöyle uygulamaktır :

- (void)drawRect:(CGRect)rect
{
    CGContextRef contextRef = UIGraphicsGetCurrentContext();
    CGContextSetLineWidth(contextRef, 1);
    CGContextSetRGBStrokeColor(contextRef, 255.0, 255.0, 255.0, 1.0);
    CGContextStrokeRect(contextRef, rect);    
}

@Krish Rengi bir değişkende saklarsınız ve kenarlık rengini değiştirmeniz gerektiğinde, değişken değerini değiştirir setNeedsDisplayve görünümde çağırırsınız . Bu, UIView'in yeniden çizilmesini zorlar ve dolaylı olarak yeniden arar drawRect. Test edilmedi, ...
Nicu Surdu

8
view.layer.borderWidth = 1.0
view.layer.borderColor = UIColor.lightGray.cgColor

1
İnsanların açıklama yapmadan oy kullanmasını gerçekten sevmiyorum. Kimseye yardım etmez.
David DelMonte

7

Bu kodu deneyin:

view.layer.borderColor =  [UIColor redColor].CGColor;
view.layer.borderWidth= 2.0;
[view setClipsToBounds:YES];

4

Performansa neden olduğu için drawRect'i geçersiz kılmayı önermem.

Bunun yerine, sınıfın özelliklerini aşağıdaki gibi değiştiririm (özel uiview'unuzda):

  - (id)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
      self.layer.borderWidth = 2.f;
      self.layer.borderColor = [UIColor redColor].CGColor;
    }
  return self;

Yukarıdaki yaklaşımı alırken herhangi bir aksaklık görmedim - neden initWithFrame koyarak bu durur ;-)


3

Bunu @ marczking'in cevabına ( Seçenek 1 ) yorum olarak eklemek istedim , ancak StackOverflow'daki düşük durumum bunu engelliyor.

@ Marczking'in Objective C'ye cevabını verdim. Cazibe gibi çalışıyor, teşekkürler @marczking!

UIView + Border.h:

#import <UIKit/UIKit.h>

IB_DESIGNABLE
@interface UIView (Border)

-(void)setBorderColor:(UIColor *)color;
-(void)setBorderWidth:(CGFloat)width;
-(void)setCornerRadius:(CGFloat)radius;

@end

UIView + Border.m:

#import "UIView+Border.h"

@implementation UIView (Border)
// Note: cannot use synthesize in a Category

-(void)setBorderColor:(UIColor *)color
{
    self.layer.borderColor = color.CGColor;
}

-(void)setBorderWidth:(CGFloat)width
{
    self.layer.borderWidth = width;
}

-(void)setCornerRadius:(CGFloat)radius
{
    self.layer.cornerRadius = radius;
    self.layer.masksToBounds = radius > 0;
}

@end

2

@IBInspectable, iOS 9, Swift 2.0'da benim için çalışıyor

extension UIView {

@IBInspectable var borderWidth: CGFloat {
get {
        return layer.borderWidth
    }
    set(newValue) {
        layer.borderWidth = newValue
    }
}

@IBInspectable var cornerRadius: CGFloat {
    get {
        return layer.cornerRadius
    }
    set(newValue) {
        layer.cornerRadius = newValue
    }
}

@IBInspectable var borderColor: UIColor? {
    get {
        if let color = layer.borderColor {
            return UIColor(CGColor: color)
        }
        return nil
    }
    set(newValue) {
        layer.borderColor = newValue?.CGColor
    }
}

1

Bir UIView katmanını düzenlemek istemediyseniz, görünümü her zaman başka bir görünüme gömebilirsiniz. Üst görünümün arka plan rengi kenarlık rengine ayarlanmış olacaktır. Sınırın ne kadar geniş olmasını istediğinize bağlı olarak biraz daha büyük olacaktır.

Tabii ki, bu yalnızca görünümünüz şeffaf değilse ve yalnızca tek bir kenarlık rengi istiyorsanız çalışır. OP sınırın kendisinde görünmesini istedi, ancak bu uygulanabilir bir alternatif olabilir.


0

Farklı kenarlara farklı kenarlık eklemek istiyorsanız, belirli bir stil ile bir alt görünüm eklemek gelmek kolay bir yoldur.


0

öğenin kenarlık rengi hızlı 4.2:

let cell = tableView.dequeueReusableCell(withIdentifier: "Cell_lastOrderId") as! Cell_lastOrder
cell.layer.borderWidth = 1
cell.layer.borderColor = UIColor.white.cgColor
cell.layer.cornerRadius = 10
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.