tutorial objective-c deprecated ios7

objective-c - tutorial - j2objc download



Reemplazo para sizeWithFont en desuso: en iOS 7? (19)

Aquí está el equivalente monotouch si alguien lo necesita:

/// <summary> /// Measures the height of the string for the given width. /// </summary> /// <param name="text">The text.</param> /// <param name="font">The font.</param> /// <param name="width">The width.</param> /// <param name="padding">The padding.</param> /// <returns></returns> public static float MeasureStringHeightForWidth(this string text, UIFont font, float width, float padding = 20) { NSAttributedString attributedString = new NSAttributedString(text, new UIStringAttributes() { Font = font }); RectangleF rect = attributedString.GetBoundingRect(new SizeF(width, float.MaxValue), NSStringDrawingOptions.UsesLineFragmentOrigin, null); return rect.Height + padding; }

que se puede utilizar de esta manera:

public override float GetHeightForRow(UITableView tableView, NSIndexPath indexPath) { //Elements is a string array return Elements[indexPath.Row].MeasureStringHeightForWidth(UIFont.SystemFontOfSize(UIFont.LabelFontSize), tableView.Frame.Size.Width - 15 - 30 - 15); }

En iOS 7, sizeWithFont: ahora está en desuso. ¿Cómo paso ahora el objeto UIFont al método de reemplazo sizeWithAttributes: :?


Como puede ver sizeWithFont en el sitio de desarrolladores de Apple, está en desuso, por lo que necesitamos usar sizeWithAttributes .

#define SYSTEM_VERSION_LESS_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending) NSString *text = @"Hello iOS 7.0"; if (SYSTEM_VERSION_LESS_THAN(@"7.0")) { // code here for iOS 5.0,6.0 and so on CGSize fontSize = [text sizeWithFont:[UIFont fontWithName:@"Helvetica" size:12]]; } else { // code here for iOS 7.0 CGSize fontSize = [text sizeWithAttributes: @{NSFontAttributeName: [UIFont fontWithName:@"Helvetica" size:12]}]; }


Creé una categoría para manejar este problema, aquí está:

#import "NSString+StringSizeWithFont.h" @implementation NSString (StringSizeWithFont) - (CGSize) sizeWithMyFont:(UIFont *)fontToUse { if ([self respondsToSelector:@selector(sizeWithAttributes:)]) { NSDictionary* attribs = @{NSFontAttributeName:fontToUse}; return ([self sizeWithAttributes:attribs]); } return ([self sizeWithFont:fontToUse]); }

De esta manera, solo tienes que buscar / reemplazar sizeWithFont: with sizeWithMyFont: y listo.


Crea una función que tome una instancia de UILabel. y devuelve CGSize

CGSize constraint = CGSizeMake(label.frame.size.width , 2000.0); // Adjust according to requirement CGSize size; if([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0){ NSRange range = NSMakeRange(0, [label.attributedText length]); NSDictionary *attributes = [label.attributedText attributesAtIndex:0 effectiveRange:&range]; CGSize boundingBox = [label.text boundingRectWithSize:constraint options: NSStringDrawingUsesLineFragmentOrigin attributes:attributes context:nil].size; size = CGSizeMake(ceil(boundingBox.width), ceil(boundingBox.height)); } else{ size = [label.text sizeWithFont:label.font constrainedToSize:constraint lineBreakMode:label.lineBreakMode]; } return size;


Creo que la función estaba en desuso porque esa serie de funciones NSString+UIKit ( sizewithFont:... , etc) estaban basadas en la biblioteca UIStringDrawing , que no era segura para subprocesos. Si intentaste ejecutarlos no en el hilo principal (como cualquier otra funcionalidad de UIKit ), obtendrás comportamientos impredecibles. En particular, si ejecutó la función en varios subprocesos simultáneamente, probablemente bloqueará su aplicación. Es por eso que en iOS 6, introdujeron el método boundingRectWithSize:... para NSAttributedString . Esto se creó sobre las bibliotecas NSStringDrawing y es seguro para subprocesos.

Si observa la nueva NSString boundingRectWithSize:... NSString , solicita una matriz de atributos de la misma manera que una NSAttributeString . Si tuviera que adivinar, esta nueva función NSString en iOS 7 es simplemente una envoltura para la función NSAttributeString de iOS 6.

En esa nota, si solo fuera compatible con iOS 6 y iOS 7, definitivamente cambiaría todo su NSString sizeWithFont:... a NSAttributeString boundingRectWithSize . ¡Te ahorrará muchos dolores de cabeza si tienes un extraño estuche de esquina con subprocesos múltiples! Aquí es cómo convertí NSString sizeWithFont:constrainedToSize: ::

Lo que solía ser:

NSString *text = ...; CGFloat width = ...; UIFont *font = ...; CGSize size = [text sizeWithFont:font constrainedToSize:(CGSize){width, CGFLOAT_MAX}];

Puede ser reemplazado por:

NSString *text = ...; CGFloat width = ...; UIFont *font = ...; NSAttributedString *attributedText = [[NSAttributedString alloc] initWithString:text attributes:@{NSFontAttributeName: font}]; CGRect rect = [attributedText boundingRectWithSize:(CGSize){width, CGFLOAT_MAX} options:NSStringDrawingUsesLineFragmentOrigin context:nil]; CGSize size = rect.size;

Por favor, tenga en cuenta la documentación menciona:

En iOS 7 y versiones posteriores, este método devuelve tamaños fraccionarios (en el componente de tamaño del CGRect devuelto); para usar un tamaño devuelto a las vistas de tamaño, debe usar aumentar su valor al número entero más cercano utilizando la función ceil.

Por lo tanto, para extraer la altura o el ancho calculados que se usarán para dimensionar las vistas, usaría:

CGFloat height = ceilf(size.height); CGFloat width = ceilf(size.width);


En iOS7 necesitaba la lógica para devolver la altura correcta para el método tableview: heightForRowAtIndexPath, pero sizeWithAttributes siempre devuelve la misma altura independientemente de la longitud de la cadena porque no sabe que se va a colocar en una celda de tabla de ancho fijo . Encontré que esto funciona muy bien para mí y calcula la altura correcta teniendo en cuenta el ancho de la celda de la tabla. Esto se basa en la respuesta del Sr. T anterior.

NSString *text = @"The text that I want to wrap in a table cell." CGFloat width = tableView.frame.size.width - 15 - 30 - 15; //tableView width - left border width - accessory indicator - right border width UIFont *font = [UIFont systemFontOfSize:17]; NSAttributedString *attributedText = [[NSAttributedString alloc] initWithString:text attributes:@{NSFontAttributeName: font}]; CGRect rect = [attributedText boundingRectWithSize:(CGSize){width, CGFLOAT_MAX} options:NSStringDrawingUsesLineFragmentOrigin context:nil]; CGSize size = rect.size; size.height = ceilf(size.height); size.width = ceilf(size.width); return size.height + 15; //Add a little more padding for big thumbs and the detailText label


Las etiquetas de varias líneas que usan altura dinámica pueden requerir información adicional para establecer el tamaño correctamente. Puede usar sizeWithAttributes con UIFont y NSParagraphStyle para especificar la fuente y el modo de salto de línea.

Definiría el estilo de párrafo y usaría un NSDictionary como este:

// set paragraph style NSMutableParagraphStyle *style = [[NSParagraphStyle defaultParagraphStyle] mutableCopy]; [style setLineBreakMode:NSLineBreakByWordWrapping]; // make dictionary of attributes with paragraph style NSDictionary *sizeAttributes = @{NSFontAttributeName:myLabel.font, NSParagraphStyleAttributeName: style}; // get the CGSize CGSize adjustedSize = CGSizeMake(label.frame.size.width, CGFLOAT_MAX); // alternatively you can also get a CGRect to determine height CGRect rect = [myLabel.text boundingRectWithSize:adjustedSize options:NSStringDrawingUsesLineFragmentOrigin attributes:sizeAttributes context:nil];

Puede usar la propiedad CGSize ''selectedSize'' o CGRect como rect.size.height si está buscando la altura.

Más información sobre NSParagraphStyle aquí: https://developer.apple.com/library/mac/documentation/cocoa/reference/applicationkit/classes/NSParagraphStyle_Class/Reference/Reference.html


Mejor uso de las dimensiones automáticas (Swift):

tableView.estimatedRowHeight = 68.0 tableView.rowHeight = UITableViewAutomaticDimension

NB: 1. El prototipo UITableViewCell debe estar correctamente diseñado (para la instancia, no se olvide de configurar el método UILabel.numberOfLines = 0, etc.) 2. Elimine el método HeightForRowAtIndexPath

VIDEO: https://youtu.be/Sz3XfCsSb6k


Nada de esto me funcionó en iOS 7. Esto es lo que terminé haciendo. Pongo esto en mi clase de celda personalizada y llamo al método en mi método heightForCellAtIndexPath.

Mi celda se ve similar a la celda de descripción cuando veo una aplicación en la tienda de aplicaciones.

Primero en el guión gráfico, configure su etiqueta como ''TextText'', establezca el número de líneas en 0 (que cambiará el tamaño de la etiqueta automáticamente (solo en ios 6+)) y la ajustará a ajuste de palabras.

Luego simplemente agrego todas las alturas del contenido de la celda en mi Clase de celda personalizada. En mi caso, tengo una etiqueta en la parte superior que siempre dice "Descripción" (_descriptionHeadingLabel), una etiqueta más pequeña que tiene un tamaño variable que contiene la descripción real (_descriptionLabel) una restricción desde la parte superior de la celda hasta el encabezado (_descriptionHeadingLabelTopConstraint) . También agregué 3 para espaciar un poco la parte inferior (aproximadamente la misma cantidad de lugares de Apple en la celda de tipo de subtítulo).

- (CGFloat)calculateHeight { CGFloat width = _descriptionLabel.frame.size.width; NSAttributedString *attributedText = _descriptionLabel.attributedText; CGRect rect = [attributedText boundingRectWithSize:(CGSize){width, CGFLOAT_MAX} options: NSStringDrawingUsesLineFragmentOrigin context:nil]; return rect.size.height + _descriptionHeadingLabel.frame.size.height + _descriptionHeadingLabelTopConstraint.constant + 3; }

Y en mi delegado de Table View:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath; { if (indexPath.row == 0) { UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"descriptionCell"]; DescriptionCell *descriptionCell = (DescriptionCell *)cell; NSString *text = [_event objectForKey:@"description"]; descriptionCell.descriptionLabel.text = text; return [descriptionCell calculateHeight]; } return 44.0f; }

