7

我正在使用一个UISegmentedControl内部UIToolBar按钮。我不能使用 normal UIButtonBarItem,因为我需要设置tintColor并支持 iOS 4.3。所以我使用以下代码:

UISegmentedControl* searchButton = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObjects:@"", nil]];
[searchButton setImage:[UIImage imageNamed:@"search_picto"] forSegmentAtIndex:0];
searchButton.momentary = YES;
searchButton.segmentedControlStyle = UISegmentedControlStyleBar;
searchButton.tintColor = [UIColor colorWithRed:0.27 green:0.60 blue:0.20 alpha:1.00];
[searchButton addTarget:self action:@selector(actionSearch:) forControlEvents:UIControlEventValueChanged];

这很好用,但是有没有办法在我的图像旁边有一个文本/标题?方法 setTitle: 删除图像。一定有别的办法...

谢谢你的帮助。

--

编辑:我决定将文本直接添加到UIImageView这样的:

NSString* label = @"My Label";
UIImage* image = [self addText:label toImage:[UIImage imageNamed:@"icon"]];
[_segmentedControl insertSegmentWithImage:image atIndex:0 animated:NO];
[_segmentedControl setWidth:image.size.width + 10]; // add some margin on the right



- (UIImage *)addText:(NSString *)text toImage:(UIImage *)image {
    UIFont* font = [UIFont boldSystemFontOfSize: 12];
    CGSize expectedSize = [text sizeWithFont:font];

    [self retinaAwareUIGraphicsBeginImageContext:CGSizeMake(image.size.width + expectedSize.width + 10, image.size.height)];
    [image drawAtPoint: CGPointZero];
    [[UIColor whiteColor] set];
    [text drawAtPoint: CGPointMake(30, 2) withFont:font];
    image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return image;
}

- (void)retinaAwareUIGraphicsBeginImageContext:(CGSize) size {
    CGFloat scale = -1.0;
    if (scale<0.0) {
        UIScreen *screen = [UIScreen mainScreen];
        if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 4.0) {
            scale = [screen scale];
        }
        else {
            scale = 0.0;
        }
    }
    if (scale>0.0) {
        UIGraphicsBeginImageContextWithOptions(size, NO, scale);
    }
    else {
        UIGraphicsBeginImageContext(size);
    }
}
4

7 回答 7

23

你能行的:

为 UIImage 添加类别:

在 UIImage+UISegmentIconAndText.h

@interface UIImage (UISegmentIconAndText)

+ (id) imageFromImage:(UIImage*)image string:(NSString*)string color:(UIColor*)color;
+ (id) imageFromImage:(UIImage*)image string:(NSString*)string color:(UIColor*)color position:(NSString*)position;

@end

UIImage+UISegmentIconAndText.m

#import "UIImage+UISegmentIconAndText.h"

@implementation UIImage (UISegmentIconAndText)
+ (id) imageFromImage:(UIImage*)image string:(NSString*)string color:(UIColor*)color
{
    UIFont *font = [UIFont systemFontOfSize:16.0];
    CGSize expectedTextSize = [string sizeWithAttributes:@{NSFontAttributeName: font}];
    int width = expectedTextSize.width + image.size.width + 5;
    int height = MAX(expectedTextSize.height, image.size.width);
    CGSize size = CGSizeMake((float)width, (float)height);
    UIGraphicsBeginImageContextWithOptions(size, NO, 0);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetFillColorWithColor(context, color.CGColor);
    int fontTopPosition = (height - expectedTextSize.height) / 2;
    CGPoint textPoint = CGPointMake(image.size.width + 5, fontTopPosition);

    [string drawAtPoint:textPoint withAttributes:@{NSFontAttributeName: font}];
    // Images upside down so flip them
    CGAffineTransform flipVertical = CGAffineTransformMake(1, 0, 0, -1, 0, size.height);
    CGContextConcatCTM(context, flipVertical);
    CGContextDrawImage(context, (CGRect){ {0, (height - image.size.height) / 2}, {image.size.width, image.size.height} }, [image CGImage]);
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return newImage;
}
@end

在您的代码中实现段:

UIImage *imageWithText = [UIImage imageFromImage:[UIImage imageNamed:@"images/jobaids_tab_icon"] string:@"Hello", nil) color:[UIColor whiteColor]];

[_segmentedController setImage:imageWithText forSegmentAtIndex:0];
于 2014-03-26T06:51:24.430 回答
7

斯威夫特 4

