Пользовательские элементы управления в конструкторе Xamarin для iOS

Конструктор Xamarin для iOS поддерживает отрисовку пользовательских элементов управления, созданных в проекте или на которые ссылаются внешние источники, такие как хранилище компонентов Xamarin.

Предупреждение

Поддержка конструктора iOS была прекращена в Visual Studio 2019 версии 16.8 и Visual Studio 2019 для Mac версии 8.8. В Visual Studio 2019 версии 16.9 и Visual Studio для Mac версии 8.9 этот конструктор удален. Рекомендуемый способ создания пользовательских интерфейсов iOS находится непосредственно на компьютере Mac под управлением Xcode. Дополнительные сведения см. в статье Проектирование пользовательских интерфейсов с помощью Xcode.

Конструктор Xamarin для iOS — это мощный инструмент для визуализации пользовательского интерфейса приложения и обеспечивает поддержку редактирования WYSIWYG для большинства представлений и контроллеров представлений iOS. Приложение также может содержать пользовательские элементы управления, расширяющие встроенные в iOS. Если эти пользовательские элементы управления написаны с учетом нескольких рекомендаций, они также могут быть отрисованы конструктором iOS, предоставляя еще более широкий интерфейс редактирования. В этом документе посмотрим на эти рекомендации.

Требования

Элемент управления, соответствующий всем следующим требованиям, будет отображаться на поверхности конструктора:

  1. Это прямой или косвенный подкласс UIView или UIViewController. Другие подклассы NSObject будут отображаться как значок на поверхности конструктора.
  2. Он имеет RegisterAttribute , чтобы предоставить его Objective-C.
  3. У него есть обязательный конструктор IntPtr.
  4. Он либо реализует интерфейс IComponent, либо имеет значение DesignTimeVisibleAttribute с значением True.

Элементы управления, определенные в коде, которые соответствуют приведенным выше требованиям, будут отображаться в конструкторе при компиляции содержащего проекта для симулятора. По умолчанию все пользовательские элементы управления будут отображаться в разделе "Пользовательские компоненты" панели элементов. Однако класс CategoryAttribute можно применить к классу пользовательского элемента управления, чтобы указать другой раздел.

Конструктор не поддерживает загрузку сторонних Objective-C библиотек.

Пользовательские свойства

Свойство, объявленное пользовательским элементом управления, появится на панели свойств, если выполнены следующие условия:

  1. Свойство имеет общедоступный метод получения и задания.
  2. Свойство имеет значение ExportAttribute, а также в поле "ПросмотрableAttribute" значение True.
  3. Тип свойства — это числовый тип, тип перечисления, строка, bool, SizeF, UIColor или UIImage. Этот список поддерживаемых типов может быть расширен в будущем.

Свойство также можно декорировать с помощью DisplayNameAttribute , чтобы указать метку, отображаемую для нее на панели свойств.

Инициализация

Для UIViewController подклассов следует использовать метод ViewDidLoad для кода, который зависит от представлений, созданных в конструкторе.

Для UIView других NSObject подклассов метод AwakeFromNib рекомендуется выполнить инициализацию пользовательского элемента управления после загрузки из файла макета. Это связано с тем, что все настраиваемые свойства, заданные на панели свойств, не будут заданы при запуске конструктора элемента управления, но они будут заданы перед AwakeFromNib вызовом:

[Register ("CustomView"), DesignTimeVisible (true)]
public class CustomView : UIView {

    public CustomView (IntPtr handle) : base (handle) { }

    public override void AwakeFromNib ()
    {
        // Initialize the view here.
    }
}

Если элемент управления также предназначен для создания непосредственно из кода, может потребоваться создать метод, имеющий общий код инициализации, как показано ниже.

[Register ("CustomView"), DesignTimeVisible (true)]
public class CustomView : UIView {

    public CustomView (IntPtr handle) : base (handle) { }

    public CustomView ()
    {
        // Called when created from code.
        Initialize ();
    }

    public override void AwakeFromNib ()
    {
        // Called when loaded from xib or storyboard.
        Initialize ();
    }

    void Initialize ()
    {
        // Common initialization code here.
    }
}

Инициализация свойств и AwakeFromNib

Необходимо учитывать, когда и где инициализировать доступные для разработки свойства в пользовательском компоненте, чтобы не перезаписать значения, заданные внутри конструктора iOS. В качестве примера выполните следующий код:

