2012-01-10 24 views
5

Điều tôi muốn làm là tạo thành phần chứa văn bản có thể cho biết từ gần nhất khi nào có liên lạc trên đó (tức là từ "đằng sau" "điểm xúc động".Lấy từ được chạm vào trong UILabel/UITextView

Trước tiên, tôi đã tạo một lớp con UILabel và ghi đè lên các phương thức chạm: Phương thức: withEvent: để xác định CGPoint được chạm vào. Tôi cũng đã viết một phương pháp tính toán "khung hình" tương ứng (CGRect) của mỗi từ của văn bản bằng cách sử dụng sizeWithFont: forWidth: lineBreakMode :. Với CGPoint chạm và khung này, tôi có thể xác định từ nào thực sự đang được chạm vào. Nhưng phương pháp tính toán khung chỉ hoạt động với văn bản đơn dòng. Vì vậy, bây giờ tôi cần biết phần nào của văn bản nằm trên một dòng nhất định (tức là cách văn bản được tách ra), để tôi có thể tìm đúng lề trái và lề trên của mỗi từ.

Bất kỳ ý tưởng nào về cách tôi có thể có được điều này? Hoặc có thể có bạn một giải pháp đơn giản hơn để đạt được điều này? This post was unfortunately not very helpful... ...

Trả lời

9

(Có một liên kết đến một dự án mã mẫu trong bài liên kết của bạn mà không chứa một số mẫu mã hữu ích, nhưng tôi sẽ phác thảo quá trình cho bạn ở đây quá.)

Nói tóm lại, bạn sẽ cần sử dụng Core Text, đây là khung xử lý văn bản dựa trên C tiên tiến của Apple có thể sao lưu tất cả bố cục văn bản tinh vi trong iOS và OS X.

Mã đầy đủ sẽ tham gia một phần, nhưng các phương pháp chính bạn sẽ muốn xem xét là:

CTFramesetterCreateWithAttributedString() - sử dụng điều này, trong conj chú thích với NSAttributedString mà bạn sẽ nhận được từ văn bản của nhãn của bạn - để tạo khung hình

CTFramesetterCreateFrame() - sử dụng điều này để nhận CTFrameRef cho văn bản của bạn từ bộ khung trên. Bạn sẽ cần phải tạo ra một CGPathRef sử dụng giới hạn nhãn của bạn để làm điều này.

CTFrameGetLines(), CTFrameGetLineOrigins() - sử dụng các mã này để nhận CTLineRefs tương ứng với các dòng sắp xếp và tọa độ của nguồn gốc tương ứng, sau đó sử dụng CTLineGetStringIndexForPosition() để tìm chỉ mục ký tự tại vị trí cảm ứng.

Sau đó, bạn có thể sử dụng chỉ mục ký tự này (trong khung tham chiếu của dòng) để làm việc ngược và tìm ký tự/từ/v.v. trong chuỗi đầy đủ của bạn.

Đừng quên rằng vấn đề trở nên phức tạp bởi một vài vấn đề:

  1. Nếu bạn sử dụng UILabel của bản vẽ bạn sẽ phải chăm sóc đến hoàn hảo phù hợp với số liệu sắp chữ của bạn, có thể là cồng kềnh vì hầu hết các các đối tượng (ví dụ CTFontRef) không phải là cầu nối miễn phí với các đối tác UIKit của chúng. Việc triển khai bản vẽ của riêng bạn đôi khi có thể dễ dàng hơn, điều này sẽ đảm bảo kết hợp chỉ số.

  2. Văn bản chính sử dụng hệ tọa độ ngược đối với hệ thống bản vẽ iOS thông thường. Nếu bạn đang nhận được kết quả wacky, và đặc biệt là nếu bạn làm bản vẽ của riêng bạn, đây là một cái gì đó để có một cái nhìn tại.

Không phải là nhiệm vụ dễ dàng nhất trên thế giới, nhưng không thể thực hiện được. Chúc may mắn!

+0

Trên thực tế, bản vẽ văn bản chính mình là những gì tôi muốn tránh vì nó có vẻ là một chút của phí trên xem xét nhu cầu ban đầu. Tôi sẽ xem xét các chức năng chính của CoreText mà bạn đã cung cấp, cảm ơn bạn! – AgentCorleone

2

Mặc dù đây là một câu hỏi cũ, nhưng tôi nghĩ rằng điều này có thể là một số trợ giúp.

Kể từ khi học văn bản cốt lõi là rất lớn, tôi đã lựa chọn GLTapDemo by German Laullon

Với một vài thay đổi, điều này hoạt động tuyệt vời cho việc phát hiện từ đề cập đến UILabel.

+1

Tôi đã thử cả giải pháp VSWordDetector và giải pháp này, và tìm thấy giải pháp này để hoạt động hiệu quả hơn cho trường hợp sử dụng của tôi. –

5

Sau khi tìm kiếm một chút, tôi đã viết mã cho điều này. Mã sẽ hoạt động cho UITextViewUILabel.
Chỉ cần tải xuống VSWordDetector.zip rồi giải nén và kéo & thả thư mục VSWordDetector vào dự án của bạn.
Có hai tệp VSWordDetector.hVSWordDetector.m
#import VSWordDetector.h trong lớp ViewController của bạn.

@property (strong, nonatomic) VSWordDetector *wordDetector; 

Lưu ý: Làm cho thuộc tính của nó không được thực hiện cục bộ.

Bây giờ sẵn sàng của nó cho bạn, Chỉ cần thêm nó vào textViews hoặc Labels

-(void)viewDidLoad 
{ 
    self.wordDetector = [[VSWordDetector alloc] initWithDelegate:self]; 
    [self.wordDetector addOnView:textView]; 
    [self.wordDetector addOnView:label]; 
} 

-(void)wordDetector:(VSWordDetector *)wordDetector detectWord:(NSString *)word 
{ 
    NSLog(@"Detected Word: %@", word); 
} 

đại biểu Phương pháp này sẽ được gọi khi bạn sẽ gõ vào nhãn kết nối hoặc TextView.

EDIT: cho VSWordDetector.

SUGGESTED EDIT: Nếu bạn không muốn tải xuống mã mẫu ở đây là mã cho cả hai tệp. Vui lòng xem tệp gist này VSWordDetector.

+0

hi. Tôi đã cố gắng sử dụng mã của bạn, nhưng vòi không được phát hiện. tôi đã làm theo các bước u đã đưa ra, bạn có thể cho tôi biết tôi đang đi sai ở đâu không? –

+1

@NijilNair Xin lỗi nhưng tôi không thể nói bạn đang làm gì sai. Vì vậy, tôi đã làm một mẫu xin vui lòng xem phần Chỉnh sửa câu trả lời của tôi. – TheTiger

+0

Tôi không phải là một niềm vui lớn của mã nén. Thêm các phần liên quan của 'VSWordDetector' vào đây hoặc dán mã trên github. – Sulthan