iOS позволяет вам создавать собственные элементы управления, которые можно использовать в ваших приложениях вместе с теми, что предоставляются Apple. До Xcode 6 вы не могли просматривать пользовательские элементы управления в Интерфейсном Разработчике, вам нужно было запустить приложение, чтобы увидеть, что вы создали. Это может расстраивать, когда вам придется постоянно запускать приложение для проверки результатов внесенных вами изменений, поскольку запуск приложения на симуляторе или устройстве может занять некоторое время.
Xcode 6 улучшает этот процесс, так что теперь вы можете предварительно просмотреть свои пользовательские элементы управления в Интерфейсном Разработчике и видеть ваши изменения в реальном времени по мере их внесения. Это ускоряет разработку, так как вы можете быстро увидеть результаты того, что вы кодируете. Xcode 6 идет дальше, позволяя вам отлаживать элементы управления без предварительного запуска приложения.
Преимущество встроенных элементов управления в том, что их можно настраивать с помощью Interface Builder. Вы можете легко изменять свойства элемента управления в Инспекторе атрибутов. Чтобы изменить свойства пользовательского элемента управления, ранее вы могли делать это только в коде. Это улучшилось, поскольку теперь вы можете открывать свойства вашего элемента управления в Интерфейсном Разработчике и редактировать их из Инспектора атрибутов, как если бы вы использовали встроенный элемент управления. Эта функция отлично подходит для создания многоразовых элементов управления. Вы можете создать элемент управления, который можно использовать в различных приложениях, который настраивается в Interface Builder, как встроенные элементы управления. Возможность настраивать пользовательские элементы управления таким образом облегчает совместную работу разработчиков и дизайнеров. Разработчик может создать элемент управления и оставить его на усмотрение дизайнера, чтобы стилизовать его и настроить его под свои нужды без написания кода.
В этом уроке мы рассмотрим, как создать пользовательский элемент управления, включить рендеринг в реальном времени и показать его свойства в Интерфейсном Разработчике.
Чтобы следовать руководству, загрузите стартовый проект, который мы будем использовать вместо того, чтобы начинать с нуля. Проект представляет собой простое приложение для гипотетической социальной сети, где пользователь может просматривать профили пользователей. При выборе профиля вы попадете в представление, в котором отображаются данные пользователя, в том числе имя, биография, рейтинг профиля и фотография. Если вы запустите приложение, вы заметите, что изображение пользователя не было включено в представление профиля. Вместо этого есть пустой вид, где мы планируем иметь изображение. (Изображения, используемые в приложении, загружаются с uifaces )
Вместо того, чтобы использовать ImageView
от Apple, мы хотим создать наш собственный пользовательский вид, который будет стилизован по-другому и будет настраиваться через Interface Builder. (Я буду использовать «пользовательский вид» и «пользовательский контроль» взаимозаменяемо).
Для начала создайте новый класс в стартовом проекте, открыв Файл -> Создать -> Файл -> iOS -> Источник -> Какао Touch Class . Назовите его CircularImageView
, сделайте его подклассом UIView
и установите для языка значение Swift.
Откройте файл раскадровки и выберите представление, которое находится над данными пользователя.
Установите его класс в CircularImageView
в инспекторе идентичности.
В файле CircularImageView.swift
добавьте @IBDesignable
перед объявлением класса. Это отмечает класс как проектируемый. Вы должны сделать это для живого рендеринга, который будет включен для класса. Объявление класса должно выглядеть так:
@IBDesignable class CircularImageView: UIView { }
Вернитесь к файлу раскадровки, выберите представление (я буду предполагать, что представление теперь выбрано) и откройте Identity Inspector. Вы заметите, что индикатор статуса Designables появился в разделе Custom Class.
Up to date
статус означает, что пользовательский вид компилируется и отображается правильно. Если во время рендеринга произойдет ошибка, будет отображаться состояние « Build failed
с кнопкой « Показать» рядом с ней. При нажатии на кнопку Xcode откроет сеанс отладки и покажет вам проблему, которая вызвала сбой.
Откройте CircularImageView.swift
и добавьте следующее к классу.
var backgroundLayer: CAShapeLayer! @IBInspectable var backgroundLayerColor: UIColor = UIColor.grayColor() @IBInspectable var lineWidth: CGFloat = 1.0
Применение атрибута @IBInspectable
к свойству открывает его в инспекторе атрибутов. Вернитесь в файл раскадровки, и вы увидите два атрибута.
Я рекомендую использовать помощник редактора для разделения просмотра файлов CircularImageView.swift
и Main.storyboard
вместо переключения между файлами для просмотра изменений.
Типы свойств, которые можно пометить с помощью @IBInspectable
: Int
, CGFloat
, Double
, String
, Bool
, CGRect
, CGSize
, CGPoint
, UIImage
и UIColor
.
Добавьте следующее к классу:
override func layoutSubviews() { super.layoutSubviews() setBackgroundLayer() } func setBackgroundLayer() { if backgroundLayer == nil { backgroundLayer = CAShapeLayer() layer.addSublayer(backgroundLayer) let rect = CGRectInset(bounds, lineWidth / 2.0, lineWidth / 2.0) let path = UIBezierPath(ovalInRect: rect) backgroundLayer.path = path.CGPath backgroundLayer.lineWidth = lineWidth backgroundLayer.fillColor = backgroundLayerColor.CGColor } backgroundLayer.frame = layer.bounds }
Здесь мы проверяем, был ли создан backgroundLayer
. Если нет, мы создаем объект CAShapeLayer
и добавляем его в подуровень представления. Затем мы создаем круговой UIBezierPath
и применяем его к пути backgroundLayer
. Затем мы устанавливаем backgroundLayer
lineWidth и fillColor .
Если вы посмотрите на Interface Builder, вы увидите серый объект. Это будет фон нашего изображения.
Цвет по умолчанию для backgroundLayer
был установлен на серый в коде. Вы можете проверить проверяемые атрибуты, которые вы установили ранее, изменив Цвет фона или Ширина линии в Инспекторе Атрибутов. После изменения раскадровка будет обновлена немедленно.
Добавьте следующее к классу:
var imageLayer: CALayer! @IBInspectable var image: UIImage? func setBackgroundImageLayer() { if imageLayer == nil { let mask = CAShapeLayer() let dx = lineWidth + 3.0 let path = UIBezierPath(ovalInRect: CGRectInset(self.bounds, dx, dx)) mask.fillColor = UIColor.blackColor().CGColor mask.path = path.CGPath mask.frame = self.bounds layer.addSublayer(mask) imageLayer = CAShapeLayer() imageLayer.frame = self.bounds imageLayer.mask = mask imageLayer.contentsGravity = kCAGravityResizeAspectFill layer.addSublayer(imageLayer) } } func setImage() { if let pic = image { imageLayer.contents = pic.CGImage } }
Здесь мы сначала проверяем, не был ли imageLayer создан. Если этого не произошло, мы создаем круговой путь и устанавливаем его как маску imageLayer. Маскировка слоя делает этот слой прозрачным там, где маска прозрачна.
Измените layoutSubViews()
следующим образом, чтобы были вызваны два новых метода.
override func layoutSubviews() { super.layoutSubviews() setBackgroundLayer() setBackgroundImageLayer() setImage() }
Вернувшись в файл раскадровки, проверьте инспектор атрибутов, и вы увидите, что еще один атрибут для изображения был добавлен в атрибуты кругового изображения. Выберите изображение из выпадающего меню, и вы увидите изменения в раскадровке.
Наш контроль завершен. Единственная проблема в том, что если вы запустите приложение, вы получите одно и то же изображение для всех пользователей. Нам не нужно статичное изображение для профилей пользователей. Мы хотим, чтобы он обновлялся для каждого пользователя.
Добавьте следующее к классу.
var userImage: UIImage?
Затем откройте ViewController.swift
и создайте выход для нашего пользовательского представления. Назовите его circularImageView
. Вы должны иметь следующее в коде.
@IBOutlet weak var circularImageView: CircularImageView!
В том же файле добавьте это в viewDidLoad()
блока if
в viewDidLoad()
, сразу после строки, которая устанавливает userBio.text
circularImageView.userImage = user.avatar
В CircularImageView.swift
измените метод setImage()
как показано.
func setImage() { if imageLayer != nil { if let userPic = userImage { imageLayer.contents = userPic.CGImage } else { if let pic = image { imageLayer.contents = pic.CGImage } } } }
Это проверяет, является ли userImage
не userImage
nil, и если это не так, изображение представления устанавливается на это, в противном случае оно будет установлено на изображение, выбранное в Interface Builder.
В Интерфейсном Разработчике визуализированное изображение будет тем, которое вы установили в Инспекторе Атрибутов, но если вы запустите приложение, каждый профиль покажет свое соответствующее изображение.
Стоит отметить
Ваш пользовательский элемент управления может отображать данные, которые могут быть доступны только во время выполнения, и поэтому XCode не сможет показать вам предварительный просмотр элемента управления с данными. Чтобы обойти это, вы можете переопределить prepareForInterfaceBuilder()
в вашем коде и поместить фиктивные данные в функцию. Метод вызывается только во время разработки и не влияет на приложение во время выполнения.
Как упоминалось ранее, вы можете отлаживать свой пользовательский элемент управления без запуска приложения. Для этого установите точку останова в нужном вам классе управления. Выберите представление в файле раскадровки и выберите « Редактор» -> «Отладка выбранных представлений» . Представление отладки будет отображаться так же, как и при отладке работающего приложения, и вы сможете отлаживать пользовательский элемент управления как обычно.
Вывод
Мы рассмотрели, как создать собственный элемент управления и настроить Интерфейсный Разработчик так, чтобы элемент управления мог отображаться, как только мы напишем код. Эта функция значительно улучшает рабочий процесс создания пользовательских элементов управления, поскольку теперь вы можете работать быстрее и узнавать об ошибках по мере их возникновения.
Помимо рендеринга элемента управления в Интерфейсном Разработчике, мы также видели, как создать настраиваемый элемент управления. На рисунке ниже показаны некоторые варианты элемента управления, которые мы можем получить, просто настроив его в Интерфейсном Разработчике. Это очень помогает в создании многоразовых элементов управления. Мы можем взять CircularImageView
и использовать его в любом приложении, где нам нужно отобразить изображение, а затем оформить его в соответствии с требованиями этого приложения без изменения кода.
Вы можете скачать готовый проект здесь .