2013-01-20 41 views
7

Tôi đã tìm kiếm xung quanh về cách thực hiện điều này nhưng tôi không thể tìm thấy bất kỳ câu trả lời nào.
Tôi muốn biết nếu NSTextfield của tôi đã cắt ngắn văn bản (... ở cuối) mà không phải kiểm tra độ dài stringValue của nó. Tôi cần phải làm điều này để biết tôi có nên đặt chú giải công cụ trên NSTextfield (hoạt động như một nhãn đơn giản) không.
Lý do tôi không muốn kiểm tra độ dài của trường văn bản stringValue của tôi bởi vì có một số ký tự chiếm nhiều không gian hơn các trường khác, vì vậy không chính xác lắm
Cảm ơn!Làm thế nào để kiểm tra xem NSTextfield đã cắt ngắn văn bản (... ở cuối)

Trả lời

4

Đặt cược tốt nhất của bạn có thể là sử dụng số NSTextView thay vì NSTextField. Nếu bạn sử dụng số NSTextView, bạn có thể nhận số NSTextContainer của số NSTextView bằng cách sử dụng thuộc tính textContainer. Vùng chứa có thể cho bạn biết containerSize (không gian văn bản được vẽ).

NSString đối tượng phản hồi phương pháp sizeWithAttributes:. Bạn có thể sử dụng kết quả NSSize struct để lấy chiều rộng của văn bản nếu được vẽ với các thuộc tính đã cho. Xem phần "Hằng số" của số NSAttributedString Application Kit Additions Reference để tìm ra những thuộc tính nào có liên quan.

Nếu chiều rộng containerSize nhỏ hơn chiều rộng sizeWithAttributes: thì văn bản sẽ bị cắt bớt.

CHỈNH SỬA: Xin lỗi, điều này chỉ đúng với số lineFragmentPadding, nhưng mặc định lineFragmentPadding khác không. Hoặc trừ số textContainer.lineFragmentPadding từ containerSize.width hoặc sử dụng phương pháp NSTextContainersetLineFragmentPadding: để đặt thành 0.

Tôi giả sử bạn cũng có thể đưa ra một số giả định về vùng văn bản tương ứng với kích thước của NSTextField và sử dụng phương pháp sizeWithAttributes:NSString cùng với điều đó, nhưng điều đó không sạch sẽ.

CHỈNH SỬA 2: Tôi nhận thấy rằng tôi không giải quyết được sự quan tâm của OP trong việc cắt xén văn bản bằng hình elip. Mã ví dụ bên dưới sử dụng cắt ngắn trong NSTextView. Tôi cũng nghĩ rằng tôi cũng có thể ném vào một số mã mà làm cho NSTextView một chút tương tự hơn trong xuất hiện để NSTextField bằng cách đặt nó bên trong một NSBox. Thêm một kiểm tra cho kích thước để xác định nếu một tooltip sẽ được hiển thị sẽ là một bổ sung đơn giản cho các mã dưới đây bằng cách sử dụng các thông tin đã đề cập ở trên.

NSString* string = @"Hello World."; 

// get the size the text will take up using the default font 
NSSize textBounds = [string sizeWithAttributes:@{}]; 

// Create a border view that looks more or less like the border used around 
// text fields 
NSBox* borderView = [[NSBox alloc] initWithFrame:NSMakeRect(10, 10, 60, textBounds.height+4)]; 
[borderView setBoxType:NSBoxCustom]; 
[borderView setBorderType:NSBezelBorder]; 
[borderView setContentViewMargins:NSMakeSize(0, 0)]; 
[borderView setFillColor:[NSColor whiteColor]]; 

// Create the text view 
NSTextView* textView = [[NSTextView alloc] initWithFrame:NSMakeRect(0, 0, 60, textBounds.height)]; 
[textView setTextContainerInset:NSMakeSize(2, 0)]; 
[textView.textContainer setLineFragmentPadding:0]; 
[textView setEditable:YES]; 

// Set the default paragraph style so the text is truncated rather than 
// wrapped 
NSMutableParagraphStyle* parStyle = [[NSMutableParagraphStyle alloc] init]; 
[parStyle setLineBreakMode:NSLineBreakByTruncatingTail]; 

// Do not let text get squashed to fit 
[parStyle setTighteningFactorForTruncation:0.0]; 

[textView setDefaultParagraphStyle:parStyle]; 
[parStyle release]; 

// Set text 
[textView setString:string]; 

// add NSTextView to border view 
[borderView addSubview:textView]; 
[textView release]; 

// add NSBox to view you want text view displayed in 
[self addSubview:borderView]; 
[borderView release]; 
+0

