Xamarin.forms: iOS13: Xamarin.Forms SearchBar BackgroundColor not behaving properly

Created on 16 Oct 2019  ·  31Comments  ·  Source: xamarin/Xamarin.Forms

Description

Since iOS13 update, setting the BackgroundColor property of the Xamarin.Forms SearchBar sets both the search bar border and the text-field fill to the same color. I want these two aspects to be different colors for contrast reasons.

Steps to Reproduce

<SearchBar BackgroundColor="Gray"></SearchBar>

Expected Behavior

Outer box to search bar is gray, inner text field is white
Screen Shot 2019-10-16 at 9 38 46 AM

Actual Behavior

Both outer box to search bar and text field are both gray
Screen Shot 2019-10-16 at 9 44 11 AM

Basic Information

  • Version with issue: iOS13, Visual Studio 8.3.4, XCode 11
  • Last known good version: Before iOS13
  • IDE: Visual Studio
searchbar iOS 13 iOS 🍎 platform-specifics enhancement ➕

Most helpful comment

I am experiencing this same issue. I used an Effect to modify the SearchBar to have a white background in the meantime (stuck it in a border effect that I had created temporarily).

UISearchBar.SearchTextField.BackgroundColor = UIColor.White;

All 31 comments

I've noticed this (or something similar) recently when testing the gallery app on iOS13.

I am experiencing this same issue. I used an Effect to modify the SearchBar to have a white background in the meantime (stuck it in a border effect that I had created temporarily).

UISearchBar.SearchTextField.BackgroundColor = UIColor.White;

I can confirm that when I put BackgroundColor=White or BackgroundColor=#FFFFFF, the expected behavior as describe by @baileysnead occur. Perphaps, SearchTextField.BackgroundColor should be exposed as a iOS Platform-specific property. I would like to give a try on doing that if that change is accepted.

Sorry for the wall of text.

Also experiencing the same issue described by @baileysnead.

Also tried a custom renderer and having no luck there either.

using System.ComponentModel;
using Foundation;
using App.iOS.Renderers;
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;

[assembly: ExportRenderer(typeof(SearchBar), typeof(CustomSearchBarRenderer))]

namespace App.iOS.Renderers
{
    public class CustomSearchBarRenderer : SearchBarRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<SearchBar> e)
        {
            base.OnElementChanged(e);

            //!!! Works, but only for the first search bar (we have 3) **
            UITextField.AppearanceWhenContainedIn(typeof(UISearchBar)).BackgroundColor =
            UIColor.FromRGB(255, 0, 0);

            //Match text field within SearchBar to its background color
            using (var searchKey = new NSString("_searchField"))
            {
                if (e.NewElement == null) return;

                //!!! Throws an iOS error on iOS 13 ***
                var textField = (UITextField)Control.ValueForKey(searchKey);
                textField.BackgroundColor = e.NewElement.BackgroundColor.ToUIColor();
                textField.TintColor = UIColor.White;
            }
        }

        protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            base.OnElementPropertyChanged(sender, e);

            // Hide Cancel Button
            if (e.PropertyName == "Text") Control.ShowsCancelButton = false;
        }
    }
}

* This line works but only for the first searchbar. We have 3 search bars (on different tabs...not sure if that is a cause) and only the first search bar utilizes this code
*
* This throws the below error when debugging on iOS 13+

