2009-05-27 39 views
19

Trước khi tôi hỏi câu hỏi của tôi, đây là từ tái tài liệu của Apple: làm thế nào để xác định chiều rộng của một chuỗi sử dụng thạch anh:SDK iPhone: Làm cách nào để đo chiều rộng và chiều cao của chuỗi bằng Quartz?

Nếu đo văn bản rất quan trọng để ứng dụng của bạn, nó có thể để tính toán chúng bằng thạch anh Chức năng 2D. Tuy nhiên, trước tiên bạn có thể xem xét sử dụng ATSUI, có độ mạnh là bố cục văn bản và đo lường . ATSUI có một số hàm có số liệu văn bản. Không chỉ chỉ bạn mới có thể nhận được số liệu văn bản sau bố cục, nhưng trong trường hợp hiếm hoi bạn cần chúng, bạn có thể lấy số liệu văn bản trước bố cục. Không giống như Quartz, mà bạn phải tự thực hiện các phép tính, ATSUI tính toán các phép đo cho bạn. Ví dụ: bạn có thể lấy hình chữ nhật giới hạn hình ảnh cho văn bản bằng cách gọi hàm ATSUI ATSUMeasureTextImage.

Nếu bạn quyết định rằng thạch anh văn bản phù hợp với nhu cầu của bạn tốt hơn so với ATSUI (hoặc Cocoa), bạn có thể làm theo các bước sau để đo chiều rộng của văn bản trước khi thạch anh rút nó:

  1. Gọi chức năng CGContextGetTextPosition để có được vị trí văn bản hiện tại.
  2. Đặt chế độ vẽ văn bản thành kCGTextInvisible bằng cách sử dụng hàm CGContextSetTextDrawingMode.
  3. Vẽ văn bản bằng cách gọi hàm CGContextShowText để vẽ văn bản tại vị trí văn bản hiện tại.
  4. Xác định vị trí văn bản cuối cùng bằng cách gọi hàm CGContextGetTextPosition.
  5. Trừ vị trí bắt đầu khỏi vị trí kết thúc để xác định chiều rộng của văn bản.

Dưới đây là những câu hỏi của tôi:

  1. Đây có phải là thực sự là cách tốt nhất để xác định chiều rộng của một chuỗi sử dụng Core Graphics? Nó có vẻ mỏng manh và kể từ khi văn bản của tôi cùng tồn tại với các yếu tố đồ họa 2D, tôi muốn sử dụng cùng một bối cảnh cho tất cả các hiển thị. Tôi đã hy vọng sẽ có một số phương pháp nhỏ gọn, như:

    CGContextGetTextWidthAndHeight (ngữ cảnh, văn bản);

  2. Tôi đọc rằng ATSUI đã lỗi thời và sẽ được thay thế bằng Văn bản cốt lõi. Điều đó có đúng không và nếu có, nó có nằm trong SDK iPhone không?

+0

Văn bản chính hiện được gửi trong iOS 4. Tuy nhiên, các phương thức pgb được trả lời đơn giản nhất. – Eonil

Trả lời

22

Trên SDK iPhone, có một nhóm phương pháp trên NSString cung cấp những gì bạn muốn.

Tính đến iOS 7.0, these methods are:

- boundingRectWithSize:options:attributes:context: 
- sizeWithAttributes: 

Mở phiên bản cũ của iOS chúng tôi đã có những, bây giờ bị phản đối:

– sizeWithFont: 
– sizeWithFont:forWidth:lineBreakMode: 
– sizeWithFont:constrainedToSize: 
– sizeWithFont:constrainedToSize:lineBreakMode: 
– sizeWithFont:minFontSize:actualFontSize:forWidth:lineBreakMode: 
+0

Tôi không nhận ra rằng bạn có thể trộn và kết hợp các cuộc gọi Core Graphics với các đối tượng Objective-C ... CG có chức năng vẽ văn bản riêng dựa trên mảng const char nhưng chuông và còi hạn chế. Có vẻ như "ngữ cảnh hiện tại" chỉ đơn giản có nghĩa là bối cảnh cuối cùng được khởi tạo, ví dụ: \t CGContextSetFillColorWithColor (context, color.CGColor); \t [text drawAtPoint: origin withFont: font]; Cảm ơn lời khuyên tuyệt vời! –

+1

Trên thực tế, tôi khá chắc chắn rằng theo ngữ cảnh hiện tại, chúng có nghĩa là bối cảnh được trả về bởi UIGraphicsGetCurrentContext() –

+0

Bạn có thể _không trộn và kết hợp trong các trường hợp cụ thể - cụ thể; bất cứ điều gì mà gọi UI___ (chẳng hạn như UIGraphicsGetCurrentContext()) từ bất kỳ chủ đề nào khác ngoài chủ đề chính sẽ thường xuyên thất bại. Đây là một vấn đề nghiêm trọng, đặc biệt là khi bạn đang sử dụng những thứ như CATiledLayer - thực hiện nó hiển thị không đồng bộ trên các chủ đề nền. – Steve

0

Khi thực hiện vẽ các hoạt động trên các chủ đề khác với thread UI, bạn phải sử dụng kỹ thuật bạn mô tả.Điều này đặc biệt quan trọng cần lưu ý khi sử dụng những thứ như CATiledLayer, thực hiện nó hiển thị không đồng bộ trên các chủ đề nền hoặc khi vẽ đồ họa tùy chỉnh ở chế độ nền vì bất kỳ lý do nào khác.

Tôi đồng ý với PGB khi bạn đang làm đồ họa "đơn giản" và bạn được đảm bảo đang chạy trên chuỗi chính. Tuy nhiên, sizeWithFont đang làm điều tương tự như kỹ thuật bạn đã mô tả - nó đơn giản là làm việc đó cho bạn sử dụng UIGraphicsGetCurrentContext().

Các vấn đề liên quan