Xamarin.iOS UIApperance setDefaultTextAttributes

Posted

技术标签:

【中文标题】Xamarin.iOS UIApperance setDefaultTextAttributes【英文标题】: 【发布时间】:2018-01-15 11:59:22 【问题描述】:

我正在尝试弄清楚如何在 Xamarin 中实现以下代码:

[[UITextField appearanceWhenContainedIn:[UISearchBar class], nil] setDefaultTextAttributes:@NSForegroundColorAttributeName:[UIColor greenColor]];

但我找不到在 UIApperance 类上设置默认文本属性的方法。

【问题讨论】:

【参考方案1】:

Xamarin.ios 中有 number 个缺少 UIAppearance 功能,关于您的问题,有一个 missing API。

这是一个错误,? 我写了自己的 UIAppearance.cs 来添加缺失的功能并更正缺失的 API,假设没有其他 Xamarin.iOS 编码器真正使用较新的 UIAppearance 功能作为自 Xamarin 中的 iOS 9 以来,它已被破坏。

首先,appearanceWhenContainedIn 已弃用,您应该改用 appearanceWhenContainedInInstancesOfClasses

AppearanceWhenContainedIn - 在 iOS 9 中已弃用,不推荐使用。

其次,appearanceWhenContainedInInstancesOfClassesXamarin.iOS错误地定义为仅在tvOS 中可用,而事实并非如此。

#if TVOS
   // new in iOS9 but the only option for tvOS
   const string selAppearanceWhenContainedInInstancesOfClasses = "appearanceWhenContainedInInstancesOfClasses:";
   ~~~

UIAppearance.cs#L77

更新:我提交了一个关于此的 Github 问题。

https://github.com/xamarin/xamarin-macios/issues/3230

因此,它不能通过 Xamarin.iOS 包装 API 获得,但当然可以直接从 ObjC 运行时获得:

var NSForegroundColorAttributeName = Dlfcn.GetStringConstant(UIKitLibraryHandle, "NSForegroundColorAttributeName");
var defaultAttributes = NSDictionary.FromObjectsAndKeys(new NSObject[]  UIColor.Red , new NSObject[]  NSForegroundColorAttributeName );
var styleHandle = GetAppearanceEx(Class.GetHandle("UITextField"), typeof(UISearchBar));
void_objc_msgSend_IntPtr(styleHandle, Selector.GetHandle("setDefaultTextAttributes:"), defaultAttributes.Handle);

下一个问题是上面的代码需要许多标记为 internal 的 Xamarin.iOS 方法才能运行,因此需要对某些源进行一些复制/粘贴/修改:

public const string selAppearanceWhenContainedInInstancesOfClasses = "appearanceWhenContainedInInstancesOfClasses:";

public static readonly IntPtr UIKitLibraryHandle = Dlfcn.dlopen("/System/Library/Frameworks/UIKit.framework/UIKit", 0);

[DllImport("/usr/lib/libobjc.dylib", EntryPoint = "objc_msgSend")]
public static extern IntPtr IntPtr_objc_msgSend_IntPtr(IntPtr receiver, IntPtr selector, IntPtr arg1);

[DllImport("/usr/lib/libobjc.dylib", EntryPoint = "objc_msgSend")]
public static extern void void_objc_msgSend_IntPtr(IntPtr receiver, IntPtr selector, IntPtr arg1);

public static IntPtr GetAppearanceEx(IntPtr class_ptr, params Type[] whenFoundIn)

    var ptrs = TypesToPointers(whenFoundIn);
    var handles = NSArray.FromIntPtrs(ptrs);
    using (var array = handles)
    
        return IntPtr_objc_msgSend_IntPtr(class_ptr, Selector.GetHandle(selAppearanceWhenContainedInInstancesOfClasses), array.Handle);
    


public static IntPtr[] TypesToPointers(Type[] whenFoundIn)

    IntPtr[] ptrs = new IntPtr[whenFoundIn.Length];

    for (int i = 0; i < whenFoundIn.Length; i++)
    
        if (whenFoundIn[i] == null)
            throw new ArgumentException(String.Format("Parameter 0 was null, must specify a valid type", i));
        if (!typeof(NSObject).IsAssignableFrom(whenFoundIn[i]))
            throw new ArgumentException(String.Format("Type 0 does not derive from NSObject", whenFoundIn[i]));

        var classHandle = Class.GetHandle(whenFoundIn[i]);
        if (classHandle == IntPtr.Zero)
            throw new ArgumentException(string.Format("Could not find the Objective-C class for 0", whenFoundIn[i].FullName));
        ptrs[i] = classHandle;
    
    return ptrs;

【讨论】:

@TunykPavel 没问题,很高兴它有帮助 ? 哇,我正在研究这个,但没有找到接近的地方,干得好寿司! ? @IainSmith LOL...谢谢,前段时间我为一个客户写了一个完整的 UIAppearance.cs 替代品,而不是顶部有一个 CSS 模板层,所以我有别人付钱给我的优势学习技巧;-) 抱歉我迟到的问题,但我如何使用此代码更改 UIAlertController 中的 UILabel NumberOfLInes?我需要一个两行操作表选项... @GrupoCDSInformática 您应该问一个新问题,说明您要实现的目标以及到目前为止的代码。

以上是关于Xamarin.iOS UIApperance setDefaultTextAttributes的主要内容,如果未能解决你的问题,请参考以下文章

Xamarin 表单中是不是有相当于 iOS 的动态系统颜色?

Xamarin iOS DocumentPicker:如何导入大文件?

Xamarin.iOS unrecognized selector sent to class

迫切需要 Xamarin.IOS 模态 MessageBox 之类的弹出窗口

在 Xamarin iOS 中的远程通知的“默认用户操作”上推送视图控制器

如何让 UIView / Menu 滑入和滑出? (使用 C# 而不是 Swift 的 Xamarin IOS)