Hãy nhớ rằng NSTextField sẽ hơi co lại văn bản nếu nó gần khớp mà không cắt xén. [Cả hai trường văn bản này đều có cùng cỡ chữ.] (Http://i.stack.imgur.com/wrJtj.png) –

+1

@JohnSauer Điểm tốt. Điều này thực sự xảy ra đối với NSTextViews. Đó là hành vi mặc định của thuật toán cắt ngắn để cố gắng di chuyển các ký tự gần nhau hơn trước khi cắt bớt. Trong bản chỉnh sửa thứ hai của tôi, tôi dừng điều này bằng cách sử dụng phương thức 'setTighteningFactorForTruncation:' của lớp 'NSMutableParagraphStyle'. – Mathew

+0

cảm ơn câu trả lời của bạn, tôi sẽ thử nó càng sớm càng tốt và tôi sẽ cho bạn biết –

0

Tôi nghĩ bạn có thể làm điều đó bằng cách xem khung của trình chỉnh sửa trường của trường văn bản. Bạn kiểm tra chiều rộng của nó trong controlTextDidBeginEditing, và sau đó một lần nữa trong controlTextDidEndEditing. Nếu giá trị sau lớn hơn, thì văn bản đã bị cắt bớt. Sau đây là thực hiện trong đại biểu của trường text (Tôi tạo ra một Ivar cho initialWidth):

- (void)controlTextDidBeginEditing:(NSNotification *)aNotification { 
    if (! initialWidth) 
     initialWidth = ((NSTextView *)aNotification.userInfo[@"NSFieldEditor"]).frame.size.width; 
} 


- (void)controlTextDidEndEditing:(NSNotification *)aNotification { 
    if (initialWidth) { //Make sure that beginEditing is called first 
     NSInteger finalWidth = ((NSTextView *)aNotification.userInfo[@"NSFieldEditor"]).frame.size.width; 
     if (finalWidth - initialWidth > 1) NSLog(@"We have truncation"); 
     NSLog(@"Final: %ld Initial: %ld", finalWidth,initialWidth); 
    } 
} 

Điều này dường như làm việc hầu hết thời gian, kể cả nếu bạn gõ vào một chuỗi dài, sau đó xóa cho đến khi nó phù hợp một lần nữa. Trong một vài trường hợp, nó đã cho tôi thông điệp tường trình khi tôi là một nhân vật ở cuối phần văn bản, nhưng tôi không nhận được dấu ba chấm khi chỉnh sửa kết thúc.

9

Đối với khách truy cập trong tương lai, bạn có thể sử dụng phương pháp -[NSCell expansionFrameWithFrame:inView:] để xác định xem có cắt xén hay không.Từ tiêu đề:

Cho phép ô trả về khung mở rộng nếu cellFrame là quá nhỏ cho toàn bộ nội dung trong chế độ xem. ... <snip> ... Nếu khung không quá nhỏ, trả về khoảng trống trống và không có giao diện mẹo công cụ mở rộng nào sẽ được hiển thị . Theo mặc định, NSCell trả về NSZeroRect, trong khi một số lớp con (chẳng hạn như NSTextFieldCell) sẽ trả lại khung thích hợp khi được yêu cầu.

Nói tóm lại, bạn có thể cho biết nếu một NSTextField được cắt xén như thế này:

NSRect expansionRect = [[self cell] expansionFrameWithFrame: self.frame inView: self]; 
    BOOL truncating = !NSEqualRects(NSZeroRect, expansionRect); 
+2

đây là giải pháp tốt nhất – jimwan

+0

Bạn có thể vui lòng cung cấp giải pháp Swift 3 không? Tôi không thể điều chỉnh mã Obj-C. – ixany

-1

Swift 4 giải pháp sử dụng ipmcc như cơ sở

Nó sẽ thay đổi kích thước từng người một cho đến khi nó phù hợp hoặc fontsize = 3

var size_not_ok = true 

var conter = 0 
let mininum_font_size = 3 // will resize ultil 3 
while size_not_ok || conter < 15 { // will try 15 times maximun 
    let expansionRect = le_nstextfield.expansionFrame(withFrame: le_nstextfield.frame) 

    let truncated = !NSEqualRects(NSRect.zero, expansionRect) 

    if truncated { 

     if let actual_font_size : CGFloat = le_nstextfield.font?.fontDescriptor.object(forKey: NSFontDescriptor.AttributeName.size) as? CGFloat { 

      le_nstextfield.font = NSFont.systemFont(ofSize: actual_font_size - 1) 

      if actual_font_size < mininum_font_size { 
       break 
      } 
     } 
    } else {   
     size_not_ok = false 
    } 
    conter = conter + 1 
} 
Các vấn đề liên quan