Apple довольно четко определила, как подкласс UIView
в документе.
Проверьте список ниже, особенно взгляните на initWithFrame:
и layoutSubviews
. Первый предназначен для настройки рамки вашегоUIView
тогда как второй предназначен для настройки фрейма и макета его подпредставлений.
Также помните, что он initWithFrame:
вызывается, только если вы создаете свою UIView
программу программно. Если вы загружаете его из файла пера (или раскадровки), initWithCoder:
будет использоваться. И в initWithCoder:
кадре еще не был рассчитан, поэтому вы не можете изменить кадр, который вы установили в Интерфейсном Разработчике. Как предлагается в этом ответе, вы можете подумать о том, чтобы позвонить initWithFrame:
изinitWithCoder:
того , чтобы настроить рамку.
Наконец, если вы загружаете свой UIView
из пера (или раскадровки), у вас также есть awakeFromNib
возможность выполнять пользовательские инициализации фрейма и макета, так как, когдаawakeFromNib
вызове гарантируется, что каждое представление в иерархии было разархивировано и инициализировано.
Из документа NSNibAwaking
(теперь заменен документом awakeFromNib
):
Сообщения другим объектам можно безопасно отправлять из awakeFromNib - к этому времени гарантируется, что все объекты разархивированы и инициализированы (хотя, конечно, не обязательно пробуждены)
Стоит также отметить, что с autolayout вы не должны явно устанавливать рамку своего представления. Вместо этого вы должны указать набор достаточных ограничений, чтобы фрейм автоматически вычислял кадр.
Прямо из документации :
Методы для переопределения
инициализация
initWithFrame:
Рекомендуется реализовать этот метод. Вы также можете реализовать пользовательские методы инициализации в дополнение или вместо этого метода.
initWithCoder:
Реализуйте этот метод, если вы загружаете ваше представление из nib-файла Interface Builder, и ваше представление требует пользовательской инициализации.
layerClass
Реализуйте этот метод, только если вы хотите, чтобы ваше представление использовало другой слой Core Animation для своего резервного хранилища. Например, если вы используете OpenGL ES для рисования, вам нужно переопределить этот метод и вернуть класс CAEAGLLayer.
Рисование и печать
drawRect:
Реализуйте этот метод, если ваше представление рисует пользовательский контент. Если ваш вид не выполняет никаких пользовательских рисунков, избегайте переопределения этого метода.
drawRect:forViewPrintFormatter:
Реализуйте этот метод, только если вы хотите по-разному отображать содержимое вашего представления во время печати.
Ограничения
requiresConstraintBasedLayout
Реализуйте этот метод класса, если ваш класс представления требует ограничений для правильной работы.
updateConstraints
Реализуйте этот метод, если вашему представлению необходимо создать пользовательские ограничения между вашими подпредставлениями.
alignmentRectForFrame:
, frameForAlignmentRect:
Реализуйте эти методы, чтобы переопределить, как ваши представления выровнены с другими представлениями.
раскладка
sizeThatFits:
Реализуйте этот метод, если вы хотите, чтобы размер вашего представления отличался от размера по умолчанию, чем обычно при операциях изменения размера. Например, вы можете использовать этот метод, чтобы предотвратить сужение вашего вида до точки, где подпредставления не могут отображаться правильно.
layoutSubviews
Реализуйте этот метод, если вам нужен более точный контроль над компоновкой ваших подпредставлений, чем обеспечивают ограничения или режимы автоматического изменения размера.
didAddSubview:
, willRemoveSubview:
Реализовать эти методы, необходимые для отслеживания дополнения и изъятия подвидов.
willMoveToSuperview:
, didMoveToSuperview
Реализовать эти методы, необходимые для отслеживания перемещения текущего вида в иерархии вида.
willMoveToWindow:
, didMoveToWindow
Реализовать эти методы, необходимые для отслеживания движения вашей точки зрения в другое окно.
Обработка событий:
touchesBegan:withEvent:
, touchesMoved:withEvent:
, touchesEnded:withEvent:
, touchesCancelled:withEvent:
Реализовать эти методы , если вам нужно обрабатывать событие прикосновения непосредственно. (Для ввода на основе жестов используйте распознаватели жестов.)
gestureRecognizerShouldBegin:
Реализуйте этот метод, если ваше представление напрямую обрабатывает сенсорные события и может потребовать, чтобы присоединенные распознаватели жестов не запускали дополнительные действия.
Габриэле Петронелла
источник
layoutSubviews
?Это все еще высоко в Google. Ниже приведен обновленный пример для swift.
didLoad
Функция позволяет поместить весь код пользовательской инициализации. Как уже упоминалось,didLoad
будет вызываться, когда представление создается программно с помощьюinit(frame:)
или когда десериализатор XIB объединяет шаблон XIB с вашим представлением черезinit(coder:)
источник
draw
метод?В документации Apple есть достойное резюме , и это хорошо освещено в бесплатном Стэнфордском курсе, доступном в iTunes. Я представляю свою версию TL; DR здесь:
Если ваш класс в основном состоит из подпредставлений, правильное место для их размещения - в
init
методах. Для представлений есть два разныхinit
метода, которые могут быть вызваны в зависимости от того, создается ли ваше представление из кода или из nib / storyboard. Что я могу сделать , это написать свой собственныйsetup
метод, а затем вызвать его из обоихinitWithFrame:
иinitWithCoder:
методов.Если вы делаете собственный рисунок, вы действительно хотите переопределить
drawRect:
. Если ваш пользовательский вид в основном является контейнером для подпредставлений, вам, вероятно, не понадобится это делать.Переопределять, только
layoutSubViews
если вы хотите сделать что-то вроде добавления или удаления подпредставления, в зависимости от того, находитесь ли вы в книжной или альбомной ориентации. В противном случае вы сможете оставить это в покое.источник
layoutSubViews
, это сработало.layoutSubviews
предназначен для установки рамки на дочерние представления, а не на само представление.Для
UIView
, как правило, назначенный конструктор,initWithFrame:(CGRect)frame
и вы должны установить кадр там (или вinitWithCoder:
), возможно, игнорируя переданное в значение кадра. Вы также можете предоставить другой конструктор и установить фрейм там.источник
awakeFromNib