我开始使用多行NSTextFIEld.
但是,调用[self.cell setlineBreakMode:NSlineBreakByTruncatingMIDdle];导致文本字段仅显示单个截断的行(不再有换行符).
这是Finder中的样子:
解决方法 如果你想像finder标签一样包装文本,使用两个标签对你没有任何好处,因为你需要知道第一行的最大可破坏文本量是多少.另外,如果你正在构建一些会显示很多项目的东西,那么两个标签会不必要地使GUI过载.像这样设置你的NSTextFIEld.cell:
[captionLabel.cell setlineBreakMode: NSlineBreakByCharWrapPing];
然后找到“NS(Attributed)String Geometrics”的代码(Google it,它就在那里).你必须#import“NS(Attributed)String Geometrics.h”
测量文本.它猴子补丁Nsstring和NSAttributedString
我包含以下代码来准确地包装文本的Finder在其标题中的作用.使用图标下方的一个标签,它假定像Finder一样,将有两行标题.
首先,您将在代码中调用以下代码:
Nsstring *caption = self.textinput.stringValue;CGfloat w = self.captionLabel.bounds.size.wIDth;Nsstring *wrappedCaption = [self wrappedCaptionText:self.captionLabel.Font caption:caption wIDth:w];self.captionLabel.stringValue = wrappedCaption ? [self mIDdleTruncatedCaption:wrappedCaption withFont:self.captionLabel.Font wIDth:w] : caption;
现在为主要代码:
#define SINGLE_liNE_HEIGHT 21/* This is the way finder captions work - 1) see if the string needs wrapPing at all 2) if so find the maximum amount that will fit on the first line of the caption 3) See if there is a (word)break character somewhere between the maximum that would fit on the first line and the begining of the string 4) If there is a break character (working backwards) on the first line- insert a line break then return a string so that the truncation function can trunc the second line*/-(Nsstring *) wrappedCaptionText:(NSFont*) aFont caption:(Nsstring*)caption wIDth:(CGfloat)captionWIDth{ Nsstring *wrappedCaption = nil; //get the wIDth for the text as if it was in a single line CGfloat wIDthOfText = ; //1) nothing to wrap if ( wIDthOfText <= captionWIDth ) return nil; //2) find the maximum amount that fits on the first line NSRange firstlineRange = [self getMaximumLengthOfFirstlineWithFont:aFont caption:caption wIDth:captionWIDth]; //3) find the first breakable character on the first line looking backwards NSCharacterSet *notAlphaNums = [NSCharacterSet AlphanumericCharacterSet].invertedSet; NSCharacterSet *whites = [NSCharacterSet whitespaceAndNewlineCharacterSet]; NSRange range = ; NSUInteger splitPos; if ( (range.length == 0) || (range.location < firstlineRange.length * 2 / 3) ) { // no break found or break is too (less than two thirds) far to the start of the text splitPos = firstlineRange.length; } else { splitPos = range.location+range.length; } //4) put a line break at the logical end of the first line wrappedCaption = [Nsstring stringWithFormat:@"%@\n%@",[ stringByTrimmingCharactersInSet:whites],[ stringByTrimmingCharactersInSet:whites]]; return wrappedCaption;}/* Binary search is great..but when we split the caption in half,we dont have far to go usually Depends on the average length of text you are trying to wrap filenames are not usually that long compared to the captions that hold them... */-(NSRange) getMaximumLengthOfFirstlineWithFont:(NSFont *)aFont caption:(Nsstring*)caption wIDth:(CGfloat)captionWIDth{ BOol fits = NO; Nsstring *firstline = nil; NSRange range; range.length = caption.length /2; range.location = 0; NSUInteger lastFailedLength = caption.length; NSUInteger lastSuccessLength = 0; int testCount = 0; NSUInteger initialLength = range.length; NSUInteger actualdistance = 0; while (!fits) { firstline = ; fits = [firstline wIDthForHeight:SINGLE_liNE_HEIGHT Font:aFont] < captionWIDth; testCount++; if ( !fits ) { lastFailedLength = range.length; range.length-= (lastFailedLength - lastSuccessLength) == 1? 1 : (lastFailedLength - lastSuccessLength)/2; continue; } else { if ( range.length == lastFailedLength -1 ) { actualdistance = range.length - initialLength; #ifdef DEBUG NSLog(@"# of tests:%d actualdistance:%lu iteration better? %@",testCount,(unsigned long)actualdistance,testCount > actualdistance ? @"YES" :@"NO"); #endif break; } else { lastSuccessLength = range.length; range.length += (lastFailedLength-range.length) / 2; fits = NO; continue; } } } return range;}-(Nsstring *)mIDdleTruncatedCaption:(Nsstring*)aCaption withFont:(NSFont*)aFont wIDth:(CGfloat)captionWIDth{ NSArray *components = [aCaption componentsSeparatedByString:@"\n"]; Nsstring *secondline = [components objectAtIndex:1]; Nsstring *newCaption = aCaption; CGfloat wIDthOfText = [secondline wIDthForHeight:SINGLE_liNE_HEIGHT Font:aFont]; if ( wIDthOfText > captionWIDth ) { //ignore the fact that the length might be an odd/even number "..." will always truncate at least one character int mIDdleChar = ((int)secondline.length-1) / 2; Nsstring *newSecondline = nil; Nsstring *leftSIDe = secondline; Nsstring *rightSIDe = secondline; for (int i=1; i <= mIDdleChar; i++) { leftSIDe = [secondline substringToIndex:mIDdleChar-i]; rightSIDe = [secondline substringFromIndex:mIDdleChar+i]; newSecondline = [Nsstring stringWithFormat:@"%@…%@",leftSIDe,rightSIDe]; wIDthOfText = [newSecondline wIDthForHeight:SINGLE_liNE_HEIGHT Font:aFont]; if ( wIDthOfText <= captionWIDth ) { newCaption = [Nsstring stringWithFormat:@"%@\n%@",[components objectAtIndex:0],newSecondline]; break; } } } return newCaption;}@end
干杯!
PS测试原型作品很可能有BUG …找到它们
总结以上是内存溢出为你收集整理的cocoa – 截断多行NSTextField的最后一行全部内容,希望文章能够帮你解决cocoa – 截断多行NSTextField的最后一行所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)