在iOS中使用自定义字体的阿拉伯文字

我正在使用自定义阿拉伯字体来处理需要显示阿拉伯文字的应用程序。 问题是,我没有任何运气显示使用阿拉伯语字体的阿拉伯文字。 我试图在UILabel,UITextField,UITextView,UIWebView,FontLabel(由Zynga)和使用CoreText显示文本。

你可以在这里find示例项目:

使用UILabel,UITextField,UITextView和CoreText的示例应用程序

使用UIWebView的示例应用程序(HTML)

使用UIWebView(HTML)的示例应用程序:您必须在示例项目中安装字体。 然后,您可以比较结果,并通过在模拟器(或iPad)中运行应用程序并在浏览器(Safari)中打开Sample.html文件来查看问题。

我已经在苹果的开发者论坛上发布了一些细节,但是我总是发现stackoverflow比苹果的官方开发者论坛更加活跃。 以下是该post的链接:

在iOS中使用自定义阿拉伯字体

What am i doing wrong? 

注:字体正确加载到系统中,并且我可以成功地将自定义字体应用于常规(英文)文本。

PS有几个关于这个主题的stackoverflow的post,但没有任何帮助,所以我发布一个新的问题。

更新:

从iOS 7开始,您并不需要使用Core Text来呈现自定义阿拉伯字体。 你可以使用UILabel和/或UITextViewNSAttributedString 。 结果与使用Core-Text相同。 不过,根据您的要求,使用核心文本仍然是一个更好的select。

更新:

我已经把这个漏洞报告给苹果公司,但是我不确定他们什么时候会添加对阿拉伯字体的支持。 目前,没有简单的方法来做到这一点。 我结束了使用默认的系统字体,这是不是很好。

原始信息

我设法build立了一个使用自定义阿拉伯字体的古兰经应用程序。 我用Core Text框架使用已知的阿拉伯语字体来获得所需的结果。 您可以通过检查App Store上的应用程序“Quran Presenter for iPad”来查看结果。

这里有一些示例代码可以帮助你:

 - (CTFontRef)newCustomFontWithName:(NSString *)aFontName ofType:(NSString *)type attributes:(NSDictionary *)attributes { NSString *fontPath = [[NSBundle mainBundle] pathForResource:aFontName ofType:type]; NSData *data = [[NSData alloc] initWithContentsOfFile:fontPath]; CGDataProviderRef fontProvider = CGDataProviderCreateWithCFData((CFDataRef)data); [data release]; CGFontRef cgFont = CGFontCreateWithDataProvider(fontProvider); CGDataProviderRelease(fontProvider); CTFontDescriptorRef fontDescriptor = CTFontDescriptorCreateWithAttributes((CFDictionaryRef)attributes); CTFontRef font = CTFontCreateWithGraphicsFont(cgFont, 0, NULL, fontDescriptor); CFRelease(fontDescriptor); CGFontRelease(cgFont); return font; } - (CATextLayer *)customCATextLayer { NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithFloat:24.f], (NSString *)kCTFontSizeAttribute, [NSNumber numberWithInt:1], (NSString *)kCTLigatureAttributeName, nil]; CTFontRef font = [self newCustomFontWithName:@"PDMS_Saleem_QuranFont-signed" ofType:@"ttf" attributes:attributes]; CATextLayer *normalTextLayer = [[CATextLayer alloc] init]; normalTextLayer.font = font; normalTextLayer.string = NSLocalizedString(@"Sample", nil); normalTextLayer.wrapped = YES; normalTextLayer.foregroundColor = [[UIColor blackColor] CGColor]; normalTextLayer.fontSize = 24.f; normalTextLayer.alignmentMode = kCAAlignmentCenter; normalTextLayer.frame = CGRectMake(0.f, 10.f, 320.f, 32.f); CFRelease(font); return [normalTextLayer autorelease]; } - (void)viewDidLoad { [super viewDidLoad]; CATextLayer *normalTextLayer = [self customCATextLayer]; [self.customView.layer addSublayer:normalTextLayer]; } 

请注意,我正在使用CATextLayerCTFontRef 。 这种方法有几个问题。 1.你必须在所选的“自定义阿拉伯字体”中解决问题。 2.您必须使用使用字体支持的扩展字符的阿拉伯文字。

HTH。

这些课程将完成这项工作:

https://github.com/Accorpa/Arabic-Converter-From-and-To-Arabic-Presentation-Forms-B

下载他们,我敢肯定,回答你的问题,因为我以前有完全相同的问题!

代码示例:

 ArabicConverter *converter = [[ArabicConverter alloc] init]; NSString* convertedString = [converter convertArabic:@"منذ دقيقة"]; infoText.font = [UIFont fontWithName:@"YOUARABICFONT" size:16]; infoText.text = convertedString; 

现在infoText将正确显示字体:)

我刚开始在2012年中期开始学习iOS开发,而且我在互联网上到处search,find适合iPhone的自定义波斯语字体的解决scheme,而且永远也找不到合适的解决scheme。 有一个我试过一次的Core Text库,它并不总是很好,特别是你必须做一个额外的subview添加自定义字体的文字。 我试了一下Arabic Converter ,它工作正常,但新的Xcode并没有改变文字,除了在networking视图,只是出现故障!

所以…无论如何,我很高兴苹果正在解决问题,以支持更多的语言。 现在这里是非常简单的解决scheme,完美的工作:

  1. 转到您项目的info.plist文件,
  2. 右键单击并selectAdd row
  3. 在新行中键入Fonts provided by application
  4. input所需的字体名称作为此项的项目。

在这里输入图像说明

  1. 将字体文件拖放到项目中,
  2. 将其应用到您想要的文本:

