İOS 7'de sizeWithFont:
artık kullanımdan kaldırıldı. Şimdi UIFont nesnesini değiştirme yöntemine sizeWithAttributes:
nasıl geçiririm ?
İOS 7'de sizeWithFont:
artık kullanımdan kaldırıldı. Şimdi UIFont nesnesini değiştirme yöntemine sizeWithAttributes:
nasıl geçiririm ?
Yanıtlar:
Kullan sizeWithAttributes:
artık sürer yerine NSDictionary
. Anahtarla UITextAttributeFont
ve yazı tipi nesnenizle çifti iletin :
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));
boundingRectWithSize:options:attributes:context:
yerine CGSizeMake(250.0f, CGFLOAT_MAX)
çoğu durumda geçersiniz .
Bu NSString+UIKit
işlev ( sizewithFont:...
, vb.) Bir dizi UIStringDrawing
iş parçacığı güvenli olmayan kütüphane dayanıyordu çünkü işlevi kullanımdan kaldırıldığını düşünüyorum . Bunları ana iş parçacığında (diğer UIKit
işlevler gibi ) çalıştırmaya çalıştıysanız , öngörülemeyen davranışlar elde edersiniz. Özellikle, işlevi aynı anda birden çok iş parçacığında çalıştırdıysanız, muhtemelen uygulamanızı kilitler. Bu yüzden iOS 6'da bir boundingRectWithSize:...
yöntem sundular NSAttributedString
. Bu NSStringDrawing
kütüphanelerin üzerine inşa edilmiş ve iş parçacığı güvenlidir.
Yeni NSString
boundingRectWithSize:...
işleve bakarsanız, a ile aynı şekilde bir nitelik dizisi ister NSAttributeString
. Tahmin etmek zorunda kalsaydım, NSString
iOS 7'deki bu yeni işlev yalnızca NSAttributeString
iOS 6'daki işlev için bir sarıcıdır .
Bu notta, yalnızca iOS 6 ve iOS 7'yi destekliyorsanız, kesinlikle tüm NSString
sizeWithFont:...
cihazınızı NSAttributeString
boundingRectWithSize
. Tuhaf bir çok iş parçacıklı köşe kasanız varsa, baş ağrısından tasarruf edersiniz! İşte nasıl dönüştürdüm NSString
sizeWithFont:constrainedToSize:
:
Eskiden ne olurdu:
NSString *text = ...;
CGFloat width = ...;
UIFont *font = ...;
CGSize size = [text sizeWithFont:font
constrainedToSize:(CGSize){width, CGFLOAT_MAX}];
Şununla değiştirilebilir:
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;
Lütfen belgelere dikkat edin:
İOS 7 ve sonraki sürümlerde, bu yöntem kesirli boyutları döndürür (döndürülen öğenin boyut bileşeninde
CGRect
); görünümlere döndürülen bir boyutu kullanmak için, tavan işlevini kullanarak değerini en yakın daha yüksek tamsayıya yükseltmeniz gerekir.
Bu yüzden görünümleri boyutlandırmak için kullanılacak hesaplanan yüksekliği veya genişliği çıkarmak için şunu kullanırdım:
CGFloat height = ceilf(size.height);
CGFloat width = ceilf(size.width);
sizeWithFont
Apple Developer sitesinde görebileceğiniz gibi kullanımdan kaldırıldı, bu yüzden kullanmamız gerekiyor 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]}];
}
[NSObject respondsToSelector:]
burada olduğu gibi yöntemi kullanmak daha iyidir : stackoverflow.com/a/3863039/1226304
Bu sorunu çözmek için bir kategori oluşturdum, işte burada:
#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]);
}
Yalnızca değiştirmek / bulmak zorunda Bu şekilde sizeWithFont:
olan sizeWithMyFont:
ve sen iyi gitmek.
İOS7'de tablo görünümü için doğru yüksekliği döndürmek için mantığa ihtiyacım vardı: heightForRowAtIndexPath yöntemi, ancak boyut genişliğinden bağımsız olarak sizeWithAttributes her zaman aynı yüksekliği döndürür, çünkü sabit genişlikli bir tablo hücresine yerleştirileceğini bilmez . Bunun benim için harika olduğunu gördüm ve tablo hücresinin genişliğini dikkate alarak doğru yüksekliği hesaplıyor! Bu, Bay T'nin yukarıdaki cevabına dayanmaktadır.
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
Dinamik yükseklik kullanan çok satırlı etiketler, boyutu uygun şekilde ayarlamak için ek bilgi gerektirebilir. UFont ve NSParagraphStyle ile sizeWithAttributes öğesini hem yazı tipini hem de satır sonu modunu belirtmek için kullanabilirsiniz.
Paragraf Stili'ni tanımlar ve aşağıdaki gibi bir NSDictionary kullanırsınız:
// 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];
Yüksekliği arıyorsanız CGSize 'adjustSize' veya CGRect'i rect.size.height özelliği olarak kullanabilirsiniz.
NSParagraphStyle hakkında daha fazla bilgi için: https://developer.apple.com/library/mac/documentation/cocoa/reference/applicationkit/classes/NSParagraphStyle_Class/Reference/Reference.html
// 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));
UILabel örneği alan bir işlev oluşturun. ve CGSize değerini döndürür
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;
tableView.estimatedRowHeight = 68.0 tableView.rowHeight = UITableViewAutomaticDimension
Alternatif çözüm
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];
}
@Bitsand üzerine inşa etmek, bu NSString + Extras kategorime yeni eklediğim yeni bir yöntem:
- (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;
}
Sadece ortaya çıkan çerçevenin boyutunu kullanıyorum.
Yine de kullanabilirsiniz sizeWithFont
. ancak, iOS> = 7.0'da dize önde gelen ve sondaki boşluklar veya bitiş çizgileri içeriyorsa çökmeye neden olur \n
.
Metni kullanmadan önce kırpma
label.text = [label.text stringByTrimmingCharactersInSet:
[NSCharacterSet whitespaceAndNewlineCharacterSet]];
Bu sizeWithAttributes
ve için de geçerli olabilir [label sizeToFit]
.
ayrıca, nsstringdrawingtextstorage message sent to deallocated instance
iOS 7.0 cihazınızda her zaman bununla ilgilenir.
Otomatik boyutları (Swift) daha iyi kullanın:
tableView.estimatedRowHeight = 68.0
tableView.rowHeight = UITableViewAutomaticDimension
Not: 1. UITableViewCell prototipi düzgün bir şekilde tasarlanmalıdır (örneğin UILabel.numberOfLines = 0 vb. Ayarlamayı unutmayın) 2. HeightForRowAtIndexPath yöntemini kaldırın
VİDEO: https://youtu.be/Sz3XfCsSb6k
Xamarin'de kabul edilen cevap şu olacaktır (sizeWithAttributes ve UITextAttributeFont kullanın):
UIStringAttributes attributes = new UIStringAttributes
{
Font = UIFont.SystemFontOfSize(17)
};
var size = text.GetSizeUsingAttributes(attributes);
@Ayush cevabı olarak:
sizeWithFont
Apple Developer sitesinde görebileceğiniz gibi kullanımdan kaldırıldı, bu yüzden kullanmamız gerekiyorsizeWithAttributes
.
Eh, 2019+ içinde muhtemelen kullandığınız varsayarak Swift ve String
yerine Objective-c ve NSString
burada boyutunu almak do doğru yoldur, String
önceden tanımlanmış yazı ile:
let stringSize = NSString(string: label.text!).size(withAttributes: [.font : UIFont(name: "OpenSans-Regular", size: 15)!])
- (CGSize) sizeWithMyFont:(UIFont *)fontToUse
{
if ([self respondsToSelector:@selector(sizeWithAttributes:)])
{
NSDictionary* attribs = @{NSFontAttributeName:fontToUse};
return ([self sizeWithAttributes:attribs]);
}
return ([self sizeWithFont:fontToUse]);
}
İşte herhangi birinin ihtiyacı varsa monotok eşdeğeri:
/// <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;
}
Bu şekilde kullanılabilir:
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);
}
CGSize maximumLabelSize = CGSizeMake(label.frame.size.width, FLT_MAX);
CGSize expectedLabelSize = [label sizeThatFits:maximumLabelSize];
float heightUse = expectedLabelSize.height;
Bu sözdizimini deneyin:
NSAttributedString *attributedText =
[[NSAttributedString alloc] initWithString:text
attributes:@{NSFontAttributeName: font}];
Bunlardan hiçbiri benim için ios 7'de işe yaramadı. Bu benim özel hücre sınıfına koymak ve benim heightForCellAtIndexPath yönteminde yöntemi çağırır.
Uygulama mağazasında bir uygulamayı görüntülerken hücrem açıklama hücresine benziyor.
Film şeridinde ilk olarak, etiketinizi 'attributedText' olarak ayarlayın, satır sayısını 0 olarak ayarlayın (etiketi otomatik olarak yeniden boyutlandıracaktır (yalnızca ios 6+)) ve kelime kaydırmaya ayarlayın.
Sonra özel Hücre Sınıfımdaki hücrenin içeriğinin tüm yüksekliklerini topladım. Benim durumumda üstte her zaman "Açıklama" (_descriptionHeadingLabel), gerçek açıklama (_descriptionLabel) hücrenin üst kısmından başlık (_descriptionHeadingLabelTopConstraint) içeren bir boyutta değişken olan daha küçük bir etiket yazan bir Etiket var . Ben de biraz alttan biraz boşluk ekledim (altyazı tipi hücrede yaklaşık aynı miktarda elma yer.)
- (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;
}
Ve Tablo Görünümü temsilcimde:
- (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;
}
İf ifadesini biraz 'daha akıllı' olacak şekilde değiştirebilir ve hücre tanımlayıcısını bir tür veri kaynağından alabilirsiniz. Benim durumumda, hücreler belirli bir sırada sabit miktarda olacağından sabit kodlanacak.
boundingRectWithSize
ios 9.2'de mevcut problemler, ios <9.2'den farklı sonuçlardır. Bunu yapmanın en iyi yolunu buldunuz veya biliyorsunuz.
NSString
veUILabel
(vaka değil her zaman çoğu zaman) vb çoğaltılamaz kodunu / önlemek için, ayrıca yerini alabilir[UIFont systemFontOfSize:17.0f]
ilelabel.font
- it birden çok kez yazarak size karşı var olan verilere başvurulması veya yerinden sabitlerini başvurarak kod bakım yardımcı olur yer, vb