ios 本地化国际化

个人对这个研究得比较久,也实际项目测过每一种方式;自认为是相对网上各种,是最全最详细的。欢迎大家交流!


需要国际化的内容:
  • 文本信息国际化(代码国际化):包括应用名称(InfoPlist.strings),按钮,警告提示信息以及界面中显示的静态文字;
  • Xib/Storyboard 国际化:同一个界面和场景可以提供多个本地化版本的xib和storyboard 文件;
  • 资源文件国际化:包括图片和音频等资源;图片国际化包括应用图标和一般图片的国际化;

    demo 地址:(由于csdn不能上传附件,我放到资源里去了)
    http://download.csdn.net/download/lixin88/10050869


    一. InfoPlist.strings-应用名称国际化
    1:创建 InfoPlist.strings
    在xcode6 之前的版本中InfoPlist.strings会自动创建;
    本例子是xcode8,需要自己创建,new file,选择Strings File,命名为 InfoPlist.strings; 创建的文件名必须是InfoPlist.strings且不需要写任何代码;







    2: 先给整个project添加语言支持
    如果需要使用某种语言,需要先给整个project添加支持,比如简体中文,如下添加好;




    3.实现InfoPlist.strings本地化
    InfoPlist.strings文件中添加  CFBundleDisplayName=" 国际化"
      选中 InfoPlist.strings文件,打开文件检查器,选中Localize,如下:





      会弹出对话框,由于之前添加了中文支持,则此处有简体中文和英文2个选项:


      下拉列表中,选择Chinese(Simple) ; 然后在右边红色框中勾选English,则会生成相应左边红色框的文件,在文件里面修改key对应的value即可;






      现在来看下整个目录结构,注意这个和project 一个层级,会生成语言.lproj 目录,下面放着对应的 InfoPlist.strings






      二.程序代码输出的静态文本国际化
      1.默认命字符串资源文件
      Localizable.strings, 创建参考上文的InfoPlist.strings,创建后,添加英文版和简体中文版本支持,生成的文件结构如下图,然后修改对应的值即可。
       

      调用方式如下:
      Localizable.strings多语言文件,用于本地化App内容的字符串,用户创建时必须这样命名,与之对应的调用方法是(这个宏在Foundation框架中):
      #define NSLocalizedString(key, comment) \
      [NSBundle.mainBundle localizedStringForKey:(key) value:@"" table:nil]
      例如:label.text = NSLocalizedString(@"labelText", @"中国”);


      2.自定义字符串资源文件
      我们通过一个 Localizable.strings 文件来存储每个语言的文本,它是iOS默认加载的文件,如果想用自定义名称命名,在使用 NSLocalizedString 方法时指定tableName为自定义名称就好了,但你的应用规模不是很大就不要分模块搞特殊了。比如自定义命名为 Language.strings;

      调用方式如下:
      Language.strings 同样是多语言文件,用于本地化APP内容的字符串,不同于Localizable的是,用户创建时可以随意取名,与之对应的方法是:
      #define NSLocalizedStringFromTable(key, tbl, comment) \
      [NSBundle.mainBundle localizedStringForKey:(key) value:@"" table:(tbl)]
      例如:label.text = NSLocalizedStringFromTable(@"labelText",@"Language",@"中国");

      genstrings工具批量静态文本国际化
      代码中即.m文件的国际化首先在你需要进行国际化处理的字符串外面加一层NSLocalizedString,注意中文也是可以的哦

      NSLocalizedString是一个定义在NSBundle.h中的宏,其用途是寻找当前系统语言对应的Localizable.strings文件中的某个key的值。
      第一个参数是key的名字,第二个参数是对这个“键值对”的注释,在用genstrings工具生成Localizable.strings文件时会自动加上去。
      当我们把所有的.m文件都修改好了,就可以动用genstrings工具了

      1. 启动终端,进入工程所在目录。
      2. 新建两个目录,推荐放在资源目录下。
      目录名会作用到Localizable.strings文件对应的语言,不能写错了。这里zh-Hans指简体中文,注意不能用zh.lproj表示。
      mkdir zh-Hans.lproj
      mkdir en.lproj

      3. 生成Localizable.strings文件
      genstrings -o zh-Hans.lproj *.m
      genstrings -o en.lproj *.m
      -o <文件夹>,指定生成的Localizable.strings文件放置的目录。
      *.m,扫描所有的.m文件。这里支持的文件还包括.h, .java等。

      上面genstrings指令只能是该目录下的文件遍历,但不能实现递归遍历,这样在一些大工程里面明显不能满足需求,于是在工程里更普遍的用法是
      find ./ -name *.m | xargs genstrings -o en.lproj





      三.xib 和故事板文件国际化
      使用Base 国际化技术
      Base 国际化 是Xcode 4.5 之后新的解决国际化的技术,用来解决标识故事板和xib文件的国际化问题。
      在4.5 之前如果storyboard支持多语言,则会有多份"语言.lproj”,每个子目录下都有一份Main.storyboard,如果需要修改,则需要维护多份;
      在4.5 之后,只需要在Base.lproj 中存一份,其他本地化语言,只生成Main.strings文件来存放信息即可;


      storyboard 国际化语言支持也和上面一样, 打开文件检查器,选中Localize,如下右边框,则会生成对应左边框内;




      宏观目录结构如下:



      新增控件怎么办?
      方法1. 手动添加
      如果需要新添加一个控件,比如输入框,如下方式找到ID,然后加到你需要本地化的语言 Main.strings文件中;
      比如在中文版的 Main.strings中添加:
       “ IOr-1q-mE7 ”=“查询”;


      注意:使用auto layout 设置,来保证 “标签+文本框” 在国际化前后能保持固定的宽度;



      方法2.   ibtool工具 自动添加
                    相应语言的strings一旦生成后,Base Storyboard有任何编辑都不会影响到strings,这就意味着如果我们删除或添加了一个UILabel的text,strings也不能同步改动
      还好,Xcode为我们提供了ibtool工具来生成Storyboard的strings文件。

      ibtool Main.storyboard --generate-strings-file ./NewTemp.string

      但是ibtool生成的strings文件是BaseStoryboard的strings(默认语言的strings),且会把我们原来的strings替换掉。所以我们要做的就是把新生成的strings与旧的strings进行冲突处理(新的附加上,删除掉的注释掉),这一切可以用这个pythoy脚本来实现,见 AutoGenStrings.py 。然后我们将借助 Xcode 中 Run Script 来运行这段脚本。这样每次Build时都会保证语言strings与Base Storyboard保持一致





      三.资源文件国际化

      图片本地化
      本地化图片,有两种方式,第一种方式和本地化代码中的字符串一样,通过NSLocalizedString(key,comment)来获取相应的字符串,然后根据这个字符串再获取图片。

      方式一:自定义文本命名


      利用文本国际化的方式,在代码中调用
      UIImage(named: NSLocalizedString("search_logo",comment: ""))
      
      
      不推荐,一是因为做法太low了,工作量明显加大。二是不能在Storyboard或XIB中使用
      


      方式二: 原生支持

      将图片添加到工程,选中某个图片,打开其文件检查器,点击Localization 中的Localized 按钮,同上,选择要支持的语言,这样该资源文件就被移动到 对应的”语言.lproj”目录下面了;



      使用这种方式,在XIB或Storyboard中引用图片时如果只使用名称是实时显示不了的,一定要加上后缀名。如avater.png
      使用方式不变,iOS会自动找相应语言(xxx.lproj)下的图片
      1
      UIImage(named:  "avater" )



      2.声音资源


      新版Xcode中Images.xcassets不支持国际化(属性页面中没有 Localization ),Xcode5以前是支持的;
      正确姿态应该是需要国际化的图片放在自定义Group里面,不需要国际化的图片放在Images.xcassets




      四.如何测试

      • 设置运行语言环境
      有时我们第一次安装APP时不想默认跟随系统,那么可以通过Xcode的scheme来指定特定语言
      或者在系统设置中,切换语言测试







      五.应用内切换语言



      应用启动时,首先会读取NSUserDefaults中的key为AppleLanguages的内容,该key返回一个String数组,存储着APP支持的语言列表,数组的第一项为APP当前默认的语言。
      1
      2
      //获取APP当前语言
      (NSUserDefaults.standardUserDefaults().valueForKey( "AppleLanguages" ) as! Array)[0]
      那么我们要实现语言切换改变AppleLanguages的值即可,因为苹果没提供给我们直接修改APP默认语言的API,我们只能通过NSUserDefaults手动去操作,且AppleLanguages的值改变后APP得重新启动后才会生效(才会读取相应语言的lproj中的资源,意义着就算你改了,资源还是加载的APP启动时lproj中的资源),猜测应该是框架层在第一次加载时对AppleLanguages的值进行了内存缓冲
      1
      2
      3
      4
      //设置APP当前语言
      var   def = NSUserDefaults.standardUserDefaults()
      def.setValue([“zh-Hans”], forKey: "AppleLanguages" )
      def.synchronize()

      那么问题来了,如何做到改变AppleLanguages的值就加载相应语言的lproj资源?
      其实,APP中的Storyboard的加载,图片与字符串的加载都是在NSBundle.mainBundle()上操作的,那么我们只要在语言切换后把NSBundle.mainBundle()替换成当前语言的bundle就行了,这样系统通过NSBundle.mainBundle()去加载资源时实则是加载的当前语言bundle中的资源
      评论
      添加红包

      请填写红包祝福语或标题

      红包个数最小为10个

      红包金额最低5元

      当前余额3.43前往充值 >
      需支付:10.00
      成就一亿技术人!
      领取后你会自动成为博主和红包主的粉丝 规则
      hope_wisdom
      发出的红包
      实付
      使用余额支付
      点击重新获取
      扫码支付
      钱包余额 0

      抵扣说明:

      1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
      2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

      余额充值