UISegmentedController 中的图标和文本

问题描述 投票:0回答:3

一个片段只能有一个图像或一个标题;它不能两者兼得。没有默认图像。

Apple 在 UISegmentedController Reference 中如此说道。

有人想出了一个通用的解决方案,可以让你同时拥有图标和文本吗?我有一个有四个段的分段控件。有一些用于自定义控件外观的选项,但它们似乎只为具有两个段的 UISegmentedControl 设计?

我正在思考的想法:

  1. 放弃四个 UIButton 的分段控件并自己处理“选定”状态
  2. 举起双手,只需使用文本图标即可。
  3. 您的建议...?
iphone ios cocoa-touch
3个回答
10
投票

您可以通过将当前图像绘制到上下文中来创建新图像,绘制所需的文本,然后使用该组合图像作为单段图像:

UIGraphicsBeginImageContextWithOptions(size, YES, 0);
CGContextRef context = UIGraphicsGetCurrentContext();

// Text first
[myString drawAtPoint:somePoint withFont:font];

// Images upside down so flip them 
CGAffineTransform flipVertical = CGAffineTransformMake(1, 0, 0, -1, 0, size.height);
CGContextConcatCTM(context, flipVertical);
CGContextDrawImage(context, (CGRect){ imagePoint, imageSize }, [myUIimage CGImage]);

UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

return image;

5
投票

您可能想尝试第三方替代方案,例如STSegmentedControl(没有关系,但我已经使用过它,听起来它会给您所需的灵活性,而无需从头开始)。


0
投票

您可以尝试我的解决方案并根据需要进行修改。 添加一些扩展:

extension NSLayoutConstraint {
    enum EdgeAttribute {
        case leading, trailing
    }
}

extension UIImage {
    func insertAttributedText(_ text: NSAttributedString, atEdge edge: NSLayoutConstraint.EdgeAttribute, offset: CGFloat, prefferedImageSize: CGSize?) -> UIImage {
        var imageSize = size
    
        if let size = prefferedImageSize {
            imageSize = size
        }
    
        let textSize = text.size()
        let expectedBoundsWidth = textSize.width + imageSize.width + offset
        let expectedBoundsHeight = max(textSize.height, imageSize.height)
        let expectedBoundsSize = CGSize(width: expectedBoundsWidth, height: expectedBoundsHeight)
        let render = UIGraphicsImageRenderer(size: expectedBoundsSize)
    
        return render.image(actions: { _ in
            let textXPoint: CGFloat
            let imageXPoint: CGFloat
        
            switch edge {
            case .leading:
                textXPoint = 0
                imageXPoint = textSize.width + offset
            case .trailing:
                textXPoint = imageSize.width + offset
                imageXPoint = 0
            }
        
            let textYPoint: CGFloat = (expectedBoundsSize.height - textSize.height) / 2
            let imageYPoint: CGFloat = (expectedBoundsSize.height - imageSize.height) / 2
        
            text.draw(at: CGPoint(x: textXPoint, y: textYPoint))
            draw(in: CGRect(origin: CGPoint(x: imageXPoint, y: imageYPoint), size: imageSize))
        })
    }
}

然后配置你的segmentedControl:

    let image = UIImage(systemName: "doc.plaintext")!.insertAttributedText(
        NSAttributedString(string: "Text"),
        atEdge: .leading,
        offset: 5,
        prefferedImageSize: CGSize(width: 16, height: 12)
    )
     
    segmentedControl.insertSegment(with: image, at: 0, animated: false)
© www.soinside.com 2019 - 2024. All rights reserved.