UIAppearance appearanceWhenContainedInInstancesOfClasses incorrectly restricted to tvOS
- Dominant language
- C#
- Stars
- 2.9k
- Forks
- 576
- Avg merge
- 2d 13h
- Merged PRs (30d)
- 96
Description
Note: This is a C/P from my StackOverflow answer, so if you need additional info, just ask, thanks.
* https://stackoverflow.com/questions/48262588/xamarin-ios-uiapperance-setdefaulttextattributes
There are a *number* of missing `UIAppearance` features in Xamarin.iOS and in regards to your question, there is a *missing* API.
* This is a bug, 🍣 I wrote my own `UIAppearance.cs` to add the missing features and correct the missing API and *assume* no other Xamarin.iOS coders really use the newer `UIAppearance` features as it has been broken since iOS 9 in Xamarin.
First, `appearanceWhenContainedIn` is deprecated and you should be using `appearanceWhenContainedInInstancesOfClasses` instead.
>AppearanceWhenContainedIn - was deprecated in iOS 9 and is not recommended for use.
Second, `appearanceWhenContainedInInstancesOfClasses` is **incorrectly** defined within `Xamarin.iOS` as ***only available in `tvOS`*** via a `#if TVOS` and that is just not true.
Re: Apple Docs: https://developer.apple.com/documentation/uikit/uiappearance/1615013-appearancewhencontainedininstanc
#if TVOS
// new in iOS9 but the only option for tvOS
const string selAppearanceWhenContainedInInstancesOfClasses = "appearanceWhenContainedInInstancesOfClasses:";
~~~
[UIAppearance.cs#L77][1]
Thus it is not available via the iOS wrapper API, but of course is available directly from the ObjC runtime as such:
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);
var searchBar = new UISearchBar(new CGRect(0, 50, 300, 40));
searchBar.Placeholder = "Xamarin.iOS";
Add(searchBar);
[![enter image description here][2]][2]
The next problem there are a number of Xamarin.iOS methods marked **internal** that are needed for the above code to function, so some copy/paste/modify of some source is needed:
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;
}
### Xamarin.iOS Version: 11.8.0.1
[1]: https://github.com/xamarin/xamarin-macios/blob/fc55e4306f79491fd269ca2495c6a859799cb1c6/src/UIKit/UIAppearance.cs#L77
[2]: https://i.stack.imgur.com/xYMJD.png
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.