uti | id | title | platforms | packages | ||||||
---|---|---|---|---|---|---|---|---|---|---|
com.xamarin.workbook |
285ac8e2-25ef-4e22-965c-f04643524c48 |
Untitled |
|
|
xamarin/Xamarin.Forms#1244 のPRをマージを待たずに自分でXamarin.Forms.iOSのILを書き換えることで実現するサンプル
#r "Mono.Cecil"
#r "Mono.Cecil.Mdb"
#r "Mono.Cecil.Pdb"
#r "Mono.Cecil.Rocks"
using System;
using System.Reflection;
using Mono.Cecil;
using Mono.Cecil.Cil;
using Mono.Cecil.Rocks;
以下のCellに対象となるアセンブリとそれを格納しているディレクトリを記述する.
基本的にはアセンブリが含まれるディレクトリを記述すればいいのだが,Xamarin.Forms.Platform.iOSを_monodis_などで開いてわかるように,リゾルバがカレントディレクトリだけでは解決できていないことがわかる(ikdasmだといい感じに探してくれる).
そのため今回はエラーとして出たXamarin.iOSのアセンブリを含むディレクトリを追加している.
var baseDir = "/Users/yamachu/Project/Xamarin/TonpeiFes/packages/Xamarin.Forms.2.4.0.18342/lib/Xamarin.iOS10";
var xamiosInstallDir = "/Library/Frameworks/Xamarin.iOS.framework/Versions/11.4.0.93/lib/64bits";
var assemblyResolver = new DefaultAssemblyResolver();
assemblyResolver.AddSearchDirectory(baseDir);
assemblyResolver.AddSearchDirectory(xamiosInstallDir);
var asm = AssemblyDefinition.ReadAssembly(System.IO.Path.Combine(baseDir, "Xamarin.Forms.Platform.iOS.dll"), new ReaderParameters{AssemblyResolver = assemblyResolver});
var targetType = asm.MainModule.GetType("Xamarin.Forms.Platform.iOS.ListViewRenderer");
var targetMethod = targetType.Methods.First(x => x.Name == "UpdateItems");
ちょっと見やすくしてくれる.こっちの方が楽そうなので使用したが,問題出てたらつらい(要確認
targetMethod.Body.SimplifyMacros();
var proc = targetMethod.Body.GetILProcessor();
// groupReset 変数を詰む
proc.InsertBefore(targetMethod.Body.Instructions[20], Instruction.Create(OpCodes.Ldloc_1));
// if 文のブロックの終わった先のジャンプ先を格納
// このタイミングでやらないで,,Createのなかでそのまま記述するとずれるので注意
var tmp = targetMethod.Body.Instructions[51];
proc.InsertBefore(targetMethod.Body.Instructions[21], Instruction.Create(OpCodes.Brtrue, tmp));
Simplifyしたので,これを戻して命令長などの修正をする
targetMethod.Body.OptimizeMacros();
asm.Write(System.IO.Path.Combine(baseDir, "NewXamarin.Forms.Platform.iOS.dll"));