Как добавить градиент к тексту UILabel, но не к фону?

Другое событие NullPointerException возникает, когда объявляется массив объектов, а затем сразу же пытается разыменовать его внутри.

String[] phrases = new String[10];
String keyPhrase = "Bird";
for(String phrase : phrases) {
    System.out.println(phrase.equals(keyPhrase));
}

Этот конкретный NPE можно избежать, если порядок сравнения отменяется ; а именно, использовать .equals для гарантированного непустого объекта.

Все элементы внутри массива инициализируются их общим начальным значением ; для любого типа массива объектов, это означает, что все элементы null.

Вы должны инициализировать элементы в массиве перед доступом или разыменованием их.

String[] phrases = new String[] {"The bird", "A bird", "My bird", "Bird"};
String keyPhrase = "Bird";
for(String phrase : phrases) {
    System.out.println(phrase.equals(keyPhrase));
}

24
задан Brad Larson 12 August 2009 в 17:45
поделиться

2 ответа

Вы можете выделить подкласс UILable и выполнить метод рисования самостоятельно. Вероятно, это будет более сложный подход, может быть более простой способ.

0
ответ дан 15 October 2019 в 21:28
поделиться

В приведенном вами примере используются частные функции рисования текста, к которым у вас нет доступа на iPhone. Автор приводит пример того, как это сделать с помощью общедоступного API, в последующей публикации . Его более поздний пример использует градиентное изображение для цвета текста. (К сожалению, похоже, что его блог с тех пор был удален, но см. ответ Баха здесь , чтобы узнать о подходе, который он использовал.)

Если вы все еще хотите нарисовать градиент для цвета текста в коде, это можно сделать. Это можно сделать путем создания подкласса UILabel и переопределения -drawRect:, чтобы в нем был код, подобный следующему:

CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSaveGState(context);
CGContextTranslateCTM(context, 0.0f, self.bounds.size.height);
CGContextScaleCTM(context, 1.0f, -1.0f);

CGContextSelectFont(context, "Helvetica", 20.0f, kCGEncodingMacRoman);
CGContextSetTextDrawingMode(context, kCGTextClip);
CGContextSetTextPosition(context, 0.0f, round(20.0f / 4.0f));
CGContextShowText(context, [self.text UTF8String], strlen([self.text UTF8String]));

CGContextClip(context);

CGGradientRef gradient;
CGColorSpaceRef rgbColorspace;
size_t num_locations = 2;
CGFloat locations[2] = { 0.0, 1.0 };
CGFloat components[8] = { 1.0, 1.0, 1.0, 1.0,  // Start color
    1.0, 1.0, 1.0, 0.1 }; // End color

rgbColorspace = CGColorSpaceCreateDeviceRGB();
gradient = CGGradientCreateWithColorComponents(rgbColorspace, components, locations, num_locations);

CGRect currentBounds = self.bounds;
CGPoint topCenter = CGPointMake(CGRectGetMidX(currentBounds), 0.0f);
CGPoint midCenter = CGPointMake(CGRectGetMidX(currentBounds), CGRectGetMidY(currentBounds));
CGContextDrawLinearGradient(context, gradient, topCenter, midCenter, 0);

CGGradientRelease(gradient);
CGColorSpaceRelease(rgbColorspace);         

CGContextRestoreGState(context);

Одним из недостатков этого подхода является то, что используемые мной функции Core Graphics не обрабатывают текст Unicode должным образом.

Что делает код, так это то, что он переворачивает контекст рисования по вертикали (iPhone инвертирует нормальную систему координат Quartz для оси Y), устанавливает режим рисования текста так, чтобы он пересекал нарисованный текст с контуром обрезки, обрезает область для рисования к тексту, а затем рисует градиент. Градиент заполняет только текст, а не фон.

Я пробовал использовать для этого метод NSString -drawAtPoint:, который поддерживает Unicode, но все символы располагались друг над другом, когда я переключил текстовый режим на kCGTextClip.

14
ответ дан 15 October 2019 в 21:28
поделиться