extension UIImage {

class func textEmbededImage(image: UIImage, string: String, color:UIColor, imageAlignment: Int = 0, segFont: UIFont? = nil) -> UIImage {
    let font = segFont ?? UIFont.systemFont(ofSize: 16.0)
    let expectedTextSize: CGSize = (string as NSString).size(withAttributes: [NSAttributedStringKey.font: font])
    let width: CGFloat = expectedTextSize.width + image.size.width + 5.0
    let height: CGFloat = max(expectedTextSize.height, image.size.width)
    let size: CGSize = CGSize(width: width, height: height)
    UIGraphicsBeginImageContextWithOptions(size, false, 0)
    let context: CGContext = UIGraphicsGetCurrentContext()!
    context.setFillColor(color.cgColor)
    let fontTopPosition: CGFloat = (height - expectedTextSize.height) / 2.0
    let textOrigin: CGFloat = (imageAlignment == 0) ? image.size.width + 5 : 0
    let textPoint: CGPoint = CGPoint.init(x: textOrigin, y: fontTopPosition)
    string.draw(at: textPoint, withAttributes: [NSAttributedStringKey.font: font])
    let flipVertical: CGAffineTransform = CGAffineTransform(a: 1, b: 0, c: 0, d: -1, tx: 0, ty: size.height)
    context.concatenate(flipVertical)
    let alignment: CGFloat =  (imageAlignment == 0) ? 0.0 : expectedTextSize.width + 5.0
    context.draw(image.cgImage!, in: CGRect.init(x: alignment, y: ((height - image.size.height) / 2.0), width: image.size.width, height: image.size.height))
    let newImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

    return newImage!
}
}
于 2018-09-05T06:59:28.967 回答
5

斯威夫特 5

对于我们这些喜欢尽可能使用现代 API 的人:

extension UIImage {
    static func textEmbeded(image: UIImage,
                           string: String,
                isImageBeforeText: Bool,
                          segFont: UIFont? = nil) -> UIImage {
        let font = segFont ?? UIFont.systemFont(ofSize: 16)
        let expectedTextSize = (string as NSString).size(withAttributes: [.font: font])
        let width = expectedTextSize.width + image.size.width + 5
        let height = max(expectedTextSize.height, image.size.width)
        let size = CGSize(width: width, height: height)

        let renderer = UIGraphicsImageRenderer(size: size)
        return renderer.image { context in
            let fontTopPosition: CGFloat = (height - expectedTextSize.height) / 2
            let textOrigin: CGFloat = isImageBeforeText
                ? image.size.width + 5
                : 0
            let textPoint: CGPoint = CGPoint.init(x: textOrigin, y: fontTopPosition)
            string.draw(at: textPoint, withAttributes: [.font: font])
            let alignment: CGFloat = isImageBeforeText
                ? 0
                : expectedTextSize.width + 5
            let rect = CGRect(x: alignment,
                              y: (height - image.size.height) / 2,
                          width: image.size.width,
                         height: image.size.height)
            image.draw(in: rect)
        }
    }
}
于 2019-05-08T12:13:11.703 回答
1

对于斯威夫特。

segFont是嵌入文本的字体。

imageAlignment是出现在文本左侧或右侧的图像的对齐方式。

imageAlignment设置为0用于左对齐(图像将出现在文本的左侧)和1用于右对齐(图像将出现在文本的右侧)

class func textEmbededImage(image: UIImage, string: String, color:UIColor, imageAlignment: Int = 0, segFont: UIFont? = nil) -> UIImage {

let font = segFont ?? UIFont.systemFontOfSize(16.0)

let expectedTextSize: CGSize = (string as NSString).sizeWithAttributes([NSFontAttributeName: font])

let width: CGFloat = expectedTextSize.width + image.size.width + 5.0

let height: CGFloat = max(expectedTextSize.height, image.size.width)

let size: CGSize = CGSizeMake(width, height)

UIGraphicsBeginImageContextWithOptions(size, false, 0)

let context: CGContextRef = UIGraphicsGetCurrentContext()!

CGContextSetFillColorWithColor(context, color.CGColor)

let fontTopPosition: CGFloat = (height - expectedTextSize.height) / 2.0

let textOrigin: CGFloat = (imageAlignment == 0) ? image.size.width + 5 : 0
let textPoint: CGPoint = CGPointMake(textOrigin, fontTopPosition)


string.drawAtPoint(textPoint, withAttributes: [NSFontAttributeName: font])
let flipVertical: CGAffineTransform = CGAffineTransformMake(1, 0, 0, -1, 0, size.height)
CGContextConcatCTM(context, flipVertical)

let alignment: CGFloat =  (imageAlignment == 0) ? 0.0 : expectedTextSize.width + 5.0
CGContextDrawImage(context, CGRectMake(alignment, ((height - image.size.height) / 2.0), image.size.width, image.size.height), image.CGImage)
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()

return newImage
}
于 2016-09-16T03:50:35.200 回答
0

