struct GradientView: View {
var body: some View {
VStack {
GradientLabelWrapper(width: 150) // you can give as you want
.frame(width: 200, height: 200, alignment: .center) // set frame as you want
}
}
}
型
GradientLabelWrapper:
struct GradientLabelWrapper: UIViewRepresentable {
var width: CGFloat
var text: String?
typealias UIViewType = UIView
func makeUIView(context: UIViewRepresentableContext<GradientLabelWrapper>) -> UIView {
let label = UILabel()
label.lineBreakMode = .byWordWrapping
label.numberOfLines = 0
label.preferredMaxLayoutWidth = width
label.text = text ?? ""
label.font = UIFont.systemFont(ofSize: 25) //set as you need
label.applyGradientWith(startColor: .red, endColor: .blue)
return label
}
func updateUIView(_ uiView: UIView, context: UIViewRepresentableContext<GradientLabelWrapper>) {
}
}
型
**UILabel:**扩展名
extension UILabel {
func applyGradientWith(startColor: UIColor, endColor: UIColor) {
var startColorRed:CGFloat = 0
var startColorGreen:CGFloat = 0
var startColorBlue:CGFloat = 0
var startAlpha:CGFloat = 0
if !startColor.getRed(&startColorRed, green: &startColorGreen, blue: &startColorBlue, alpha: &startAlpha) {
return
}
var endColorRed:CGFloat = 0
var endColorGreen:CGFloat = 0
var endColorBlue:CGFloat = 0
var endAlpha:CGFloat = 0
if !endColor.getRed(&endColorRed, green: &endColorGreen, blue: &endColorBlue, alpha: &endAlpha) {
return
}
let gradientText = self.text ?? ""
let textSize: CGSize = gradientText.size(withAttributes: [NSAttributedString.Key.font:self.font!])
let width:CGFloat = textSize.width
let height:CGFloat = textSize.height
UIGraphicsBeginImageContext(CGSize(width: width, height: height))
guard let context = UIGraphicsGetCurrentContext() else {
UIGraphicsEndImageContext()
return
}
UIGraphicsPushContext(context)
let glossGradient:CGGradient?
let rgbColorspace:CGColorSpace?
let num_locations:size_t = 2
let locations:[CGFloat] = [ 0.0, 1.0 ]
let components:[CGFloat] = [startColorRed, startColorGreen, startColorBlue, startAlpha, endColorRed, endColorGreen, endColorBlue, endAlpha]
rgbColorspace = CGColorSpaceCreateDeviceRGB()
glossGradient = CGGradient(colorSpace: rgbColorspace!, colorComponents: components, locations: locations, count: num_locations)
let topCenter = CGPoint.zero
let bottomCenter = CGPoint(x: 0, y: textSize.height)
context.drawLinearGradient(glossGradient!, start: topCenter, end: bottomCenter, options: CGGradientDrawingOptions.drawsBeforeStartLocation)
UIGraphicsPopContext()
guard let gradientImage = UIGraphicsGetImageFromCurrentImageContext() else {
UIGraphicsEndImageContext()
return
}
UIGraphicsEndImageContext()
self.textColor = UIColor(patternImage: gradientImage)
}
}
7条答案
按热度按时间b1payxdu1#
我已经用新答案更新了答案,你可以试试。旧的答案仍然可用。
新答案
字符串
输出
的数据
旧答案
在
SwiftUI
中你也可以这样做,如下所示,使用添加渐变颜色到文本的概念渐变视图:
型
GradientLabelWrapper:
型
**UILabel:**扩展名
型
i5desfxk2#
这可以在纯
SwiftUI
中轻松完成,而不需要使用UIViewRepresentable
。你需要用你的文本来遮罩渐变:字符串
的数据
jm81lzqq3#
我想这应该有帮助。可处理文本、图像和任何其他视图。
字符串
我个人最喜欢这种方式。但你也可以将其合并为:
型
使用示例
型
的数据
See gist
guicsvcw4#
SwiftUI新增:修改器
.foregroundStyle()
(iOS15+)的数据
字符串
mqkwyuun5#
您可以将任何渐变或其他类型的视图指定为自调整大小的遮罩,如:
字符串
with this simple简单tiny小extension扩展:
型
的数据
奖金1
您可以将其应用于任何类型的
view
:的
奖金2
此外,您可以在其上应用所有渐变或任何类型的视图:
的
bpzcxfmw6#
将其创建为
TextStyle
是有意义的,就像LabelStyle
和ButtonStyle
一样,但奇怪的是,SwiftUI出于某种原因将Text
排除在样式修饰符之外。一个自定义的可以继续创建,直到SwiftUI发布一个API(?):字符串
有了这个,可以创建自定义文本样式(受接受答案启发的覆盖/遮罩技术):
型
然后你可以像使用
LabelStyle
或ButtonStyle
一样使用它:型
x1c 0d1x的数据
wgeznvg77#
您可以使用此选项将渐变作为文本的前景色:
字符串
希望这对你有帮助:)你也可以使用这个链接作为你的参考:https://www.hackingwithswift.com/quick-start/swiftui/how-to-render-a-gradient