Foundation.MonoTouchException: at at (wrapper managed-to-native) ObjCRuntime.Messaging.xamarin_IntPtr_objc_msgSend_IntPtr(intptr,intptr,intptr) at Foundation.NSObject.ValueForKey (Foundation.NSString key) [0x0001c] in /Library/Frameworks/Xamarin.iOS.framework/Versions/13.2.0.47/src/Xamarin.iOS/NSObject.g.cs:602 at App.iOS.Renderers.CustomSearchBarRenderer.OnElementChanged (Xamarin.Forms.Platform.iOS.ElementChangedEventArgs`1[TElement] e) [0x00024] in /Users/user-name/Documents/App/iOS/Renderers/CustomSearchBarRenderer.cs:22 at Xamarin.Forms.Platform.iOS.VisualElementRenderer`1[TElement].SetElement (TElement element) [0x0012a] in <fc33cd67c9774c61ba6dca5e7bdd7329>:0 at Xamarin.Forms.Platform.iOS.VisualElementRenderer`1[TElement].Xamarin.Forms.Platform.iOS.IVisualElementRenderer.SetElement (Xamarin.Forms.VisualElement element) [0x00000] in <fc33cd67c9774c61ba6dca5e7bdd7329>:0 at Xamarin.Forms.Platform.iOS.Platform.CreateRenderer (Xamarin.Forms.VisualElement element) [0x00014] in <fc33cd67c9774c61ba6dca5e7bdd7329>:0 at Xamarin.Forms.Platform.iOS.VisualElementPackager.OnChildAdded (Xamarin.Forms.VisualElement view) [0x0003d] in <fc33cd67c9774c61ba6dca5e7bdd7329>:0 at Xamarin.Forms.Platform.iOS.VisualElementPackager.Load () [0x0001e] in <fc33cd67c9774c61ba6dca5e7bdd7329>:0 at Xamarin.Forms.Platform.iOS.VisualElementRenderer`1[TElement].SetElement (TElement element) [0x000de] in <fc33cd67c9774c61ba6dca5e7bdd7329>:0 at Xamarin.Forms.Platform.iOS.VisualElementRenderer`1[TElement].Xamarin.Forms.Platform.iOS.IVisualElementRenderer.SetElement (Xamarin.Forms.VisualElement element) [0x00000] in <fc33cd67c9774c61ba6dca5e7bdd7329>:0 at Xamarin.Forms.Platform.iOS.Platform.CreateRenderer (Xamarin.Forms.VisualElement element) [0x00014] in <fc33cd67c9774c61ba6dca5e7bdd7329>:0 at Xamarin.Forms.Platform.iOS.VisualElementPackager.OnChildAdded (Xamarin.Forms.VisualElement view) [0x0003d] in <fc33cd67c9774c61ba6dca5e7bdd7329>:0 at Xamarin.Forms.Platform.iOS.VisualElementPackager.Load () [0x0001e] in <fc33cd67c9774c61ba6dca5e7bdd7329>:0 at Xamarin.Forms.Platform.iOS.VisualElementRenderer`1[TElement].SetElement (TElement element) [0x000de] in <fc33cd67c9774c61ba6dca5e7bdd7329>:0 at Xamarin.Forms.Platform.iOS.VisualElementRenderer`1[TElement].Xamarin.Forms.Platform.iOS.IVisualElementRenderer.SetElement (Xamarin.Forms.VisualElement element) [0x00000] in <fc33cd67c9774c61ba6dca5e7bdd7329>:0 at Xamarin.Forms.Platform.iOS.Platform.CreateRenderer (Xamarin.Forms.VisualElement element) [0x00014] in <fc33cd67c9774c61ba6dca5e7bdd7329>:0 at Xamarin.Forms.Platform.iOS.VisualElementPackager.OnChildAdded (Xamarin.Forms.VisualElement view) [0x0003d] in <fc33cd67c9774c61ba6dca5e7bdd7329>:0 at Xamarin.Forms.Platform.iOS.VisualElementPackager.Load () [0x0001e] in <fc33cd67c9774c61ba6dca5e7bdd7329>:0 at Xamarin.Forms.Platform.iOS.VisualElementRenderer`1[TElement].SetElement (TElement element) [0x000de] in <fc33cd67c9774c61ba6dca5e7bdd7329>:0 at Xamarin.Forms.Platform.iOS.VisualElementRenderer`1[TElement].Xamarin.Forms.Platform.iOS.IVisualElementRenderer.SetElement (Xamarin.Forms.VisualElement element) [0x00000] in <fc33cd67c9774c61ba6dca5e7bdd7329>:0 at Xamarin.Forms.Platform.iOS.Platform.CreateRenderer (Xamarin.Forms.VisualElement element) [0x00014] in <fc33cd67c9774c61ba6dca5e7bdd7329>:0 at Xamarin.Forms.Platform.iOS.VisualElementPackager.OnChildAdded (Xamarin.Forms.VisualElement view) [0x0003d] in <fc33cd67c9774c61ba6dca5e7bdd7329>:0 at Xamarin.Forms.Platform.iOS.VisualElementPackager.Load () [0x0001e] in <fc33cd67c9774c61ba6dca5e7bdd7329>:0 at Xamarin.Forms.Platform.iOS.VisualElementRenderer`1[TElement].SetElement (TElement element) [0x000de] in <fc33cd67c9774c61ba6dca5e7bdd7329>:0 at Xamarin.Forms.Platform.iOS.VisualElementRenderer`1[TElement].Xamarin.Forms.Platform.iOS.IVisualElementRenderer.SetElement (Xamarin.Forms.VisualElement element) [0x00000] in <fc33cd67c9774c61ba6dca5e7bdd7329>:0 at Xamarin.Forms.Platform.iOS.Platform.CreateRenderer (Xamarin.Forms.VisualElement element) [0x00014] in <fc33cd67c9774c61ba6dca5e7bdd7329>:0 at Xamarin.Forms.Platform.iOS.VisualElementPackager.OnChildAdded (Xamarin.Forms.VisualElement view) [0x0003d] in <fc33cd67c9774c61ba6dca5e7bdd7329>:0 at Xamarin.Forms.Platform.iOS.VisualElementPackager.Load () [0x0001e] in <fc33cd67c9774c61ba6dca5e7bdd7329>:0 at Xamarin.Forms.Platform.iOS.VisualElementRenderer`1[TElement].SetElement (TElement element) [0x000de] in <fc33cd67c9774c61ba6dca5e7bdd7329>:0 at Xamarin.Forms.Platform.iOS.VisualElementRenderer`1[TElement].Xamarin.Forms.Platform.iOS.IVisualElementRenderer.SetElement (Xamarin.Forms.VisualElement element) [0x00000] in <fc33cd67c9774c61ba6dca5e7bdd7329>:0 at Xamarin.Forms.Platform.iOS.Platform.CreateRenderer (Xamarin.Forms.VisualElement element) [0x00014] in <fc33cd67c9774c61ba6dca5e7bdd7329>:0 at Xamarin.Forms.Platform.iOS.VisualElementPackager.OnChildAdded (Xamarin.Forms.VisualElement view) [0x0003d] in <fc33cd67c9774c61ba6dca5e7bdd7329>:0 at Xamarin.Forms.Platform.iOS.VisualElementPackager.OnChildAdded (System.Object sender, Xamarin.Forms.ElementEventArgs e) [0x0000f] in <fc33cd67c9774c61ba6dca5e7bdd7329>:0 at Xamarin.Forms.Element.OnChildAdded (Xamarin.Forms.Element child) [0x0000f] in D:\a\1\s\Xamarin.Forms.Core\Element.cs:312 at Xamarin.Forms.VisualElement.OnChildAdded (Xamarin.Forms.Element child) [0x00000] in D:\a\1\s\Xamarin.Forms.Core\VisualElement.cs:755 at Xamarin.Forms.Layout.OnInternalAdded (Xamarin.Forms.View view) [0x0001d] in D:\a\1\s\Xamarin.Forms.Core\Layout.cs:453 at Xamarin.Forms.Layout.InternalChildrenOnCollectionChanged (System.Object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) [0x00078] in D:\a\1\s\Xamarin.Forms.Core\Layout.cs:443 at System.Collections.ObjectModel.ObservableCollection`1[T].OnCollectionChanged (System.Collections.Specialized.NotifyCollectionChangedEventArgs e) [0x00018] in /Users/builder/jenkins/workspace/xamarin-macios/xamarin-macios/external/mono/external/corefx/src/System.ObjectModel/src/System/Collections/ObjectModel/ObservableCollection.cs:263 at System.Collections.ObjectModel.ObservableCollection`1[T].OnCollectionChanged (System.Collections.Specialized.NotifyCollectionChangedAction action, System.Object item, System.Int32 index) [0x00000] in /Users/builder/jenkins/workspace/xamarin-macios/xamarin-macios/external/mono/external/corefx/src/System.ObjectModel/src/System/Collections/ObjectModel/ObservableCollection.cs:338 at System.Collections.ObjectModel.ObservableCollection`1[T].InsertItem (System.Int32 index, T item) [0x0001a] in /Users/builder/jenkins/workspace/xamarin-macios/xamarin-macios/external/mono/external/corefx/src/System.ObjectModel/src/System/Collections/ObjectModel/ObservableCollection.cs:196 at System.Collections.ObjectModel.Collection`1[T].Add (T item) [0x00020] in /Users/builder/jenkins/workspace/xamarin-macios/xamarin-macios/external/mono/external/corefx/src/Common/src/CoreLib/System/Collections/ObjectModel/Collection.cs:71 at Xamarin.Forms.ContentPresenter.OnContentChanged (Xamarin.Forms.BindableObject bindable, System.Object oldValue, System.Object newValue) [0x0004e] in D:\a\1\s\Xamarin.Forms.Core\ContentPresenter.cs:88 at System.Runtime.CompilerServices.AsyncMethodBuilderCore+<>c.<ThrowAsync>b__7_0 (System.Object state) [0x00000] in /Users/builder/jenkins/workspace/xamarin-macios/xamarin-macios/external/mono/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/AsyncMethodBuilder.cs:1021 at Foundation.NSAsyncSynchronizationContextDispatcher.Apply () [0x00000] in /Library/Frameworks/Xamarin.iOS.framework/Versions/13.2.0.47/src/Xamarin.iOS/Foundation/NSAction.cs:178

The solution we found, for now, is to only run the code textField.BackgroundColor code (*) when the iOS version is less than 13. This ensures the search bar looks okay for iOS 13+ and anything lower. Not ideal but it works

Looking into the @renzska response and the one in the stackoverflow, I was able to use the effect and it worked fine. The following code is from the link above:
```
public class SearchBarBackgroundEffect : PlatformEffect
{
public SearchBarBackgroundEffect()
{
}

    private UIKit.UISearchBar NativeSearchBar => (UIKit.UISearchBar)Control;
    private SearchBar XamarinSearchBar => (SearchBar)Element;

    protected override void OnAttached()
    {
        if (UIKit.UIDevice.CurrentDevice.CheckSystemVersion(13, 0))
            NativeSearchBar.SearchTextField.BackgroundColor = XamarinSearchBar.BackgroundColor.ToUIColor();
    }
    protected override void OnDetached()
    {

    }
}

In my case, I want the SearchTextField color to stay the same as the background, but you can modify this get the color you want.

@MathewLC interesting, the stack overflow solution you linked does not work for me. I tried it. The background color is still white

@attrib75 I'm without a mac access right now but when I have I'll definitely do a test project and share with you. For now, if you can share a project test that is not working maybe I can help you more fast.

@MathewLC interesting, the stack overflow solution you linked does not work for me. I tried it. The background color is still white

HI @MathewLC, thanks for the help. I'll try to throw something together

@justinhorner After seeing your post I thought I might give it a try:
UITextField.AppearanceWhenContainedIn(typeof(UISearchBar)).BackgroundColor =
UIColor.FromRGB(255, 0, 0);

It worked for me as well, but it only seems to change the first instance of a search bar it encounters in the app. Very strange behavior.

@MathewLC I created a repo of the problem here
https://github.com/attrib75/XamIoSSearchBarColorBug
thanks!

@justinhorner I downloaded your repo and made the test placing the searchBar on all pages. It worked for me. The only thing that is happen is that for some reason I'm changing the xaml and is not refleteced on iOS build and to get done I had to clean, close visual studio and open again. Also I think I found a bug or I doing something wrong but removing the "x:Name" property of the search Bar in first page, cause app to crash.
Ignoring all that, using just the Background Color and and removing the name(x:Name property) of the search Bar on another pages, works fine. If you still having trouble on that, you can update your repo with the version that only gets done in the first instance of searchBar. For now, maybe later today I'll make my repo and share with you.

@MathewLC I created a repo of the problem here
https://github.com/attrib75/XamIoSSearchBarColorBug
thanks!

@MathewLC
Hello, the sample works for you as is? I don't understand. The searchbar background is white on iOS 13 with the sample I uploaded.

@attrib75 Yeah, your sample worked for me, the only thing I did was remove placeholder color as the background color is applied to both background and placeholder background.

@MathewLC
Hello, the sample works for you as is? I don't understand. The searchbar background is white on iOS 13 with the sample I uploaded.

This is what it seems like:
image
image
image

This is in simulator anyway, I can't tell if something change in device or how much difference is your environment from mine.

@MathewLC I have the iPhone 11 Pro Max 13.0 and it is white.

I can't try in a device right now but as soon as I can and the bug appears I'll try a solution, if you find first thought, let me know, please.

@MathewLC I have the iPhone 11 Pro Max 13.0 and it is white.

What is your version of VS and Xamarin? Maybe this has been addressed and that's why it works in your environment. Mine is:
VS 16.3.2
Xamarin iOS 13.2.0.42

Sorry I meant earlier I have the iPhone 11 Pro Max 13.0 _simulator_ whereas yours is 13.1

My VS version is 16.3.7 and Xamarin iOS 13.4.0.2.

What is your version of VS and Xamarin? Maybe this has been addressed and that's why it works in your environment. Mine is:
VS 16.3.2
Xamarin iOS 13.2.0.42

I think that it's it!!! Maybe just the iOS version or the environment all. Let me know if you got it done.

Sorry I meant earlier I have the iPhone 11 Pro Max 13.0 _simulator_ whereas yours is 13.1

Ok. Historically, upgrading Xamarin and iOS is REALLY wrought with problems. Here's goes nothing -(

Really bad :(
That's some additional informations of my enviroment:
Xamarin Forms: 4.3.0.908675 (the last one is 4.3.0.947036)
VS for Mac: 8.3.5 (build 13)
Xcode: Version 11.1 (11A1027)
Maybe it's something more that is different from our environments?

I upgraded with the same result. the only difference is I'm one version behind on xcode

attempting upgrade of xcode

Great news! It works after updating XCode, Xamarin and VS. For others with this issue in this thread, try it

@attrib75 after so much job you finally found out. Congratulations, I'm sure many others will enjoy find this issue. For now, I'm just waiting xamarin team approval to try minimize the work with some platform specific property.

Edited older comment. Somehow I've got it working now with the custom effect mentioned above in Stackoverflow. I had declared the [assembly: ResolutionGroupName("myapnamehere")] in the ios project and not the .Net Standard project. Thanks everyone for your help. This seems to be only a workaround until Xamarin can get the background color to work without an effect?

I'm not sure that is it.
image
But my version of xamarin,forms is not the last one, when you updated, do you update to the last one? Maybe that's it?

Ahh I see the problem, it depends on the simulator used

iPhone 11 - 13.1: Doesn't work
iPhone 11 Pro Max - 13.1 Works

I solved it now (see edited comment above) thanks!

I think the SearchBar needs some attention to make it work properly again on iOS 13.x. If you look carefully at the original image of this issue, you will notice that it is not only the color that is wrong, it also misses the Cancel button that used to be there in previous iOS versions.

So for my application on iOS 12:
image

And on iOS 13.2:
image

I think the iOS 12 version is better in terms of contrast and functionality.

@klogeaage I think that if the right properties can be exposed, we can use them as we need to, and adjust the appearance according the the application needs.

Agreed, but it would also be nice if the out-of-the-box behavior is sensible.

I have the same issue and nothing has been done to fix it... it makes my product look unprofessional. if a property is exposed why isn't it applied on the first time?
In these examples the correct properties are applied after navigating around the app...
I am using the shell and the latest versions of Xamarin and Xcode as of 3/4/2020

Before navigating
SearchBox01

After navigating
SearchBox02

Was this page helpful?
0 / 5 - 0 ratings