J'utilise UIBezierPath pour que mon imageview ait des coins arrondis, mais je souhaite également ajouter une bordure à l'imageview. Gardez à l'esprit que le haut est une uiimage et le bas est une étiquette.
L'utilisation actuelle de ce code produit:
let rectShape = CAShapeLayer()
rectShape.bounds = myCell2.NewFeedImageView.frame
rectShape.position = myCell2.NewFeedImageView.center
rectShape.path = UIBezierPath(roundedRect: myCell2.NewFeedImageView.bounds,
byRoundingCorners: .TopRight | .TopLeft,
cornerRadii: CGSize(width: 25, height: 25)).CGPath
myCell2.NewFeedImageView.layer.mask = rectShape
Je veux ajouter une bordure verte à cela, mais je ne peux pas utiliser
myCell2.NewFeedImageView.layer.borderWidth = 8
myCell2.NewFeedImageView.layer.borderColor = UIColor.greenColor().CGColor
car elle coupe le coin supérieur gauche et supérieur droit de la bordure, comme illustré dans cette image:
Existe-t-il un moyen d’ajouter une bordure avec UIBezierPath avec mon code actuel?
Vous pouvez réutiliser le chemin UIBezierPath et ajouter un calque de forme à la vue. Voici un exemple à l'intérieur d'un contrôleur de vue.
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Create a view with red background for demonstration
let v = UIView(frame: CGRectMake(0, 0, 100, 100))
v.center = view.center
v.backgroundColor = UIColor.redColor()
view.addSubview(v)
// Add rounded corners
let maskLayer = CAShapeLayer()
maskLayer.frame = v.bounds
maskLayer.path = UIBezierPath(roundedRect: v.bounds, byRoundingCorners: .TopRight | .TopLeft, cornerRadii: CGSize(width: 25, height: 25)).CGPath
v.layer.mask = maskLayer
// Add border
let borderLayer = CAShapeLayer()
borderLayer.path = maskLayer.path // Reuse the Bezier path
borderLayer.fillColor = UIColor.clearColor().CGColor
borderLayer.strokeColor = UIColor.greenColor().CGColor
borderLayer.lineWidth = 5
borderLayer.frame = v.bounds
v.layer.addSublayer(borderLayer)
}
}
Le résultat final ressemble à ceci.
Notez que cela ne fonctionne comme prévu que lorsque la taille de la vue est corrigée. Lorsque la vue peut être redimensionnée, vous devez créer une classe d'affichage personnalisée et redimensionner les calques dans layoutSubviews
.
Comme je le commente ci-dessus, il est
Voici la "solution OCD", il s'agit d'un code totalement inscriptible.
Voici un exemple complet. Ce
répond correctement/explique le problème qui se pose lorsque vous faites cela, vous tracez LA DEMI-LIGNE DE LA FRONTIÈRE
est totalement utilisable en autolayout
se remanie complètement lorsque la taille de la vue change ou s'anime
est totalement IBDesignable - vous pouvez le voir en temps réel dans votre story-board
pour 2017 ...
@IBDesignable
class RoundedCornersAndTrueBorder: UIView {
@IBInspectable var cornerRadius: CGFloat = 10 {
didSet { setup() }
}
@IBInspectable var borderColor: UIColor = UIColor.black {
didSet { setup() }
}
@IBInspectable var trueBorderWidth: CGFloat = 2.0 {
didSet { setup() }
}
override func layoutSubviews() {
setup()
}
var border:CAShapeLayer? = nil
func setup() {
// make a path with round corners
let path = UIBezierPath(roundedRect: self.bounds, cornerRadius:cornerRadius)
// note that it is >exactly< the size of the whole view
// mask the whole view to that shape
// note that you will ALSO be masking the border we'll draw below
let mask = CAShapeLayer()
mask.path = path.cgPath
self.layer.mask = mask
// add another layer, which will be the border as such
if (border == nil) {
border = CAShapeLayer()
self.layer.addSublayer(border!)
}
// IN SOME APPROACHES YOU would INSET THE FRAME
// of the border-drawing layer by the width of the border
// border.frame = bounds.insetBy(dx: borderWidth, dy: borderWidth)
// so that when you draw the line, ALL of the WIDTH of the line
// DOES fall within the actual mask.
// here, we will draw the border-line LITERALLY ON THE Edge
// of the path. that means >HALF< THE LINE will be INSIDE
// the path and HALF THE LINE WILL BE OUTSIDE the path
border!.frame = bounds
let pathUsingCorrectInsetIfAny =
UIBezierPath(roundedRect: border!.bounds, cornerRadius:cornerRadius)
border!.path = pathUsingCorrectInsetIfAny.cgPath
border!.fillColor = UIColor.clear.cgColor
// the following is not what you want:
// it results in "half-missing corners"
// (note however, sometimes you do use this approach):
//border.borderColor = borderColor.cgColor
//border.borderWidth = borderWidth
// this approach will indeed be "inside" the path:
border!.strokeColor = borderColor.cgColor
border!.lineWidth = trueBorderWidth * 2.0
// HALF THE LINE will be INSIDE the path and HALF THE LINE
// WILL BE OUTSIDE the path. so MAKE IT >>TWICE AS THICK<<
// as requested by the consumer class.
}
}
Aide débutant à la question ci-dessous ...
Créez un "nouveau fichier Swift" appelé "Fattie.Swift". (Notez que cela ne change rien à votre façon de parler. Si vous en êtes au stade "je ne sais pas comment créer un nouveau fichier", recherchez des didacticiels Xcode de base.
Mettez tout le code ci-dessus dedans
Vous venez d'ajouter une classe "RoundedCornersAndTrueBorder" à votre projet.
Sur votre story board. Ajoutez un UIView ordinaire à votre scène. Faites-en réellement n'importe quelle taille/forme que vous préférez.
Dans l'inspecteur identity (recherchez un didacticiel de base si vous ne savez pas ce que c'est, c'est simple), changez simplement le cours en "RoundedCornersAndTrueBorder". (Une fois que vous aurez commencé à taper "Roun ...", il devinera de quelle classe vous parlez.
Vous avez terminé, lancez le projet.
Notez que vous devez bien sûr ajouter des contraintes complètes à UIView, comme pour tout ce que vous faites dans Xcode. Prendre plaisir!
Il est sûr! Chaque vue a une propriété layer
(que vous connaissez en donnant à votre calque des angles arrondis). Les deux autres propriétés de layer
sont borderColor
et borderWidth
. En les définissant, vous pouvez ajouter une bordure à votre vue! (La bordure suivra les coins arrondis.) Assurez-vous d'utiliser UIColor.CGColor
pour borderColor
car un UIColor
ordinaire ne correspondra pas au type.