Antworten:
Sie müssen die Ebene der Ansicht verwenden, um die Rahmeneigenschaft festzulegen. z.B:
#import <QuartzCore/QuartzCore.h>
...
view.layer.borderColor = [UIColor redColor].CGColor;
view.layer.borderWidth = 3.0f;
Sie müssen auch eine Verknüpfung mit QuartzCore.framework herstellen, um auf diese Funktionalität zugreifen zu können.
__bridge CGColorRef
. Das funktioniert nicht. Es muss [UIColor blackColor].CGColor
wie in der Antwort erwähnt sein.
#import <QuartzCore/QuartzCore.h>
wird nicht mehr benötigt.
Seit der neuesten Version von Xcode gibt es eine bessere Lösung dafür:
Mit @IBInspectable
Ihnen Attribute direkt aus einstellen können innerhalb der Attributes Inspector
.
Dies legt das User Defined Runtime Attributes
für Sie fest:
Es gibt zwei Ansätze, um dies einzurichten:
Option 1 (mit Live-Aktualisierung im Storyboard)
MyCustomView
.UIView
.@IBDesignable
(dadurch wird das View-Update live geschaltet). *@IBInspectable
MyCustomView
`
@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
}
}
}
* @IBDesignable
funktioniert nur, wenn zu Beginn eingestelltclass MyCustomView
Option 2 (funktioniert seit Swift 1.2 nicht mehr, siehe Kommentare)
Erweitern Sie Ihre UIView-Klasse:
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
}
}
}
Auf diese Weise enthält Ihre Standardansicht immer diese zusätzlichen bearbeitbaren Felder Attributes Inspector
. Ein weiterer Vorteil ist, dass Sie die Klasse nicht MycustomView
jedes Mal ändern müssen . Ein Nachteil dabei ist jedoch, dass Sie Ihre Änderungen nur sehen, wenn Sie Ihre App ausführen.
Sie können auch einen Rahmen mit der Farbe Ihres Wunsches erstellen.
view.layer.borderColor = [UIColor colorWithRed:r/255.0 green:g/255.0 blue:b/255.0 alpha:1.0].CGColor;
* r, g, b sind die Werte zwischen 0 und 255.
r
, g
und b
sollte wahrscheinlich Floats sein; Die Teiler sollten auch Schwimmer sein : r / 255.0
.
Fügen Sie in der UIView-Erweiterung die folgenden @IBInspectables hinzu
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
}
}
}
Anschließend sollten Sie in der Lage sein, die Attribute borderColor und borderWidth direkt im Attributinspektor festzulegen. Siehe beigefügtes Bild
Wenn ich die CALayer-Lösung von Vladimir verwende und oben in der Ansicht eine Animation wie ein modaler UINavigationController angezeigt wird, treten viele Störungen auf und es treten Probleme mit der Zeichnungsleistung auf.
Eine andere Möglichkeit, dies zu erreichen, ohne dass es zu Störungen und Leistungseinbußen kommt, besteht darin, eine benutzerdefinierte UIView zu erstellen und die drawRect
Nachricht folgendermaßen zu implementieren :
- (void)drawRect:(CGRect)rect
{
CGContextRef contextRef = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(contextRef, 1);
CGContextSetRGBStrokeColor(contextRef, 255.0, 255.0, 255.0, 1.0);
CGContextStrokeRect(contextRef, rect);
}
setNeedsDisplay
die Ansicht auf. Dadurch wird das Neuzeichnen des UIView erzwungen und implizit erneut aufgerufen drawRect
. Nicht getestet, obwohl ...
view.layer.borderWidth = 1.0
view.layer.borderColor = UIColor.lightGray.cgColor
Versuchen Sie diesen Code:
view.layer.borderColor = [UIColor redColor].CGColor;
view.layer.borderWidth= 2.0;
[view setClipsToBounds:YES];
Ich würde nicht empfehlen, drawRect zu überschreiben, da dies zu einem Leistungseinbruch führt.
Stattdessen würde ich die Eigenschaften der Klasse wie folgt ändern (in Ihrer benutzerdefinierten Ansicht):
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
self.layer.borderWidth = 2.f;
self.layer.borderColor = [UIColor redColor].CGColor;
}
return self;
Ich habe bei der obigen Vorgehensweise keine Störungen gesehen - ich bin mir nicht sicher, warum das Einfügen des initWithFrame diese stoppt ;-)
Ich wollte dies als Kommentar zu @ marczkings Antwort ( Option 1 ) hinzufügen , aber mein niedriger Status bei StackOverflow verhindert dies.
Ich habe eine Portierung von @ marczkings Antwort auf Ziel C gemacht. Funktioniert wie Charme, danke @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
@IBInspectable arbeitet für mich unter iOS 9, Swift 2.0
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
}
}
Wenn Sie die Ebene einer UIView nicht bearbeiten möchten, können Sie die Ansicht jederzeit in eine andere Ansicht einbetten. In der übergeordneten Ansicht wird die Hintergrundfarbe auf die Rahmenfarbe festgelegt. Es wäre auch etwas größer, je nachdem, wie breit der Rand sein soll.
Dies funktioniert natürlich nur, wenn Ihre Ansicht nicht transparent ist und Sie nur eine einzige Rahmenfarbe wünschen. Das OP wollte die Grenze in der Ansicht selbst, aber dies könnte eine praktikable Alternative sein.
Wenn Sie auf verschiedenen Seiten unterschiedliche Rahmen hinzufügen möchten, ist es möglicherweise einfach, eine Unteransicht mit dem spezifischen Stil hinzuzufügen.