斯威夫特 3

extension UIImage{


class func textEmbededImage(image: UIImage, string: String, color:UIColor, imageAlignment: Int = 0, segFont: UIFont? = nil) -> UIImage {
    let font = segFont ?? UIFont.systemFont(ofSize: 16.0)
    let expectedTextSize: CGSize = (string as NSString).size(attributes: [NSFontAttributeName: font])
    let width: CGFloat = expectedTextSize.width + image.size.width + 5.0
    let height: CGFloat = max(expectedTextSize.height, image.size.width)
    let size: CGSize = CGSize(width: width, height: height)
    UIGraphicsBeginImageContextWithOptions(size, false, 0)
    let context: CGContext = UIGraphicsGetCurrentContext()!
    context.setFillColor(color.cgColor)
    let fontTopPosition: CGFloat = (height - expectedTextSize.height) / 2.0
    let textOrigin: CGFloat = (imageAlignment == 0) ? image.size.width + 5 : 0
    let textPoint: CGPoint = CGPoint.init(x: textOrigin, y: fontTopPosition)        
    string.draw(at: textPoint, withAttributes: [NSFontAttributeName: font])
    let flipVertical: CGAffineTransform = CGAffineTransform(a: 1, b: 0, c: 0, d: -1, tx: 0, ty: size.height)
    context.concatenate(flipVertical)
    let alignment: CGFloat =  (imageAlignment == 0) ? 0.0 : expectedTextSize.width + 5.0
    context.draw(image.cgImage!, in: CGRect.init(x: alignment, y: ((height - image.size.height) / 2.0), width: image.size.width, height: image.size.height))
    let newImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    return newImage!
}

}
于 2017-04-04T20:15:33.773 回答
0

斯威夫特 5

我需要在右上角添加一个图像,所以我添加了 imageOffset。

extension UIImage {
  static func textEmbeded(image: UIImage, string: String, titleColor: UIColor, imageBeforeText: Bool, imageOffset: CGPoint, segFont: UIFont? = nil) -> UIImage {
    let font = segFont ?? UIFont.systemFont(ofSize: 16)
    let expectedTextSize = (string as NSString).size(withAttributes: [.font: font])
    let width = expectedTextSize.width + image.size.width +
                max(0, imageBeforeText ? imageOffset.x * -1 : imageOffset.x)
    let height = max(expectedTextSize.height, (image.size.height / 2 + abs(imageOffset.y)) * 2)
    let size = CGSize(width: width, height: height)

    let renderer = UIGraphicsImageRenderer(size: size)
    return renderer.image { context in
      let textTopPosition: CGFloat = (height - expectedTextSize.height) / 2
      let textLeftPosition: CGFloat = imageBeforeText ? image.size.width - imageOffset.x : 0
      let textPoint: CGPoint = CGPoint.init(x: textLeftPosition, y: textTopPosition)
      string.draw(at: textPoint, withAttributes: [.font: font, .foregroundColor: titleColor])
    
      let imageLeftPosition: CGFloat = imageBeforeText ? 0 : expectedTextSize.width + imageOffset.x
      let imageTopPosition: CGFloat = (height - image.size.height) / 2 + imageOffset.y
      let imageRect = CGRect(x: imageLeftPosition,
                             y: imageTopPosition,
                         width: image.size.width,
                        height: image.size.height)
      image.draw(in: imageRect)
    }.withRenderingMode(.alwaysOriginal)
  }
}
  • 图像重叠文本未实现
  • 当 imageBeforeText 为真时,减去 x 偏移量意味着图像和文本之间的空间更大。
  • 与 RenderingMode(.alwaysOriginal) 一起使用以获取文本和图像的不同颜色
于 2021-04-04T13:44:28.003 回答
-4

试试这个:

UISegmentedControl* searchButton = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObjects:@"", nil]];
[searchButton insertSegmentWithImage:[UIImage imageNamed:@"up_button.png"] atIndex:0 animated:YES];
[searchButton insertSegmentWithImage:[UIImage imageNamed:@"down_button.png"] atIndex:1 animated:YES];
searchButton.segmentedControlStyle = UISegmentedControlStyleBar;
searchButton.tintColor = [UIColor colorWithRed:0.27 green:0.60 blue:0.20 alpha:1.00];
[searchButton setMomentary:YES];
于 2012-11-19T18:58:27.870 回答