Все, что мне нужно, это черная рамка в один пиксель вокруг моего белого текста UILabel.
Я дошел до подкласса UILabel с помощью приведенного ниже кода, который я неуклюже сколотил из нескольких косвенно связанных онлайн-примеров. И это работает, но это очень, очень медленно (кроме симулятора), и я не мог заставить его центрировать текст по вертикали (поэтому я временно жестко закодировал значение y в последней строке). Ааааа!
void ShowStringCentered(CGContextRef gc, float x, float y, const char *str) {
CGContextSetTextDrawingMode(gc, kCGTextInvisible);
CGContextShowTextAtPoint(gc, 0, 0, str, strlen(str));
CGPoint pt = CGContextGetTextPosition(gc);
CGContextSetTextDrawingMode(gc, kCGTextFillStroke);
CGContextShowTextAtPoint(gc, x - pt.x / 2, y, str, strlen(str));
}
- (void)drawRect:(CGRect)rect{
CGContextRef theContext = UIGraphicsGetCurrentContext();
CGRect viewBounds = self.bounds;
CGContextTranslateCTM(theContext, 0, viewBounds.size.height);
CGContextScaleCTM(theContext, 1, -1);
CGContextSelectFont (theContext, "Helvetica", viewBounds.size.height, kCGEncodingMacRoman);
CGContextSetRGBFillColor (theContext, 1, 1, 1, 1);
CGContextSetRGBStrokeColor (theContext, 0, 0, 0, 1);
CGContextSetLineWidth(theContext, 1.0);
ShowStringCentered(theContext, rect.size.width / 2.0, 12, [[self text] cStringUsingEncoding:NSASCIIStringEncoding]);
}
У меня просто неприятное ощущение, что я упускаю из виду более простой способ сделать это. Возможно, переопределив "drawTextInRect", но я вообще не могу заставить drawTextInRect подчиняться моей воле, несмотря на то, что я пристально смотрел на него и очень сильно хмурился.
ios
objective-c
iphone
cocoa-touch
core-graphics
Монте-Херд
источник
источник
Ответы:
Я смог это сделать, переопределив drawTextInRect:
источник
UILabel
создать подкласс и поместить-drawTextInRect:
туда реализацию.Более простое решение - использовать строку с атрибутами следующим образом:
Swift 4:
Swift 4.2:
На a
UITextField
вы также можете установитьdefaultTextAttributes
иattributedPlaceholder
.Обратите внимание, что в этом случае значение
NSStrokeWidthAttributeName
должно быть отрицательным , т.е. работают только внутренние контуры.источник
Прочитав принятый ответ и два исправления к нему, а также ответ Акселя Гильмина, я решил скомпилировать общее решение на Swift, которое мне подходит:
Вы можете добавить этот настраиваемый класс UILabel к существующей метке в Interface Builder и изменить толщину границы и ее цвет, добавив определяемые пользователем атрибуты времени выполнения следующим образом:
Результат:
источник
Есть одна проблема с реализацией ответа. Рисование текста с обводкой имеет немного другую ширину символа символа, чем рисование текста без обводки, что может привести к «нецентрированным» результатам. Это можно исправить, добавив невидимую обводку вокруг текста заливки.
Заменить:
с участием:
Я не уверен на 100%, так ли это на самом деле, потому что я не знаю,
self.textColor = textColor;
имеет ли он такой же эффект[textColor setFill]
, но он должен работать.Раскрытие информации: я разработчик THLabel.
Некоторое время назад я выпустил подкласс UILabel, который позволяет использовать текст и другие эффекты. Вы можете найти его здесь: https://github.com/tobihagemann/THLabel
источник
Это не создаст контура как такового, но создаст тень вокруг текста, и если вы сделаете радиус тени достаточно маленьким, он может напоминать контур.
Не знаю, совместим ли он со старыми версиями iOS ..
В любом случае, я надеюсь, что это поможет ...
источник
Версия класса Swift 4, основанная на ответе kprevas
Его можно полностью реализовать в Интерфейсном Разработчике, установив для настраиваемого класса UILabel значение OutlinedText. Затем у вас будет возможность установить ширину и цвет контура на панели свойств.
источник
Если вы хотите анимировать что-то сложное, лучший способ - это программно сделать снимок экрана, а вместо этого анимировать!
Чтобы сделать снимок экрана представления, вам понадобится примерно такой код:
Где mainContentView - это представление, снимок экрана которого вы хотите сделать. Добавьте viewImage в UIImageView и оживите его.
Надеюсь, это ускорит вашу анимацию !!
N
источник
Как MuscleRumble упоминал , граница принятого ответа немного не по центру. Я смог исправить это, установив ширину штриха равной нулю вместо того, чтобы менять цвет на прозрачный.
т.е. замена:
с участием:
Я бы просто прокомментировал его ответ, но, видимо, я недостаточно "уважаемый".
источник
если ВСЕ, что вы хотите, это черная рамка в один пиксель вокруг моего белого текста UILabel,
тогда я действительно думаю, что вы усложняете проблему, чем она есть ... Я не знаю по памяти, какую функцию 'draw rect / frameRect' вы должны использовать, но вам будет легко найти. этот метод просто демонстрирует стратегию (пусть за дело берется суперкласс!):
источник
Я нашел проблему с основным ответом. Положение текста не обязательно правильно центрировано относительно положения субпикселя, поэтому контур может не совпадать с текстом. Я исправил это с помощью следующего кода, который использует
CGContextSetShouldSubpixelQuantizeFonts(ctx, false)
:Это предполагает, что вы определили
textOutlineColor
иtextOutlineWidth
как свойства.источник
Вот еще один ответ, чтобы разместить на этикетке выделенный текст.
установить выделенный текст, просто используя метод расширения.
источник
также возможно создать подкласс UILabel со следующей логикой:
и если вы установите текст в раскадровке, тогда:
источник
Если ваша цель примерно такая:
Вот как я этого добился: я добавил новый
label
пользовательский класс в качестве Subview в мой текущий UILabel (вдохновленный этим ответом ).Просто скопируйте и вставьте его в свой проект, и все готово:
ИСПОЛЬЗОВАНИЕ:
он также работает
UIButton
со всеми его анимациями:источник
Почему бы вам не создать границу UIView в 1 пиксель в Photoshop, затем установить UIView с изображением и расположить его позади вашего UILabel?
Код:
Это избавит вас от подкласса объекта, и это довольно просто сделать.
Не говоря уже о том, что если вы хотите делать анимацию, она встроена в класс UIView.
источник
Чтобы поместить границу с закругленными краями вокруг UILabel, я делаю следующее:
(не забудьте включить QuartzCore / QuartzCore.h)
источник