Html iOS中带有自定义字体的阿拉伯文文本

Html iOS中带有自定义字体的阿拉伯文文本,html,ios,fonts,uiwebview,arabic,Html,Ios,Fonts,Uiwebview,Arabic,我正在开发一个应用程序,它需要使用自定义的阿拉伯语字体显示阿拉伯语文本。问题是,我在使用自定义阿拉伯字体显示阿拉伯文本方面没有任何运气。我已经尝试在UILabel、UITextField、UITextView、UIWebView、FontLabel(由Zynga提供)和CoreText中显示文本 您可以在此处找到示例项目: 使用UIWebView(HTML)的示例应用程序:您必须安装 示例项目中的字体。然后,您可以比较结果并查看 通过在模拟器(或iPad)中运行应用程序来解决问题,以及 在浏

我正在开发一个应用程序,它需要使用自定义的阿拉伯语字体显示阿拉伯语文本。问题是,我在使用自定义阿拉伯字体显示阿拉伯文本方面没有任何运气。我已经尝试在UILabel、UITextField、UITextView、UIWebView、FontLabel(由Zynga提供)和CoreText中显示文本

您可以在此处找到示例项目:

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

我在苹果的开发者论坛上发布了一些细节,但我总是发现stackoverflow比苹果的官方开发者论坛活跃得多。以下是该帖子的链接:

我做错了什么

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


p、 有几篇关于stackoverflow的帖子谈到了这个话题,但没有一篇对我有多大帮助,所以我现在发布一个新问题。

更新:

从iOS 7开始,您实际上不需要使用核心文本来呈现自定义阿拉伯字体。您可以将
UILabel
和/或
UITextView
nsattributestring
一起使用。结果与使用核心文本得到的结果相同。然而,根据您的需求,使用核心文本仍然是一个更好的选择


更新:

我已经向苹果公司报告了这个bug,但我不确定他们什么时候会增加对阿拉伯语字体的支持。目前,没有简单的方法可以做到这一点。我最终使用了默认的系统字体,这不是很好

原始消息

我确实设法构建了一个使用自定义阿拉伯字体的古兰经应用程序。我使用已知的阿拉伯文字体和
核心文本
框架来获得所需的结果。通过检查应用程序,您可以看到我最终得到的结果,该应用程序可在应用程序商店中获得

下面是一些帮助您解决问题的示例代码:

- (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];
}
请注意,我使用的是
CATextLayer
CTFontRef
。这种方法存在一些问题。 1.您将不得不接受所选“自定义阿拉伯字体”中的问题。 2.您必须使用阿拉伯文文本,该文本使用字体支持的扩展字符


HTH.

这些课程将完成以下工作:

下载它们,我敢肯定这回答了你的问题,因为我以前也遇到过同样的问题

代码示例如下:

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

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

如果您的目标是iOS 6,您可以使用
nsAttributeString
更简单地实现这一点:

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

cell.textLabel.attributedText = attributedString;

请参阅我的回答,了解与阿拉伯字体相关的其他问题,如行距和连字。

我早在2012年年中就开始学习iOS开发,我一直在互联网上到处搜索,为iPhone中的自定义波斯字体找到合适的解决方案,永远也找不到合适的解决办法。我曾经尝试过一个
核心文本
库,但它并不总是很好用,特别是您必须创建一个额外的
子视图
来添加带有自定义字体的文本。不久前,我尝试了
阿拉伯语转换器
,它工作正常,但使用新的Xcode,除了在web视图中,它根本没有对文本进行任何更改,只是出现了故障

所以。。。不管怎么说,我很高兴苹果正在解决支持更多语言的问题。下面是一个非常简单的解决方案,效果非常好:

  • 转到项目的
    info.plist
    文件
  • 右键单击并选择添加行
  • 在新行中键入应用程序提供的字体
  • 键入所需的字体名称作为此键的项目
  • 将字体文件拖放到项目中
  • 将其应用于所需的文本:
  • UITextView*persianText;
    persianText.text=@“persianText.text”;
    persianText.font=[UIFont fontWithName:@“IranNastaliq”大小:12.0]

    嗯。。。!构建并运行。。。塔达阿!它起作用了


    对于UIWebview:基本上没有解决
    UIWebview
    案例。。这是我解决这个问题的方法

    首先:使用obj-c HTML解析器,我浏览了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;
    }
    
    //contentText是HTML文本。格式仅为标记中的文本
    NSData*contentData=[contentText数据使用编码:NSUTF8StringEncoding];
    TFHpple*htmlParser=[TFHpple-hppleWithHTMLData:contentData];
    NSString*htmlXpathQueryString=@+//p”;
    NSArray*newsNodes=[htmlParser searchWithXPathQuery:htmlXpathQueryString];
    NSMutableArray*新闻段落=[@[]mutableCopy];
    NSMutableString*新闻内容=[@”“mutableCopy];
    for(新闻节点中的TFHppleElement*元素){
    NSString*paragraphText=[[element firstChild]content];
    [新闻段落添加对象:段落文本];
    [新闻内容附录格式:@“%@\n”,段落文本];
    }
    //如下所述(bodyView是一个CTContainerView对象)
    self.bodyView.contentStr=新闻内容;
    self.bodyView.callback=^(CGSize){
    [自调整滚动视图大小:大小];
    };
    [self.bodyView buildFrames];
    -(无效)调整ScrollViewSize:(CGSize)内容大小{
    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;
    }
    
    #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
    
    #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;
    }
    
    #import <UIKit/UIKit.h>
    
    @interface CTView : UIView
    @property (nonatomic, strong) id ctFrame;
    @end
    
    #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