2011-02-17 30 views
6

在AppKit(對於Mac OS X上的Cocoa)中是否有與UIKit的[NSString sizeWithFont:constrainedToSize:]做同樣的事情的方法?UIKit在AppKit中的[NSString sizeWithFont:constrainedToSize:]

如果不是這樣,我怎麼能得到足夠的空間來呈現一個特定的字符串被限制在一個寬度/高度?

更新:下面是我使用的代碼片段,我期望會產生我之後的結果。

NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys: 
          [NSFont systemFontOfSize: [NSFont smallSystemFontSize]], NSFontAttributeName, 
          [NSParagraphStyle defaultParagraphStyle], NSParagraphStyleAttributeName, 
          nil]; 
NSSize size = NSMakeSize(200.0, MAXFLOAT); 
NSRect bounds; 

bounds = [@"This is a really really really really really really really long string that won't fit on one line" 
      boundingRectWithSize: size 
      options: NSStringDrawingUsesFontLeading 
      attributes: attributes]; 

NSLog(@"height: %02f, width: %02f", bounds.size.height, bounds.size.width); 

我期望的輸出寬度爲200,高度將是東西比一個單行的高度,但是它產生:

height: 14.000000, width: 466.619141 

謝謝!

+1

重複:http://stackoverflow.com/questions/ 2349692 /最新最等效sizewithfont法換的-MAC。有沒有人搜索這些日子? –

+3

我搜索,但令人驚訝的是,我沒有找到那一個。無論如何,sizeWithAttributes:不,afaik,支持限制寬度。 –

+4

這不是重複的,因爲這個約束元素在其他問題中缺少。 –

回答

1

編輯:你應該能夠在獅子和以後的事情做正常的方式。下面描述的問題已得到解決。


在當前的Mac OS X API中無法準確測量文本。

有幾個API承諾可以工作,但不會。這是其中之一;另一個是Core Text's function for this purpose。有些方法會返回接近但錯誤的結果;一些返回的結果似乎毫無意義。我還沒有提交任何錯誤,但是當我這樣做時,我會將雷達編號編輯到該答案中。你也應該提交一個bug,並將你的代碼包含在一個小樣本項目中。

[顯然我已經提交了核心文本:8666756.它作爲未指定的其他錯誤的副本關閉。對於可可,我申請9022238約戴夫建議的方法,並且將文件中的兩個錯誤NSLayoutManager明天。]

This is the closest solution I've found.

+0

您的鏈接已損壞。 – livingtech

+0

@livingtech:我已經更新了我的答案。謝謝。 –

+0

@PeterHosey你說它適用於獅子,但它似乎並不適合我..這裏是我的問題.. http://stackoverflow.com/questions/11766189/how-do-we-measure-visible-bounds-of在可可和相關的問題是在http://stackoverflow.com/questions/11877791/what-does-the-nsstringdrawingusesdevicemetrics-flag-mean-and-how-do-we-use-it/ – trss

-4

如果您搜索NSString的文檔,您會發現「NSString Application Kit Additions Reference」,它與UIKit相似。

-[NSString sizeWithAttributes:] 

是您正在查找的方法。

+1

是否有和屬性告訴sizeWithAttributes:約束其寬度/高度? –

1

如果要將字符串限制爲特定大小,請使用-[NSString boundingRectWithSize:options:attributes:]。返回的NSRect.size是您要查找的尺寸。

+0

我已經添加了一些我期望在問題中可以使用的代碼,但它顯然沒有。你會介意指引我朝着正確的方向嗎?謝謝! –

+0

同意...這絕對不似乎工作,不知道爲什麼。 – livingtech

+0

正如Aki幫助提到的那樣,您需要爲多行計算指定'NSStringDrawingUsesLineFragmentOrigin'選項。 – livingtech

6

較新NSExtendedStringDrawing類API(與NSStringDrawingOptions參數的方法)在單線模式的行爲。如果要以多行模式測量/渲染,則需要指定NSStringDrawingUsesLineFragmentOrigin。

+3

是!這個無害的評論是「boundingRectWithSize:options:attributes:'神奇地爲我工作! 'NSStringDrawingUsesLineFragmentOrigin'是重要的選項。 – livingtech

13

試試這個:

bounds = [value boundingRectWithSize:size options:NSLineBreakByWordWrapping | NSStringDrawingUsesLineFragmentOrigin attributes:attributes]; 
+5

爲什麼這不是公認的答案? –

+0

'NSLineBreakByWordWrapping'不是'NSStringDrawingOptions'選項。它被定義爲0,所以它沒有效果。 – titaniumdecoy

+0

@titaniumdecoy 0並不意味着沒有影響,它表示默認。 – coneybeare

1

這裏是你如何能做到這一點使用boundingRectWithSize一個更完整的例子。

// get the text field 
NSTextField* field = (NSTextField*)view; 

// create the new font for the text field 
NSFont* newFont = [NSFont fontWithName:@"Trebuchet MS" size:11.0]; 

// set the font on the text field 
[field setFont:newFont]; 

// calculate the size the textfield needs to be in order to display the text properly 
NSString* text  = field.stringValue; 
NSInteger maxWidth = field.frame.size.width; 
NSInteger maxHeight = 20000; 
CGSize constraint = CGSizeMake(maxWidth, maxHeight); 
NSDictionary* attrs = [NSDictionary dictionaryWithObjectsAndKeys:NSFontAttributeName,newFont, nil]; 
NSRect newBounds = [text boundingRectWithSize:constraint 
             options:NSLineBreakByWordWrapping | NSStringDrawingUsesLineFragmentOrigin 
             attributes:attrs]; 

// set the size of the text field to the calculated size 
field.frame = NSMakeRect(field.frame.origin.x, field.frame.origin.y, field.frame.size.width, newBounds.size.height); 

當然,對於更多的信息,看看蘋果的文檔: