zoukankan      html  css  js  c++  java
  • IOS APP 国际化(实现不跟随系统语言,不用重启应用,代码切换stroyboard ,xib ,图片,其他资源)

    此问题已解决。请看:

     IOS APP 国际化 程序内切换语言实现 不重新启动系统(完美解决方案) 

     接了个变态的需求,要在程序内切换程序语言实现国际化。

    可以先看看这个,比较详细。

    http://blog.csdn.net/xwren362922604/article/details/17190061

    看完之后问题来了,

    1,工程里面大量的 xib  或 storyboard 里面的UI 设定了text ,怎么实现让它们动态加载语言【非设置系统语言重启】

    2,一个简单的思路,当代码触发切换语言 发个通知让 内存里的viewController 刷新UI的text 。[工程里这么都vc 每个都加 岂不累死]

    所有 接下来还可完善下。

    1,切换语言,重新加载window 的根视图。根据不同语言。【搜下网上的storyboard 国际化】

    你会发现 你操作后 xcode 为Main storyboard 添加了三个 文件

    这里依这为理。base和你添加的语言。
    你在这些文件上右键 show in finder 。

    看到那三个文件夹没 .lproj  这里是对应语言的 资源文件。你切换语言是 拿到当前语言eg: en 拼路径en.lproj

    [[NSBundle mainBundle] pathForResource:userLanguage ofType:@"lproj"];

    根据path 得到

    NSBundle

    熟悉吧。这玩意里面就是我们程序需要得资源文件。其实就是XX.lproj 文件夹里德东东

    初始化

    [UIStoryboard storyboardWithName:@"Main" bundle:bundle];

    我们更习惯于 后面的参数滋味nil 。 

    写到这有个问题。其实真正的main 放在了那个base 文件夹里。程序蹦了。让我们来干掉base 。千万别直接删除base文件。那样直接把main 。storyboard 删了。

    在这里

    点文件。右边栏。去掉base 沟。不要管警告。

    再看

    现在可以了。分别在两个文件夹了。

     

    遗留问题:如果支持很多语言,程序会变的很大.有解决的可以交流下

    这里可以附上关于 Base 文件的信息,

    http://samwize.com/2012/11/22/warning-do-not-use-base-internationalization-in-ios-5/

    如里面介绍,iOS 5不支持国际化 Base。 它是在ios6引入的。

     

    2, 写一个vc 基类。注册 和 移除  通知。对于自动刷新vc 内的 UI 。可以在基类里加个数组变量 【blok 的】

    在subVC,这里注意防止循环引用。_weak

    在superVC

    遍历执行。实现自动刷新

    如果你国际化后 还有接着修改storyboard 你在手动去添加 ui 到国际化文件 。string  发现不起作用了。苹果给提供了命令

    ibtool MainStoryboard.storyboard --generate-strings-file New.strings (你也可以取别的名字(New.strings))

     

    每次改完都要执行下确实挺麻烦。网上有个xcode脚本 可以在每次bulid 时帮我们完成,见下面博客:

    http://oleb.net/blog/2013/02/automating-strings-extraction-from-storyboards-for-localization/

    整理出得脚本,注释挺详细了。

    storyboardExt=".storyboard"

    stringsExt=".strings"

    newStringsExt=".strings.new"

    oldStringsExt=".strings.old"

    localeDirExt=".lproj"

     

    # Find storyboard file full path inside project folder

    for storyboardPath in `find ${SRCROOT} -name "*$storyboardExt" -print`

    do

    # Get Base strings file full path

    baseStringsPath=$(echo "$storyboardPath" | sed "s/$storyboardExt/$stringsExt/")

     

    # Create strings file only when storyboard file newer

    #if find $storyboardPath -prune -newer $baseStringsPath -print | grep -q .; then

    # Get storyboard file name and folder

    storyboardFile=$(basename "$storyboardPath")

    storyboardDir=$(dirname "$storyboardPath")

     

    # Get New Base strings file full path and strings file name

    newBaseStringsPath=$(echo "$storyboardPath" | sed "s/$storyboardExt/$newStringsExt/")

    stringsFile=$(basename "$baseStringsPath")

    ibtool --export-strings-file $newBaseStringsPath $storyboardPath

    iconv -f UTF-16 -t UTF-8 $newBaseStringsPath > $baseStringsPath

    rm $newBaseStringsPath

     

    # Get all locale strings folder

    for localeStringsDir in `find ${SRCROOT} -name "*$localeDirExt" -print`

    do

    # Skip Base strings folder

    if [ $localeStringsDir != $storyboardDir ]; then

    localeStringsPath=$localeStringsDir/$stringsFile

     

    # Just copy base strings file on first time

    if [ ! -e $localeStringsPath ]; then

    cp $baseStringsPath $localeStringsPath

    else

    oldLocaleStringsPath=$(echo "$localeStringsPath" | sed "s/$stringsExt/$oldStringsExt/")

    cp $localeStringsPath $oldLocaleStringsPath

     

    # Merge baseStringsPath to localeStringsPath

    awk 'NR == FNR && /^/*/ {x=$0; getline; a[x]=$0; next} /^/*/ {x=$0; print; getline; $0=a[x]?a[x]:$0; printf $0" "}' $oldLocaleStringsPath $baseStringsPath > $localeStringsPath

     

    rm $oldLocaleStringsPath

    fi

    fi

    done

    #else

    #echo "$storyboardPath file not modified."

    #fi

    done

    以上可以做到 在后续修改sb文件后,脚本会自动 将新加内容 添加到 .string文件

    格式如下:

    /* Class = "IBUILabel"; text = "Test2"; ObjectID = "NT7-J3-MH3"; */

    "NT7-J3-MH3.text" = "Test2";

    默认重新生成.string文件后 会覆盖原来的 内容。但这里脚本使用正则表达式 合并了。有兴趣可以搜下 shell 文件的合并。这玩意挺强大的。

     

    使用脚本的前提是 你工程里用了base.lproj 。但上面讨论的 代码切换 sb 文件不能用 base ,而且要支持ios5 使用base 会奔溃掉。

    那只能编辑sb 文件时用 base ,之后运行把base 去掉。在运行;也就去掉base 的勾选。

     

    后续解决能不能 shell 将sb 文件拷贝到APP 包中对应的 语言.lproj 。这样不用每次编辑-运行 都要手动去base沟选。

    尝试了下,可以实现 。但app 里文件li sb 文件后缀名为.storyboardc  ,文件明明在 代码加载却报错。

    有兴趣可以下载demo 里de Debug_st.sh 正是解决这个问题的。#debug if   ....  fi 里的东西是 为了调试故意让它报错的,不影响

    搞定后会再次更新。。。

     

    可以在这里下载我的demo工程: 

    刷新storyboard + 代码刷新 文案

     git clone   git@github.com:githhhh/Test_Local_Two.git   

     

     

     

  • 相关阅读:
    November 07th, 2017 Week 45th Tuesday
    November 06th, 2017 Week 45th Monday
    November 05th, 2017 Week 45th Sunday
    November 04th, 2017 Week 44th Saturday
    November 03rd, 2017 Week 44th Friday
    Asp.net core 学习笔记 ( Area and Feature folder structure 文件结构 )
    图片方向 image orientation Exif
    Asp.net core 学习笔记 ( Router 路由 )
    Asp.net core 学习笔记 ( Configuration 配置 )
    qrcode render 二维码扫描读取
  • 原文地址:https://www.cnblogs.com/DamonTang/p/3898046.html
Copyright © 2011-2022 走看看