J'ai utilisé la réponse sur Comment créer un UILabel à coins arrondis sur l'iPhone? et le code de Comment une vue rectiligne arrondie avec transparence est-elle réalisée sur iPhone? pour faire ce code.
Ensuite, j'ai réalisé que j'avais répondu à la mauvaise question (j'ai donné un UILabel arrondi au lieu de UIImage), alors j'ai utilisé ce code pour le changer:
http://discussions.apple.com/thread.jspa?threadID=1683876
Créez un projet iPhone avec le modèle View. Dans le contrôleur de vue, ajoutez ceci:
- (void)viewDidLoad
{
CGRect rect = CGRectMake(10, 10, 200, 100);
MyView *myView = [[MyView alloc] initWithFrame:rect];
[self.view addSubview:myView];
[super viewDidLoad];
}
MyView
est juste une UIImageView
sous - classe:
@interface MyView : UIImageView
{
}
Je n'avais jamais utilisé de contextes graphiques auparavant, mais j'ai réussi à entraver ce code. Il manque le code pour deux des coins. Si vous lisez le code, vous pouvez voir comment j'ai implémenté cela (en supprimant certains des CGContextAddArc
appels et en supprimant certaines des valeurs de rayon dans le code. Le code pour tous les coins est là, alors utilisez-le comme point de départ et supprimez le des pièces qui créent des coins dont vous n'avez pas besoin. Notez que vous pouvez également créer des rectangles avec 2 ou 3 coins arrondis si vous le souhaitez.
Le code n'est pas parfait, mais je suis sûr que vous pouvez le ranger un peu.
static void addRoundedRectToPath(CGContextRef context, CGRect rect, float radius, int roundedCornerPosition)
{
// all corners rounded
// CGContextMoveToPoint(context, rect.origin.x, rect.origin.y + radius);
// CGContextAddLineToPoint(context, rect.origin.x, rect.origin.y + rect.size.height - radius);
// CGContextAddArc(context, rect.origin.x + radius, rect.origin.y + rect.size.height - radius,
// radius, M_PI / 4, M_PI / 2, 1);
// CGContextAddLineToPoint(context, rect.origin.x + rect.size.width - radius,
// rect.origin.y + rect.size.height);
// CGContextAddArc(context, rect.origin.x + rect.size.width - radius,
// rect.origin.y + rect.size.height - radius, radius, M_PI / 2, 0.0f, 1);
// CGContextAddLineToPoint(context, rect.origin.x + rect.size.width, rect.origin.y + radius);
// CGContextAddArc(context, rect.origin.x + rect.size.width - radius, rect.origin.y + radius,
// radius, 0.0f, -M_PI / 2, 1);
// CGContextAddLineToPoint(context, rect.origin.x + radius, rect.origin.y);
// CGContextAddArc(context, rect.origin.x + radius, rect.origin.y + radius, radius,
// -M_PI / 2, M_PI, 1);
// top left
if (roundedCornerPosition == 1) {
CGContextMoveToPoint(context, rect.origin.x, rect.origin.y + radius);
CGContextAddLineToPoint(context, rect.origin.x, rect.origin.y + rect.size.height - radius);
CGContextAddArc(context, rect.origin.x + radius, rect.origin.y + rect.size.height - radius,
radius, M_PI / 4, M_PI / 2, 1);
CGContextAddLineToPoint(context, rect.origin.x + rect.size.width,
rect.origin.y + rect.size.height);
CGContextAddLineToPoint(context, rect.origin.x + rect.size.width, rect.origin.y);
CGContextAddLineToPoint(context, rect.origin.x, rect.origin.y);
}
// bottom left
if (roundedCornerPosition == 2) {
CGContextMoveToPoint(context, rect.origin.x, rect.origin.y);
CGContextAddLineToPoint(context, rect.origin.x, rect.origin.y + rect.size.height);
CGContextAddLineToPoint(context, rect.origin.x + rect.size.width,
rect.origin.y + rect.size.height);
CGContextAddLineToPoint(context, rect.origin.x + rect.size.width, rect.origin.y);
CGContextAddLineToPoint(context, rect.origin.x + radius, rect.origin.y);
CGContextAddArc(context, rect.origin.x + radius, rect.origin.y + radius, radius,
-M_PI / 2, M_PI, 1);
}
// add the other corners here
CGContextClosePath(context);
CGContextRestoreGState(context);
}
-(UIImage *)setImage
{
UIImage *img = [UIImage imageNamed:@"my_image.png"];
int w = img.size.width;
int h = img.size.height;
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(NULL, w, h, 8, 4 * w, colorSpace, kCGImageAlphaPremultipliedFirst);
CGContextBeginPath(context);
CGRect rect = CGRectMake(0, 0, w, h);
addRoundedRectToPath(context, rect, 50, 1);
CGContextClosePath(context);
CGContextClip(context);
CGContextDrawImage(context, rect, img.CGImage);
CGImageRef imageMasked = CGBitmapContextCreateImage(context);
CGContextRelease(context);
CGColorSpaceRelease(colorSpace);
[img release];
return [UIImage imageWithCGImage:imageMasked];
}
texte alternatif http://nevan.net/skitch/skitched-20100224-092237.png
N'oubliez pas que vous aurez besoin du framework QuartzCore pour que cela fonctionne.
À partir d'iOS 3.2, vous pouvez utiliser la fonctionnalité de
UIBezierPath
s pour créer un rectangle arrondi prêt à l'emploi (où seuls les coins que vous spécifiez sont arrondis). Vous pouvez ensuite l'utiliser comme chemin d'unCAShapeLayer
, et l'utiliser comme masque pour le calque de votre vue:Et c'est tout - pas de problème de définition manuelle des formes dans Core Graphics, pas de création d'images de masquage dans Photoshop. La couche n'a même pas besoin d'être invalidée. L'application du coin arrondi ou le passage à un nouveau coin est aussi simple que de définir un nouveau coin
UIBezierPath
et de l'utiliserCGPath
comme tracé du calque de masque. Lecorners
paramètre de labezierPathWithRoundedRect:byRoundingCorners:cornerRadii:
méthode est un masque de bits, et donc plusieurs coins peuvent être arrondis en les OR en les associant.EDIT: Ajout d'une ombre
Si vous cherchez à ajouter une ombre à cela, un peu plus de travail est nécessaire.
Parce que "
imageView.layer.mask = maskLayer
" applique un masque, une ombre n'apparaîtra généralement pas en dehors de celui-ci. L'astuce consiste à utiliser une vue transparente, puis à ajouter deux sous-couchesCALayer
au calque de la vue:shadowLayer
etroundedLayer
. Les deux doivent utiliser leUIBezierPath
. L'image est ajoutée en tant que contenu deroundedLayer
.la source
J'ai utilisé ce code à de nombreux endroits dans mon code et il fonctionne à 100% correctement. Vous pouvez changer n'importe quel corder en changeant une propriété "byRoundingCorners: UIRectCornerBottomLeft"
la source
UITableView
vues (par exemple,UITableViewCell
s ouUITableViewHeaderFooterView
s), il en résulte une mauvaise fluidité lors du défilement . Une autre approche pour cette utilisation est cette solution avec une meilleure performance (elle ajoute un cornerRadius à tous les coins). Pour `` afficher '' uniquement des coins spécifiques arrondis (comme les coins supérieurs et inférieurs droits), j'ai ajouté une sous-vue avec une valeur négative sur sonframe.origin.x
et assigné le cornerRadius à son calque. Si quelqu'un a trouvé une meilleure solution, cela m'intéresse.Dans iOS 11, nous ne pouvons désormais arrondir que certains coins
la source
Extension CALayer avec syntaxe Swift 3+
Il peut être utilisé comme:
la source
L'exemple Stuarts pour arrondir des coins spécifiques fonctionne très bien. Si vous voulez arrondir plusieurs coins comme en haut à gauche et à droite, voici comment le faire
la source
UITableView
vues (par exemple,UITableViewCell
s ouUITableViewHeaderFooterView
s), il en résulte une mauvaise fluidité lors du défilement . Une autre approche pour cette utilisation est cette solution avec une meilleure performance (elle ajoute un cornerRadius à tous les coins). Pour `` afficher '' uniquement des coins spécifiques arrondis (comme les coins supérieurs et inférieurs droits), j'ai ajouté une sous-vue avec une valeur négative sur sonframe.origin.x
et assigné le cornerRadius à son calque. Si quelqu'un a trouvé une meilleure solution, cela m'intéresse.Merci d'avoir partagé. Ici, je voudrais partager la solution sur swift 2.0 pour plus de référence sur ce problème. (pour se conformer au protocole UIRectCorner)
la source
il existe une réponse plus simple et plus rapide qui peut fonctionner en fonction de vos besoins et qui fonctionne également avec les ombres. vous pouvez définir maskToBounds sur le super-calque sur true et décaler les calques enfants de sorte que 2 de leurs coins soient en dehors des limites du super-calque, coupant ainsi efficacement les coins arrondis sur 2 côtés.
bien sûr, cela ne fonctionne que lorsque vous souhaitez avoir seulement 2 coins arrondis du même côté et que le contenu du calque est le même lorsque vous coupez quelques pixels d'un côté. fonctionne très bien pour avoir des graphiques à barres arrondis uniquement sur la face supérieure.
la source
Voir cette question connexe . Vous devez dessiner votre propre rectangle à un
CGPath
avec des coins arrondis, ajoutezCGPath
à votreCGContext
puis à couper l'aideCGContextClip
.Vous pouvez également dessiner le rect arrondi avec des valeurs alpha sur une image, puis utiliser cette image pour créer un nouveau calque que vous définissez comme
mask
propriété de votre calque ( voir la documentation d'Apple ).la source
Une demi-décennie de retard, mais je pense que la façon actuelle dont les gens font cela n'est pas correcte à 100%. Beaucoup de gens ont eu le problème que l'utilisation de la méthode UIBezierPath + CAShapeLayer interfère avec la mise en page automatique, en particulier lorsqu'elle est définie sur le Storyboard. Aucune réponse ne va plus loin, j'ai donc décidé d'ajouter la mienne.
Il existe un moyen très simple de contourner cela: Dessinez les coins arrondis dans la
drawRect(rect: CGRect)
fonction.Par exemple, si je voulais des coins arrondis supérieurs pour un UIView, je sous-classerais UIView puis utiliserais cette sous-classe le cas échéant.
C'est le meilleur moyen de surmonter le problème et ne prend pas du tout de temps pour s'y adapter.
la source
drawRect(_:)
si vous faites un dessin personnalisé dans votre vue (par exemple avec Core Graphics), sinon même une implémentation vide peut avoir un impact sur les performances. La création d'un nouveau calque de masque à chaque fois est également inutile. Tout ce que vous avez à faire est de mettre à jour lapath
propriété du calque de masque lorsque les limites de la vue changent, et l'endroit pour le faire est dans un remplacement de lalayoutSubviews()
méthode.Arrondir uniquement certains coins ne sera pas agréable avec le redimensionnement automatique ou la mise en page automatique.
Une autre option consiste donc à utiliser normal
cornerRadius
et à masquer les coins que vous ne voulez pas sous une autre vue ou en dehors de ses limites de supervision en vous assurant qu'il est configuré pour découper son contenu.la source
Pour ajouter à la réponse et à l' ajout , j'ai créé un simple, réutilisable
UIView
dans Swift. En fonction de votre cas d'utilisation, vous voudrez peut-être apporter des modifications (évitez de créer des objets sur chaque mise en page, etc.), mais je voulais que cela reste aussi simple que possible. L'extension vous permet de l'appliquer à d'autres vues (ex.UIImageView
) Plus facilement si vous n'aimez pas le sous-classement.Voici comment vous l'appliqueriez à un
UIViewController
:la source
Pour résumer la réponse de Stuart, vous pouvez avoir la méthode des coins arrondis comme suit:
Donc, pour appliquer le coin arrondi, il vous suffit de faire:
la source
Je suggère de définir le masque d'un calque. Le masque lui-même doit être un
CAShapeLayer
objet avec un chemin dédié. Vous pouvez utiliser la prochaine extension UIView (Swift 4.2):la source