J'ai créé un document de la vue qui affiche le numéro de page dans le coin. Le numéro de page est un uilabel avec un fond semi-transparent de couleur, et a un rayon d'angle (à l'aide de l' cornerRadius
de la propriété de l' view
s' layer
). Je l'ai placé au-dessus d'un UIScrollView
. Cependant, ce qui rend le défilement saccadé. Si je supprime l' cornerRadius
, la performance est bonne. Est-ce que je peux faire à ce sujet? Quelle serait une meilleure solution? Il semble avoir été atteint dans l' UIWebView
sans les problèmes de performance.
Réponses
Trop de publicités?Pour les étiquettes, ou de points de vue avec des coins arrondis et ou les couleurs de fond et les ombres sur le défilement des vues de la solution est assez simple:
Le plus gros problème est de la masksToBounds option de calque. Il semble que cette taxe performances de manière significative, cependant l'étiquette semble avoir besoin de cette SUR pour masquer la couleur d'arrière-plan à coins arrondis. Afin de contourner ce problème, vous devez définir les étiquettes de la couche de couleur d'arrière-plan au lieu et éteindre masksToBounds.
Le deuxième problème est que le comportement par défaut est le rafraîchissement de l'affichage chaque fois que possible, ce qui est totalement inutile de l'électricité statique ou lent, modifier des éléments sur le défilement des vues. Ici, nous avons simplement mis de couche.shouldRasterize = OUI. Ceci permettra à l'autorité de certification pour "cache" un pixellisé version de la vue pour l'élaboration rapide lors du défilement (sans doute avec l'accélération matérielle).
Vous devez vous assurer que votre couche a un canal alpha sinon pixellisation affectera le dessin des angles arrondis. Je n'ai jamais eu un problème comme je l'ai jeu alpha pour mes couleurs d'arrière-plan, mais vous pouvez avoir besoin de vérifier dans votre situation.
Voici un exemple de UILabel mis en place pour travailler en douceur sur un scollview:
UILabel *lbl = [[UILabel alloc] initWithFrame:CGRectMake(4, 4, 40.0, 24.0)];
lbl.font = [UIFont fontWithName:@"Helvetica" size:14.0];
lbl.textAlignment = UITextAlignmentRight;
lbl.text = @"Hello World";
// Must set the label background to clear so the layer background shows
lbl.backgroundColor = [UIColor clearColor];
// Set UILabel.layer.backgroundColor not UILabel.backgroundColor otherwise the background is not masked to the rounded border.
lbl.layer.backgroundColor = [UIColor colorWithRed:1 green:0 blue:0 alpha:0.5].CGColor;
lbl.layer.cornerRadius = 8;
lbl.layer.borderColor = [UIColor blackColor].CGColor;
lbl.layer.borderWidth = 1;
// Huge change in performance by explicitly setting the below (even though default is supposedly NO)
lbl.layer.masksToBounds = NO;
// Performance improvement here depends on the size of your view
lbl.layer.shouldRasterize = YES;
// self here is the child view in the scroll view
[self addSubview:lbl];
[lbl release];
Je peux remplir l'iPad 1 à l'écran avec une vue comme ça, et encore de défilement en douceur :)
Je suis tombé sur celui-ci aussi. cornerRadius (pour UIButton et UIImageView) était en train de tuer les performances de mon application. Je n’ai trouvé aucune solution efficace pour arrondir UIButton avec une image d’arrière-plan; il a donc fallu écrire mon propre morceau de code - une première méthode. Second ajoute un coin arrondi et une bordure à UIImageView. Je pense que ce code parle pour lui-même.
+(void)setBackgroundImage:(UIImage*)image forButton:(UIButton*)button withCornerRadius:(float)cornerRadius borderColor:(CGColorRef)borderColor andBorderWith:(float)borderWidth
{
UIImageView *tempImageView = [[UIImageView alloc] initWithFrame:button.frame];
UIGraphicsBeginImageContextWithOptions(tempImageView.bounds.size, NO, 1.0);
[[UIBezierPath bezierPathWithRoundedRect:tempImageView.bounds
cornerRadius:cornerRadius] addClip];
[image drawInRect:tempImageView.bounds];
tempImageView.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[button setBackgroundImage:tempImageView.image forState:UIControlStateNormal];
button.layer.shouldRasterize = YES;
button.layer.borderColor = borderColor;
button.layer.borderWidth = borderWidth;
button.layer.cornerRadius = cornerRadius;
}
+(void)makeRoundedCornersForImageView:(UIImageView*)imgV withCornerRadius:(float)cornerRadius borderColor:(CGColorRef)borderColor andBorderWith:(float)borderWidth
{
UIImageView *tempImageView = [[UIImageView alloc] initWithFrame:imgV.frame];
UIGraphicsBeginImageContextWithOptions(tempImageView.bounds.size, NO, 1.0);
[[UIBezierPath bezierPathWithRoundedRect:tempImageView.bounds
cornerRadius:cornerRadius] addClip];
[imgV.image drawInRect:tempImageView.bounds];
tempImageView.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
imgV.image = tempImageView.image;
imgV.layer.shouldRasterize = YES;
imgV.layer.borderColor = borderColor;
imgV.layer.borderWidth = borderWidth;
imgV.layer.cornerRadius = cornerRadius;
}
Comme l'a suggéré Petert, après avoir vu les messages "liés" dans la barre latérale, j'ai décidé de créer ma propre image. J'ai sous-classé UIView et ajouté une image d'arrière-plan (pour l'arrière-plan aux bords arrondis) et une étiquette de texte standard sur init. Pour créer l'image d'arrière-plan, je crée une image extensible à l'aide des fonctions de dessin en CG.
// create background image
CGFloat radius = frame.size.height / 2;
CGFloat imgSize = (radius*2)+1; // 1 pixel for stretching
UIGraphicsBeginImageContext(CGSizeMake(imgSize, imgSize));
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetAlpha(context, 0.5f);
CGContextSetLineWidth(context, 0);
CGContextSetFillColorWithColor(context, [UIColor blackColor].CGColor);
CGFloat minx = 0;
CGFloat midx = imgSize/2;
CGFloat maxx = imgSize;
CGFloat miny = 0;
CGFloat midy = imgSize/2;
CGFloat maxy = imgSize;
CGContextMoveToPoint(context, minx, midy);
CGContextAddArcToPoint(context, minx, miny, midx, miny, radius);
CGContextAddArcToPoint(context, maxx, miny, maxx, midy, radius);
CGContextAddArcToPoint(context, maxx, maxy, midx, maxy, radius);
CGContextAddArcToPoint(context, minx, maxy, minx, midy, radius);
CGContextClosePath(context);
CGContextDrawPath(context, kCGPathFillStroke);
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImage *stretchImage = [viewImage stretchableImageWithLeftCapWidth:radius topCapHeight:radius];
UIImageView *stretch = [[UIImageView alloc] initWithImage:stretchImage];
stretch.frame = self.bounds;
stretch.autoresizingMask = (UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth);
[self addSubview:stretch];
[self sendSubviewToBack:stretch];
[stretch release];