Puede cambiar la instrucción if para que sea un poco ''más inteligente'' y obtener el identificador de celda de algún tipo de fuente de datos. En mi caso, las celdas serán codificadas de manera rígida ya que habrá una cantidad fija de ellas en un orden específico.


Prueba esta sintaxis:

NSAttributedString *attributedText = [[NSAttributedString alloc] initWithString:text attributes:@{NSFontAttributeName: font}];


Sobre la base de @bitsand, este es un nuevo método que acabo de agregar a mi categoría NSString + Extras:

- (CGRect) boundingRectWithFont:(UIFont *) font constrainedToSize:(CGSize) constraintSize lineBreakMode:(NSLineBreakMode) lineBreakMode; { // set paragraph style NSMutableParagraphStyle *style = [[NSParagraphStyle defaultParagraphStyle] mutableCopy]; [style setLineBreakMode:lineBreakMode]; // make dictionary of attributes with paragraph style NSDictionary *sizeAttributes = @{NSFontAttributeName:font, NSParagraphStyleAttributeName: style}; CGRect frame = [self boundingRectWithSize:constraintSize options:NSStringDrawingUsesLineFragmentOrigin attributes:sizeAttributes context:nil]; /* // OLD CGSize stringSize = [self sizeWithFont:font constrainedToSize:constraintSize lineBreakMode:lineBreakMode]; // OLD */ return frame; }

Solo uso el tamaño del marco resultante.


Solución alternativa

CGSize expectedLabelSize; if ([subTitle respondsToSelector:@selector(sizeWithAttributes:)]) { expectedLabelSize = [subTitle sizeWithAttributes:@{NSFontAttributeName:subTitleLabel.font}]; }else{ expectedLabelSize = [subTitle sizeWithFont:subTitleLabel.font constrainedToSize:subTitleLabel.frame.size lineBreakMode:NSLineBreakByWordWrapping]; }


Todavía puedes usar sizeWithFont . pero, en el método iOS> = 7.0, se produce un fallo si la cadena contiene espacios iniciales y finales o líneas finales /n .

Recortar texto antes de usarlo

label.text = [label.text stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]];

