Если у меня UIButton организован с использованием autolayout, его размер корректно подстраивается под его содержимое.
Если я установлю изображение как button.image
, внутренний размер снова, кажется, объясняет это.
Однако, если я настрою titleEdgeInsets
кнопку, макет не учитывает это и вместо этого усекает заголовок кнопки.
Как я могу гарантировать, что внутренняя ширина кнопки составляет вкладку?
Редактировать:
Я использую следующее:
[self.backButton setTitleEdgeInsets:UIEdgeInsetsMake(0, 5, 0, 0)];
Цель состоит в том, чтобы добавить некоторое разделение между изображением и текстом.
ios
cocoa-touch
uiview
uibutton
autolayout
Бен Паккард
источник
источник
titleEdgeInset
документации:The insets you specify are applied to the title rectangle after that rectangle has been sized to fit the button’s text. Thus, positive inset values may actually clip the title text.
Итак, добавив вкладку, вы заставляете кнопкуОтветы:
Вы можете решить эту проблему без необходимости переопределять любые методы или устанавливать произвольное ограничение ширины. Вы можете сделать все это в Интерфейсном Разработчике следующим образом.
Внутренняя ширина кнопки определяется на основе ширины заголовка и ширины значка, а также вставок левого и правого края содержимого .
Если у кнопки есть и изображение, и текст, они центрируются как группа, без отступов между ними.
Если вы добавляете левую вставку содержимого, она рассчитывается относительно текста, а не текста + значка.
Если вы установите отрицательную левую вставку изображения, изображение будет вытянуто влево, но общая ширина кнопки не изменится.
Если вы установите отрицательную левую вставку изображения, фактический макет использует половину этого значения. Таким образом, чтобы получить левую вставку -20, вы должны использовать значение левой вставки -40 в Interface Builder.
Таким образом, вы предоставляете достаточно большую левую вставку содержимого, чтобы создать пространство как для желаемой левой вставки, так и для внутреннего отступа между значком и текстом, а затем смещаете значок влево, удваивая количество отступа между значком и текстом. Результатом является кнопка с равными левыми и правыми вставками содержимого, а также пара текста и значков, которые центрированы как группа, с определенным количеством отступов между ними.
Некоторые примеры значений:
источник
UIButton
.Вы можете заставить это работать в Интерфейсном Разработчике (без написания какого-либо кода), используя комбинацию отрицательных и положительных Заголовков и Врезок Содержания.
Обновление : в Xcode 7 есть ошибка, из-за которой нельзя вводить отрицательные значения в
Right
поле Inset, но вы можете использовать шаговый регулятор рядом с ним, чтобы уменьшить значение. (Спасибо, Стюарт)Делая это, вы добавите 8pt промежутка между изображением и заголовком и увеличите внутреннюю ширину кнопки на ту же величину. Как это:
источник
Right
поле.Почему бы не переопределить
intrinsicContentSize
метод в UIView? Например:Это должно сказать системе автоматического размещения, что она должна увеличить размер кнопки, чтобы учесть вставки и показать полный текст. Я не за своим компьютером, поэтому я не проверял это.
источник
intrinsicContentSize
это метод на UIView, а не UIButton, так что вы не будете возиться ни с какими методами UIButton. Apple не считает, что это проблема: «Переопределение этого метода позволяет настраиваемому представлению сообщать системе макетов, какой размер он хотел бы основывать на своем контенте». И ОП ничего не сказал о разных кнопках, кроме одной.intrinsicContentSize
это действительно метод в UIView, а UIButton является подклассом UIView, поэтому, конечно, вы можете переопределить этот метод; ничто в документации Apple не говорит, что вы не должны. Просто создайте подкласс UIButton, используя переопределенный метод Maarten, и измените UIButton в Интерфейсном Разработчике на тип YourUIButtonSubclass, и он будет отлично работать.intrinsicContentSize
UIButton должен добавить в titleEdgeInsets, я собираюсь подать ошибку в Apple.Вы не указали, как вы устанавливаете вставки, поэтому я предполагаю, что вы используете titleEdgeInsets, потому что я вижу тот же эффект, который вы получаете. Если я использую contentEdgeInsets вместо этого, он работает правильно.
источник
И для Свифта это сработало:
Любовь У Свифт
источник
Этот поток немного староват, но я сам столкнулся с этим и смог решить его с помощью отрицательной вставки. Например, замените желаемые значения заполнения здесь:
В сочетании с правильными ограничениями автоматической разметки вы получаете кнопку автоматического изменения размера, которая содержит изображение и текст! Видно ниже с
desiredLeftPadding
набором 10.Вы можете видеть, что фактический кадр кнопки не охватывает метку (поскольку метка смещена на 10 пунктов вправо, за пределы границ), но мы достигли 10 точек заполнения между текстом и изображением.
источник
Для Swift 3 на основе ответа pegpeg :
источник
Все вышеперечисленное не работает для iOS 9+ , что я сделал:
Теперь, чтобы добавить рамку вокруг кнопки, просто используйте метод:
источник
Я хотел добавить 5pt пробел между моей иконкой UIButton и надписью. Вот как я этого добился:
То, как contentEdgeInsets, titleEdgeInsets и imageEdgeInsets связаны друг с другом, требует небольшой отдачи от каждой вставки. Поэтому, если вы добавляете несколько вставок слева от заголовка, вы должны добавить отрицательную вставку справа и предоставить больше места (через положительную вставку) справа от содержимого.
При добавлении правильной вставки содержимого в соответствии со смещением вставок заголовка мой текст не выходит за пределы кнопки.
источник
Опция также доступна в конструкторе интерфейсов. Смотрите вставку. Я установил влево и вправо на 3. Работает как шарм.
источник
Решение, которое я использую, заключается в добавлении ограничения ширины на кнопку. Затем где-нибудь в инициализации, после того, как ваш текст установлен, обновите ограничение ширины следующим образом:
self.buttonWidthConstraint.constant = self.shareButton.intrinsicContentSize.width + 8;
Где 8, какой бы ни была ваша вставка.
источник
constant
ограничение до нового значения ... и знать, когда изменяется размер внутреннего содержимого кнопки, сложно без подкласса кнопки.setNeedsUpdateConstraints
может быть сделан "вручную" после обновления заголовка кнопки или изображения. После этого вы можете переопределитьupdateConstraints
и пересчитатьbuttonWidthConstraint
константу. Это не обязательно лучший подход, но он работает достаточно хорошо для меня. YMMV;)Вызов sizeToFit () гарантирует, что contentEdgeInset вступит в силу
источник
titleEdgeInsets