Простая общая задача!

Сложность: Начинающий | Легко | Нормальный | Испытывающий

Предпосылки:

Терминология

CALayer: базовый слой анимации, отвечающий за управление содержимым на основе изображений.

CAShapeLayer: слой, который рисует кубический сплайн Безье в своем координатном пространстве.

Мотивация

Возможно, вам понадобится создать изображение профиля для вашего приложения, и часто ваш дизайнер будет настаивать на том, чтобы у вас было красиво обрезанное изображение - к тому же круглое. Дело в том, что многие бэкенды (конечные пользователи) не выдают круглое изображение - скорее они дают фронтенду прямоугольник. Так как же закрепить эту штуку? ›

Эта статья призвана помочь вам, предлагая не менее 4 способов создания изображения профиля. Они представлены в приложении с помощью UIStackView, который можно прокручивать (так что его можно поворачивать),

Первые два изображения (как вы можете видеть) представляют собой простые изображения профиля. Вторые два изображения представляют собой круглое изображение с серым кружком вокруг изображения профиля.

Для этого руководства есть каталог активов с изображением под названием man (здесь есть одно изображение, а не разные разрешения, которые вы ожидаете в рабочем приложении - извините)

CALayer Фон

CALayers являются резервным хранилищем для любого UIView (для управления контентом), но фактически могут использоваться даже без представления (хотя в этом руководстве CALayer действительно будет использоваться с представлением).

UIView будет иметь корневой CALayer, но также будет иметь ноль или более дополнительных CALayers для различных функций (например, градиентов).

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

Настройка изображения профиля

Все эти демонстрационные изображения помещаются в контроллер представления под названием ProfileViewController.

Стандартный UIImageView

Standard ImageView

Самый простой способ реализовать изображение профиля - использовать UIImageView и добавить изображение через свойство изображения (конечно, выход должен быть установлен из раскадровки)

Это дает нам довольно простое квадратное изображение. Довольно скучно. Ваш дизайнер почувствует себя физически больным.

Круговой UIImageView

Мы можем создать класс CircularImageView, который устанавливает cornerRadius и ограничивает подпредставление границами представления через clipsToBounds. Чтобы это было легче увидеть в раскадровке, я использовал в реализации @IBDesignable.

затем его можно вызвать из ProfileViewController.

Это позволяет получить красивое круглое изображение.

Добавление границы

Было бы неплохо показать круглую рамку вокруг изображения профиля (не так ли?). В этом разделе статьи вы узнаете, как это сделать!

UIImageView в контейнере

Один из простых способов создать границу вокруг UIImageView - это вставить ее в контейнер UIView.

Xcode позволяет нам вставлять UIImage в UIView. Теперь ограничения для изображения дают небольшое отступление вокруг него.

Чтобы сделать границу круглой на этом контейнере, UIView реализовано через расширение.

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

Потрясающие! Но как мы можем предложить лучшее решение?

UIViewSubclass

Было бы неплохо иметь один UIView, содержащий UIImageView. Это правда, что этот код не это легкий . Он имеет инициализаторы как для раскадровки, так и для кода, вызывающего setupView (), который является общей функцией для инициализации UIView. Метод setupView() устанавливает ограничения и инициализирует CAShapeLayer shapelayer. После настройки UIKit вызывается func draw(_ rect: CGRect) среда рисования, во время которой мы drawRingFittingInsideSquareView().

drawRingFittingInsideSquareView() по сути рисует UIBezierPath и добавляет его к слою - что отлично работает, если мы не установили изображение через свойство изображения. Когда изображение установлено, setupView () вызывается снова, чтобы установить ограничения для UIImageView.

layoutSubViews() устанавливает угловой радиус контейнера и заставляет подвиды обрезать границы. Мы удаляем любой существующий shapeLayer (содержащий кольцо), а затем инструктируем swift вернуть кольцо с помощью drawRingFittingInsideSquareView(), это позволяет нам снова добавить UIImageView и сделать этот круг.

Уф! К счастью, код довольно легко читать:

Конечно, для создания этого представления требуется расширение.

Почему не просто подкласс UIImageView?

UIImageView не вызывает func draw(_ rect: CGRect), потому что он должен рисовать изображение. Поэтому рисование кольца поверх существующего представления изображения на самом деле не то, что мы здесь ищем, скорее мы хотим иметь возможность рисовать поверх UIView и помещать в него изображение. Это то, что нам удалось сделать с указанной выше реализацией.

Заключение

Как и многие другие вещи в программировании, это так просто или так сложно, как вы этого хотите. Другими словами, когда вы делаете это правильно, вы делаете это один раз. Другими словами, сложность упрощает жизнь. Другими словами, делайте это по-своему. Другими словами; вам нужно выбрать, какая из двух последних реализаций в вашем конкретном проекте. Вам решать!

Я хотел бы получить известие от вас, если у вас есть вопросы