Eso también puede aplicarse a sizeWithAttributes y [label sizeToFit] .

también, siempre que tenga nsstringdrawingtextstorage message sent to deallocated instance en un dispositivo iOS 7.0, se trata de esto.


Use sizeWithAttributes: lugar, que ahora toma un NSDictionary . Pase el par con la clave UITextAttributeFont y su objeto de fuente como este:

CGSize size = [string sizeWithAttributes: @{NSFontAttributeName: [UIFont systemFontOfSize:17.0f]}]; // Values are fractional -- you should take the ceilf to get equivalent values CGSize adjustedSize = CGSizeMake(ceilf(size.width), ceilf(size.height));


La respuesta aceptada en Xamarin sería (use sizeWithAttributes y UITextAttributeFont):

UIStringAttributes attributes = new UIStringAttributes { Font = UIFont.SystemFontOfSize(17) }; var size = text.GetSizeUsingAttributes(attributes);


- (CGSize) sizeWithMyFont:(UIFont *)fontToUse { if ([self respondsToSelector:@selector(sizeWithAttributes:)]) { NSDictionary* attribs = @{NSFontAttributeName:fontToUse}; return ([self sizeWithAttributes:attribs]); } return ([self sizeWithFont:fontToUse]); }


// max size constraint CGSize maximumLabelSize = CGSizeMake(184, FLT_MAX) // font UIFont *font = [UIFont fontWithName:TRADE_GOTHIC_REGULAR size:20.0f]; // set paragraph style NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init]; paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping; // dictionary of attributes NSDictionary *attributes = @{NSFontAttributeName:font, NSParagraphStyleAttributeName: paragraphStyle.copy}; CGRect textRect = [string boundingRectWithSize: maximumLabelSize options:NSStringDrawingUsesLineFragmentOrigin attributes:attributes context:nil]; CGSize expectedLabelSize = CGSizeMake(ceil(textRect.size.width), ceil(textRect.size.height));


CGSize maximumLabelSize = CGSizeMake(label.frame.size.width, FLT_MAX); CGSize expectedLabelSize = [label sizeThatFits:maximumLabelSize]; float heightUse = expectedLabelSize.height;


boundingRectWithSize:options:attributes:context: