2013-06-04 31 views
5

tôi có một loạt các ký tự unicode gói lên thành NSNumber như vậy:NSString từ Unicode

@(0x1f4de), // EntypoIconTypePhone 
@(0x1f4f1), // EntypoIconTypeMobile 
@(0xe789),  // EntypoIconTypeMouse 
@(0xe723),  // EntypoIconTypeAddress 
@(0x2709),  // EntypoIconTypeMail 
@(0x1f53f), // EntypoIconTypePaperPlane 
@(0x270e),  // EntypoIconTypePencil 

Đây là những biểu tượng từ font Entypo (rất khuyến khích).

Đây là mã tôi đang sử dụng để tạo ra NSString từ unicode:

NSNumber *u = self.unicodeLookup[type]; 

int unicode = [u intValue]; 
UniChar chars[] = {unicode}; 

NSString *string = [[NSString alloc] initWithCharacters:chars length:sizeof(chars)/sizeof(UniChar)]; 

Những gì tôi đang tìm kiếm là một số trong những biểu tượng đang được tạo ra như mong đợi nhưng không phải tất cả trong số họ; và từ những gì tôi có thể thấy nó là các unicodes có 5 chữ số trong chúng không được tạo ra đúng cách.

Ví dụ, những công việc:

@(0xe723),  // EntypoIconTypeAddress 
@(0x2709),  // EntypoIconTypeMail 

nhưng những điều này không:

@(0x1f4de), // EntypoIconTypePhone 
@(0x1f4f1), // EntypoIconTypeMobile 

Tôi khá chắc chắn đây là mã chuyển đổi của tôi. Tôi không thực sự hiểu tất cả điều này mã hóa malarky.

+0

+1 cho malarkey – uchuugaka

Trả lời

2

Nếu bạn lưu trữ các hằng số nhân vật của bạn sử dụng unichar, chứ không phải là NSNumber đối tượng, sau đó trình biên dịch tự nó sẽ cho bạn biết lý do:

unichar chars[] = 
{ 
    0xe723,  // EntypoIconTypeAddress 
    0x2709,  // EntypoIconTypeMail 
    0x1f4de, // EntypoIconTypePhone 
    0x1f4f1  // EntypoIconTypeMobile 
}; 

Implicit conversion from 'int' to 'unichar' (aka 'unsigned short') changes value from 128222 to 62686 
Implicit conversion from 'int' to 'unichar' (aka 'unsigned short') changes value from 128241 to 62705 

Như iOS/OSX sử dụng đại diện 16-bit của ký tự unicode trong nội bộ, và 0x1f4de0x1f4f1 đều 32-bit, bạn sẽ cần để mã hóa những nhân vật như cặp thay thế:

a = 0x1f4de - 0x10000 = 0xf4de 
high = a >> 10 = 0x3d 
low = a & 0x3ff = 0xde 
w1 = high + 0xd800 = 0xd83d 
w2 = low + 0xdc00 = 0xdcde 

0x1f4de (UTF-32) = 0xd83d 0xdcde (UTF-16) 

(Xem Wikipedia page này).

Kết quả là bạn không thể sử dụng một mảng ký tự unicode duy nhất vì bạn sẽ phải biết độ dài mã hóa của mỗi ký tự.

+0

Tôi đã quản lý để có được các ký tự trong ví dụ của bạn để hiển thị bằng cách sử dụng mã trong nhận xét thứ hai của tôi. Vấn đề duy nhất bây giờ là các ký tự phông chữ xã hội. Cảm ơn lời khuyên của bạn mặc dù, tôi sẽ chơi xung quanh để xem nếu tôi có thể có được những người để làm việc quá. –

+0

Tôi nhận thấy các cảnh báo khi tôi sử dụng unichar nhưng nó hoạt động nếu tôi chỉ cast mảng của tôi để int. –

+0

@LeeProbert 'int' sẽ luôn có ít nhất 32 bit, nhưng' unichar' luôn là 16 bit. Một tùy chọn cho bạn là lưu trữ các ký tự của bạn dưới dạng UTF-32 (trong một 'unsigned', không phải là' unichar') và sau đó sử dụng '[NSString initWithBytes: length: encoding:]' với một mã hóa 'NSUTF32StringEncoding', tuy nhiên có có thể là vấn đề cuối cùng cần giải quyết (tôi chưa xem xét nó). – trojanfoe

2

Nếu tôi sử dụng này để tạo chuỗi của tôi nó làm việc cho Entypo font unicode int giá trị:

int unicode = uniChars[type]; 

NSString* s = [[NSString alloc] initWithBytes:&unicode length:sizeof(unicode) encoding:NSUTF32LittleEndianStringEncoding]; 

uniChars là một CArray của int s thay vì NSArray của NSNumber s tôi đã từng. Không có lý do cho điều này thực sự, nó sẽ làm việc với cả hai.

UPDATE:

Vẫn còn một vấn đề với một số các số unicode. Các ký tự phông chữ xã hội Entypo không hiển thị. Sự khác biệt giữa các biểu tượng này và các biểu tượng thông thường là tất cả đều bắt đầu bằng F và có 4 ký tự:

0xF300 ,   // EntypoIconSocialTypeGithub, 
0xF301 ,   // EntypoIconSocialTypeCGithub, 
0xF303 ,   // EntypoIconSocialTypeFlickr, 
0xF304 ,   // EntypoIconSocialTypeCFlickr, 

Tôi nghi ngờ mã hóa sẽ khác.