2

我正在尝试设置 Xamarin.Forms SearchBar 的样式,我可以看到有一个 BackgroundColor 属性,但是无论我设置什么,该属性在 iOS 中都会被忽略。

甚至可以在 iOS 中自定义 Xamarin.Forms SearchBar(以及如何)?

4

2 回答 2

8

不幸的是,我无法得到公认的答案。下面的代码确实适用于 iOS。请注意,OnElementChanged 而不是 Draw 似乎是在自定义渲染器中放置此类事物的首选位置。

using MonoTouch.UIKit;

using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;

[assembly:ExportRenderer( typeof(MyNamespace.MySearchBar), typeof(MyNamespace.iOS.MySearchBarRenderer_iOS))]


namespace MyNamespace.iOS
{
    public class MySearchBarRenderer_iOS : SearchBarRenderer
    {
        protected override void OnElementChanged( ElementChangedEventArgs<SearchBar> args )
        {
            base.OnElementChanged( args );

            UISearchBar bar = (UISearchBar)this.Control;

            bar.AutocapitalizationType = UITextAutocapitalizationType.None;
            bar.AutocorrectionType = UITextAutocorrectionType.No;
            bar.BarStyle = UIBarStyle.Default;
            bar.BarTintColor = UIColor.Green;
            bar.KeyboardType = UIKeyboardType.ASCIICapable;
        }
    }
}
于 2014-11-08T03:59:35.207 回答
4

据我所知,Xamarin.Forms 没有属性实现 BackgroundColor 属性,或者它已损坏。最接近真实背景颜色的 UISearchBar 属性是 BarTint,它不是由 XForms 设置的。

为了解决这个问题,我将评论放在心上,并使用自定义渲染器创建了自己的自定义 SearchBar,以扩展 BarTint 属性以及我想要的其他一些东西。

注意:为了使用自定义渲染器,请确保您已更新到 Xamarin.Forms 1.1.1.6206 或更高版本。若要更新平台版本,请使用 Visual Studio 中的 NuGet,或 XamarinStudio 中的内置包管理器。

您将需要两个类,第一个是 CustomSearchBar,UI 将使用它来保存自定义属性。它位于共享或可移植类库中。:

using Xamarin.Forms;

namespace App1
{
    public class CustomSearchBar : SearchBar
    {
        // Use Bindable properties to maintain XAML binding compatibility

        public static readonly BindableProperty BarTintProperty = BindableProperty.Create<CustomSearchBar, Color?>(p => p.BarTint, null);
        public Color? BarTint
        {
            get { return (Color?)GetValue(BarTintProperty); }
            set { SetValue(BarTintProperty, value); }
        }

        public static readonly BindableProperty SearchStyleProperty = BindableProperty.Create<CustomSearchBar, string>(p => p.SearchStyle, "Default");
        public string SearchStyle
        {
            get { return (string)GetValue(SearchStyleProperty); }
            set { SetValue(SearchStyleProperty, value); }
        }

        public static readonly BindableProperty BarStyleProperty = BindableProperty.Create<CustomSearchBar, string>(p => p.BarStyle, "Default");
        public string BarStyle
        {
            get { return (string)GetValue(BarStyleProperty); }
            set { SetValue(BarStyleProperty, value); }
        }

    }
}

第二个类是自定义渲染器本身,它可以访问本机 UISearchButton 控件。这个类进入 iOS 项目:

using System;
using System.Drawing;
using App1;
using App1.iOS;
using MonoTouch.UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;

[assembly: ExportRendererAttribute(typeof(CustomSearchBar), typeof(CustomSearchBarRenderer))]
namespace App1.iOS
{
    public class CustomSearchBarRenderer : SearchBarRenderer
    {
        // There might be a better place for this, but I don't know where it is
        public override void Draw(RectangleF rect)
        {
            var csb = (CustomSearchBar) Element;
            if (csb.BarTint != null)
                Control.BarTintColor = csb.BarTint.GetValueOrDefault().ToUIColor();
            Control.BarStyle = (UIBarStyle)Enum.Parse(typeof(UIBarStyle), csb.BarStyle);
            Control.SearchBarStyle = (UISearchBarStyle)Enum.Parse(typeof(UISearchBarStyle), csb.BarStyle);

            base.Draw(rect);
        }
    }
}

代码有点粗糙,但希望你能明白。

一些附加说明:

  • 如果没有 ExportRendererAttribute,这一切都不起作用,所以不要把它关掉。
  • 我必须使 BarTint 可以为空(因为它是默认值,而 Color.Default 是黑色的)。
  • 即使从技术上讲我没有绘制任何东西,我也会覆盖 Draw(),因为我不知道将代码放在哪里。Control 和 Element 属性在构造函数中不可用。如果我找到更好的解决方案,我将尝试更新此示例。
  • 我对 Enum 属性使用字符串,但将来可能会改进。
于 2014-06-26T22:42:31.403 回答