UITextView *persianText; persianText.text = @"در جستجوی قهرمان نباشید \nبلکه خود قهرمان شوید"; persianText.font = [UIFont fontWithName:@"IranNastaliq" size: 12.0];

Annnd …! build立并运行… Tadaaa! 有用!

在这里输入图像说明

如果你的目标是iOS 6,那么你可以使用NSAttributedString来实现这一点:

 NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:info.text attributes:@{ NSFontAttributeName : [UIFont fontWithName:@"Scheherazade" size:32], NSLigatureAttributeName: @2}]; cell.textLabel.attributedText = attributedString; 

有关其他与阿拉伯语字体相关的其他问题的讨论,请参阅我的答案,例如行间距和连字。

对于UIWebview:基本上接受的答案不解决UIWebView情况下..所以这里是我解决这个问题的一种方法。

第一:使用hpple ,一个obj-c HTMLparsing器,我通过html,基本上取消了文本,并附加到一个NSMutableString像这样:

 // contentText is the HTML text. The format is just text in <p> tags NSData *contentData = [contentText dataUsingEncoding:NSUTF8StringEncoding]; TFHpple *htmlParser = [TFHpple hppleWithHTMLData:contentData]; NSString *htmlXpathQueryString = @"//p"; NSArray *newsNodes = [htmlParser searchWithXPathQuery:htmlXpathQueryString]; NSMutableArray *newsParagraphs = [@[] mutableCopy]; NSMutableString *newsContent = [@"" mutableCopy]; for (TFHppleElement *element in newsNodes) { NSString *paragraphText = [[element firstChild] content]; [newsParagraphs addObject:paragraphText]; [newsContent appendFormat:@"%@\n",paragraphText]; } // explained below (bodyView is a CTContainerView object) self.bodyView.contentStr = newsContent; self.bodyView.callback = ^(CGSize size) { [self adjustScrollViewSize:size]; }; [self.bodyView buildFrames]; - (void)adjustScrollViewSize:(CGSize)contentSize { CGRect overallSize = CGRectUnion(imageView.frame, titleText.frame); CGRect bodyViewFr = self.bodyView.frame; CGRect bodyViewWrapperFr = CGRectMake(bodyViewFr.origin.x, bodyViewFr.origin.y, contentSize.width, contentSize.height+30); overallSize = CGRectUnion(overallSize, bodyViewWrapperFr); self.scrollView.contentSize = overallSize.size; } 

然后,我使用Core Text将文本呈现到webview中,遵循本教程中的步骤。 以下是其他文件:

CTContainerView.h

 #import <UIKit/UIKit.h> typedef void (^CompletionBlock)(CGSize size); @interface CTContainerView : UIView @property (nonatomic, strong) NSString *contentStr; @property (nonatomic, strong) CompletionBlock callback; - (void)buildFrames; @end 

CTContainerView.m

 #import <CoreText/CoreText.h> #import "CTContainerView.h" #import "CTView.h" const float kMargin = 10; @implementation CTContainerView { NSAttributedString* attString; } // get the required size for the final view to render // the complete text of the body.. then pass it on // to CTContentView - (void)buildFrames { // first build the attributedString with all its properties NSString *fontName = @"29LTBukra"; // THE ARABIC FONT NAME!!!! CTFontRef fontRef = CTFontCreateWithName((CFStringRef)fontName, 12.0f, NULL); NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init]; [paragraphStyle setLineSpacing:6]; NSDictionary *attrs = [NSDictionary dictionaryWithObjectsAndKeys:(__bridge id)fontRef, kCTFontAttributeName, paragraphStyle, NSParagraphStyleAttributeName, nil]; attString = [[NSAttributedString alloc] initWithString:self.contentStr attributes:attrs]; // get the required final view size given attString CGRect selfFr = self.frame; CGRect textFr = CGRectInset(selfFr, kMargin, kMargin); CGSize requiredSize = [self getRequiredViewSizeInViewWithSize:textFr.size]; requiredSize.height = requiredSize.height + 100; CGRect requiredFrame = CGRectMake(self.bounds.origin.x, self.bounds.origin.y, requiredSize.width, requiredSize.height); // construct a CTFrameRef based on the 1. attStr and 2. calculated fr above CGMutablePathRef path = CGPathCreateMutable(); //1 CGPathAddRect(path, NULL, requiredFrame); CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((CFAttributedStringRef)attString); //3 CTFrameRef frame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, [attString length]), path, NULL); // adjust size of container selfFr.size = requiredSize; self.frame = selfFr; // create an empty CTContentView CTView *ctView = [[CTView alloc] initWithFrame: CGRectMake(5, 0, requiredSize.width, requiredSize.height)]; [ctView setBackgroundColor:[UIColor whiteColor]]; [ctView setCtFrame:(__bridge id)(frame)]; [self addSubview:ctView]; CFRelease(path); // call callback self.callback(requiredSize); } - (CGSize)getRequiredViewSizeInViewWithSize:(CGSize)viewSize { CGRect paragraphRect = [attString boundingRectWithSize:CGSizeMake(viewSize.width, CGFLOAT_MAX) options:(NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading) context:nil]; return paragraphRect.size; } 

CTContentView.h

 #import <UIKit/UIKit.h> @interface CTView : UIView @property (nonatomic, strong) id ctFrame; @end 

CTContentView.m

 #import <CoreText/CoreText.h> #import "CTView.h" @implementation CTView @synthesize ctFrame; -(void)drawRect:(CGRect)rect { CGContextRef context = UIGraphicsGetCurrentContext(); // Flip the coordinate system CGContextSetTextMatrix(context, CGAffineTransformIdentity); CGContextTranslateCTM(context, 0, self.bounds.size.height); CGContextScaleCTM(context, 1.0, -1.0); CTFrameDraw((CTFrameRef)ctFrame, context); } @end