使用半透明分隔线、按钮大小和延迟色调自定义 UIStepper 时出现问题
Problems customizing UIStepper with translucent divider, button sizes and deferring tint color
在为我的 iOS 应用自定义 UIStepper 控件时遇到问题。
到目前为止,我已经能够将其自定义为背景和分隔线是半透明的,并使用下面的代码更改了增量和减量图像...
func decorate(stepper: UIStepper) {
let greyLeft = UIImage(named: Assets.Button.leftGrey)
let greenLeft = UIImage(named: Assets.Button.leftGreen)
let greyRight = UIImage(named: Assets.Button.rightGrey)
let greenRight = UIImage(named: Assets.Button.rightGreen)
let blank = UIImage(named: Assets.Button.translucent)
let color = UIColor(red: 147/255,
green: 148/255,
blue: 81/255,
alpha: 1.0)
stepper.setDecrementImage(greenLeft, for: .normal)
stepper.setDecrementImage(greyLeft, for: .disabled)
stepper.setIncrementImage(greenRight, for: .normal)
stepper.setIncrementImage(greyRight, for: .disabled)
stepper.setBackgroundImage(blank, for: .normal)
stepper.setDividerImage(blank,
forLeftSegmentState: .normal,
rightSegmentState: .normal)
stepper.tintColor = color
}
虽然我有 3 个问题...
- 虽然分隔线在正常状态下是半透明的,但当我点击控件时,它似乎会闪烁一个图像。我已经尝试对所有其他可用状态(包括“选定”、“突出显示”、“聚焦”、“禁用”、“应用程序”和“保留”)使用“setDividerImage”方法的第二次调用,但闪光灯仍然存在(见下面的截图)。 如何用我自己的图像替换该图像或防止闪烁?
即使我使用两个不同的图像(相同的形状,不同的颜色)作为递增和递减图像,它们的原始颜色也会被色调颜色覆盖。我想我可以在色调颜色改变时循环它,但是 是否可以推迟色调颜色以使其不覆盖图像? 然后我可以避免使用纯色。
我得到的增量图和减图图太小了。 我可以通过编程方式调整大小吗? 这样我就不必编辑图像或返回到我的图形艺术家处获得更大的图像。
问题#1 是我最关心的问题,因为我认为如果需要我可以处理#2 和#3。但是,如果我至少能确认这些问题的答案是“否”,那就太好了。
更改此行:
let blank = UIImage(named: Assets.Button.translucent)
至:
let blank = UIImage()
应该去掉突出显示的分隔符。
如果您的图像是简单的箭头,您可以通过代码“即时”轻松生成具有所需颜色的箭头,或将它们用作可着色图像。
如果你像这样加载图像:
let greyLeft = UIImage(named: Assets.Button.leftGrey)?.withRenderingMode(.alwaysOriginal)
let greenLeft = UIImage(named: Assets.Button.leftGreen)?.withRenderingMode(.alwaysOriginal)
let greyRight = UIImage(named: Assets.Button.rightGrey)?.withRenderingMode(.alwaysOriginal)
let greenRight = UIImage(named: Assets.Button.rightGreen)?.withRenderingMode(.alwaysOriginal)
它们不应受到色调颜色的影响。
编辑
看看这些变化:
func decorate(stepper: UIStepper) {
let colorNormal = UIColor(red: 147/255,
green: 148/255,
blue: 81/255,
alpha: 1.0)
let colorHighlighted = UIColor(red: 0.9,
green: 0.0,
blue: 0.0,
alpha: 1.0)
let colorDisabled = UIColor(red: 0.25,
green: 0.25,
blue: 0.25,
alpha: 1.0)
// adjust size to your liking
let fnt = UIFont.systemFont(ofSize: 32)
let configuration = UIImage.SymbolConfiguration(font: fnt)
let lArrow = UIImage(systemName: "arrowtriangle.left.fill", withConfiguration: configuration)?.withRenderingMode(.alwaysOriginal)
let leftNormal = lArrow?.withTintColor(colorNormal)
let leftHighlighted = lArrow?.withTintColor(colorHighlighted)
let leftDisabled = lArrow?.withTintColor(colorDisabled)
let rArrow = UIImage(systemName: "arrowtriangle.right.fill", withConfiguration: configuration)?.withRenderingMode(.alwaysOriginal)
let rightNormal = rArrow?.withTintColor(colorNormal)
let rightHighlighted = rArrow?.withTintColor(colorHighlighted)
let rightDisabled = rArrow?.withTintColor(colorDisabled)
let blank = UIImage()
stepper.setDecrementImage(leftNormal, for: .normal)
stepper.setDecrementImage(leftHighlighted, for: .highlighted)
stepper.setDecrementImage(leftDisabled, for: .disabled)
stepper.setIncrementImage(rightNormal, for: .normal)
stepper.setIncrementImage(rightHighlighted, for: .highlighted)
stepper.setIncrementImage(rightDisabled, for: .disabled)
stepper.setBackgroundImage(blank, for: .normal)
stepper.setDividerImage(blank,
forLeftSegmentState: .normal,
rightSegmentState: .normal)
}
这使用左右填充三角形 SF Symbol
图像(根据您的喜好调整大小),并且我为 Highlighted
状态添加了颜色(不需要)。
编辑 2
如果你想在 dec/inc 按钮之间添加一些水平的 space,我们可以通过使用清晰的图像作为“分隔线”图像来实现——但是,Apple 的文档并不特别清楚如何去做。
为了避免按钮之间的“奇怪的突出显示”,我们必须为 3 个“状态组合”设置清晰的图像:
normal / normal
normal / highlighted
highlighted / normal
所以,如果我们想要,例如,64 点的水平间距:
// create a clear image of desired width
// (height will be auto-stretched)
let blank = UIGraphicsImageRenderer(size: CGSize(width: 64, height: 8)).image(actions: {c in})
stepper.setBackgroundImage(blank, for: .normal)
// set blank image for normal / normal
stepper.setDividerImage(blank,
forLeftSegmentState: .normal,
rightSegmentState: .normal)
// set blank image for normal / highlighted
stepper.setDividerImage(blank,
forLeftSegmentState: .normal,
rightSegmentState: .highlighted)
// set blank image for highlighted / normal
stepper.setDividerImage(blank,
forLeftSegmentState: .highlighted,
rightSegmentState: .normal)
我们必须至少设置这 3 个状态组合。
奇怪的是,如果一个(或两个)按钮是 .disabled
,我们还可以也设置要使用的图像...但是,如果我们不这样做它使用匹配的 .normal
状态。
注意: 使用自定义宽度分隔图像会压缩按钮的宽度,因此这可能是也可能不是有用的信息。
在为我的 iOS 应用自定义 UIStepper 控件时遇到问题。
到目前为止,我已经能够将其自定义为背景和分隔线是半透明的,并使用下面的代码更改了增量和减量图像...
func decorate(stepper: UIStepper) {
let greyLeft = UIImage(named: Assets.Button.leftGrey)
let greenLeft = UIImage(named: Assets.Button.leftGreen)
let greyRight = UIImage(named: Assets.Button.rightGrey)
let greenRight = UIImage(named: Assets.Button.rightGreen)
let blank = UIImage(named: Assets.Button.translucent)
let color = UIColor(red: 147/255,
green: 148/255,
blue: 81/255,
alpha: 1.0)
stepper.setDecrementImage(greenLeft, for: .normal)
stepper.setDecrementImage(greyLeft, for: .disabled)
stepper.setIncrementImage(greenRight, for: .normal)
stepper.setIncrementImage(greyRight, for: .disabled)
stepper.setBackgroundImage(blank, for: .normal)
stepper.setDividerImage(blank,
forLeftSegmentState: .normal,
rightSegmentState: .normal)
stepper.tintColor = color
}
虽然我有 3 个问题...
- 虽然分隔线在正常状态下是半透明的,但当我点击控件时,它似乎会闪烁一个图像。我已经尝试对所有其他可用状态(包括“选定”、“突出显示”、“聚焦”、“禁用”、“应用程序”和“保留”)使用“setDividerImage”方法的第二次调用,但闪光灯仍然存在(见下面的截图)。 如何用我自己的图像替换该图像或防止闪烁?
即使我使用两个不同的图像(相同的形状,不同的颜色)作为递增和递减图像,它们的原始颜色也会被色调颜色覆盖。我想我可以在色调颜色改变时循环它,但是 是否可以推迟色调颜色以使其不覆盖图像? 然后我可以避免使用纯色。
我得到的增量图和减图图太小了。 我可以通过编程方式调整大小吗? 这样我就不必编辑图像或返回到我的图形艺术家处获得更大的图像。
问题#1 是我最关心的问题,因为我认为如果需要我可以处理#2 和#3。但是,如果我至少能确认这些问题的答案是“否”,那就太好了。
更改此行:
let blank = UIImage(named: Assets.Button.translucent)
至:
let blank = UIImage()
应该去掉突出显示的分隔符。
如果您的图像是简单的箭头,您可以通过代码“即时”轻松生成具有所需颜色的箭头,或将它们用作可着色图像。
如果你像这样加载图像:
let greyLeft = UIImage(named: Assets.Button.leftGrey)?.withRenderingMode(.alwaysOriginal)
let greenLeft = UIImage(named: Assets.Button.leftGreen)?.withRenderingMode(.alwaysOriginal)
let greyRight = UIImage(named: Assets.Button.rightGrey)?.withRenderingMode(.alwaysOriginal)
let greenRight = UIImage(named: Assets.Button.rightGreen)?.withRenderingMode(.alwaysOriginal)
它们不应受到色调颜色的影响。
编辑
看看这些变化:
func decorate(stepper: UIStepper) {
let colorNormal = UIColor(red: 147/255,
green: 148/255,
blue: 81/255,
alpha: 1.0)
let colorHighlighted = UIColor(red: 0.9,
green: 0.0,
blue: 0.0,
alpha: 1.0)
let colorDisabled = UIColor(red: 0.25,
green: 0.25,
blue: 0.25,
alpha: 1.0)
// adjust size to your liking
let fnt = UIFont.systemFont(ofSize: 32)
let configuration = UIImage.SymbolConfiguration(font: fnt)
let lArrow = UIImage(systemName: "arrowtriangle.left.fill", withConfiguration: configuration)?.withRenderingMode(.alwaysOriginal)
let leftNormal = lArrow?.withTintColor(colorNormal)
let leftHighlighted = lArrow?.withTintColor(colorHighlighted)
let leftDisabled = lArrow?.withTintColor(colorDisabled)
let rArrow = UIImage(systemName: "arrowtriangle.right.fill", withConfiguration: configuration)?.withRenderingMode(.alwaysOriginal)
let rightNormal = rArrow?.withTintColor(colorNormal)
let rightHighlighted = rArrow?.withTintColor(colorHighlighted)
let rightDisabled = rArrow?.withTintColor(colorDisabled)
let blank = UIImage()
stepper.setDecrementImage(leftNormal, for: .normal)
stepper.setDecrementImage(leftHighlighted, for: .highlighted)
stepper.setDecrementImage(leftDisabled, for: .disabled)
stepper.setIncrementImage(rightNormal, for: .normal)
stepper.setIncrementImage(rightHighlighted, for: .highlighted)
stepper.setIncrementImage(rightDisabled, for: .disabled)
stepper.setBackgroundImage(blank, for: .normal)
stepper.setDividerImage(blank,
forLeftSegmentState: .normal,
rightSegmentState: .normal)
}
这使用左右填充三角形 SF Symbol
图像(根据您的喜好调整大小),并且我为 Highlighted
状态添加了颜色(不需要)。
编辑 2
如果你想在 dec/inc 按钮之间添加一些水平的 space,我们可以通过使用清晰的图像作为“分隔线”图像来实现——但是,Apple 的文档并不特别清楚如何去做。
为了避免按钮之间的“奇怪的突出显示”,我们必须为 3 个“状态组合”设置清晰的图像:
normal / normal
normal / highlighted
highlighted / normal
所以,如果我们想要,例如,64 点的水平间距:
// create a clear image of desired width
// (height will be auto-stretched)
let blank = UIGraphicsImageRenderer(size: CGSize(width: 64, height: 8)).image(actions: {c in})
stepper.setBackgroundImage(blank, for: .normal)
// set blank image for normal / normal
stepper.setDividerImage(blank,
forLeftSegmentState: .normal,
rightSegmentState: .normal)
// set blank image for normal / highlighted
stepper.setDividerImage(blank,
forLeftSegmentState: .normal,
rightSegmentState: .highlighted)
// set blank image for highlighted / normal
stepper.setDividerImage(blank,
forLeftSegmentState: .highlighted,
rightSegmentState: .normal)
我们必须至少设置这 3 个状态组合。
奇怪的是,如果一个(或两个)按钮是 .disabled
,我们还可以也设置要使用的图像...但是,如果我们不这样做它使用匹配的 .normal
状态。
注意: 使用自定义宽度分隔图像会压缩按钮的宽度,因此这可能是也可能不是有用的信息。