[Register ("CustomView"), DesignTimeVisible (true)]
public class CustomView : UIView {

    [Export ("Counter"), Browsable (true)]
    public int Counter {get; set;}

    public CustomView (IntPtr handle) : base (handle) { }

    public CustomView ()
    {
        // Called when created from code.
        Initialize ();
    }

    public override void AwakeFromNib ()
    {
        // Called when loaded from xib or storyboard.
        Initialize ();
    }

    void Initialize ()
    {
        // Common initialization code here.
        Counter = 0;
    }
}

Компонент CustomView предоставляет Counter свойство, которое может быть задано разработчиком в конструкторе iOS. Однако независимо от того, какое значение задано внутри конструктора, значение Counter свойства всегда будет равно нулю (0). Для этого есть следующие причины.

  • Экземпляр раскадровки CustomControl файла раскадровки.
  • Все свойства, измененные в конструкторе iOS, задаются (например, задание значения Counter двух (2).
  • Метод AwakeFromNib выполняется и вызывается метод компонента Initialize .
  • Внутри Initialize значения Counter свойства сбрасывается до нуля (0).

Чтобы устранить указанную выше ситуацию, инициализируйте Counter свойство в другом месте (например, в конструкторе компонента) или не переопределите AwakeFromNib метод и не вызовите Initialize , если компонент не требует дальнейшей инициализации вне того, что в настоящее время обрабатывается его конструкторами.

Режим конструктора

В области конструктора пользовательский элемент управления должен соответствовать нескольким ограничениям:

  • Ресурсы пакета приложений недоступны в режиме разработки. Изображения доступны при загрузке с помощью методов UIImage.
  • Асинхронные операции, такие как веб-запросы, не должны выполняться в режиме разработки. Область конструктора не поддерживает анимацию или другие асинхронные обновления пользовательского интерфейса элемента управления.

Настраиваемый элемент управления может реализовать IComponent и использовать свойство DesignMode для проверка, если он находится на поверхности конструктора. В этом примере метка будет отображать "Режим конструктора" в рабочей области конструктора и "Среда выполнения" во время выполнения:

[Register ("DesignerAwareLabel")]
public class DesignerAwareLabel : UILabel, IComponent {

    #region IComponent implementation

    public ISite Site { get; set; }
    public event EventHandler Disposed;

    #endregion

    public DesignerAwareLabel (IntPtr handle) : base (handle) { }

    public override void AwakeFromNib ()
    {
        if (Site != null && Site.DesignMode)
            Text = "Design Mode";
        else
            Text = "Runtime";
    }
}

Прежде чем пытаться получить доступ к любому из его членов, необходимо всегда проверка Site свойствоnull. Если Site это nullтак, то можно предположить, что элемент управления не запущен в конструкторе. В режиме Site конструктора будет задано после запуска конструктора элемента управления и перед AwakeFromNib вызовом.

Отладка

Элемент управления, соответствующий приведенным выше требованиям, будет отображаться на панели элементов и отображаться на поверхности. Если элемент управления не отображается, проверка для ошибок в элементе управления или одной из его зависимостей.

Область конструктора часто может перехватывать исключения, создаваемые отдельными элементами управления, продолжая отображать другие элементы управления. Элемент управления сбоя заменяется красным заполнителем, и вы можете просмотреть трассировку исключений, щелкнув значок восклицания:

A faulty control as red placeholder and the exception details

Если для элемента управления доступны символы отладки, трассировка будет иметь имена файлов и номера строк. Дважды щелкнув строку в трассировке стека, она перейдет к этой строке в исходном коде.

Если конструктор не может изолировать неисправный элемент управления, в верхней части области конструктора появится предупреждение:

A warning message at the top of the design surface

Полная отрисовка возобновляется, когда неисправный элемент управления исправлен или удален из области конструктора.

Итоги

В этой статье представлено создание и применение пользовательских элементов управления в конструкторе iOS. Сначала он описал требования, которые элементы управления должны соответствовать отрисовке на поверхности конструктора и предоставлять настраиваемые свойства на панели свойств. Затем он посмотрел на код позади — инициализацию элемента управления и свойства DesignMode. Наконец, он описал, что происходит при возникновении исключений и как устранить это.