我想将每个按钮的高度调整到屏幕尺寸。为此,我创建了以下类,该类还包含我先前创建的渐变和阴影路径:
extension UIButton {
func typeMain() {
self.translatesAutoresizingMaskIntoConstraints = false
let height = UIScreen.main.bounds.height * 0.07
self.heightAnchor.constraint(equalToConstant: height).isActive = true
self.addCharacterSpacing()
self.tintColor = UIColor.white
let color = UIColor(red: 11/255, green: 95/255, blue: 244/255, alpha: 1)
let sndColor = UIColor(red: 106/255, green: 178/255, blue: 255/255, alpha: 1)
self.layer.cornerRadius = self.frame.size.height / 5.0
self.applyGradient(colours: [color, sndColor], locations: [0.0, 1.0])
let shadowSize : CGFloat = 2.0
self.layer.shadowColor = UIColor(red: 106/255, green: 178/255, blue: 255/255, alpha: 1).cgColor
self.layer.shadowOffset = CGSize(width: 0.0, height: 0.0)
self.layer.shadowOpacity = 0.4
let shadowPath = UIBezierPath(rect: CGRect(x: -shadowSize / 2,
y: shadowSize,
width: self.frame.size.width + shadowSize,
height: self.frame.size.height + shadowSize))
self.layer.shadowPath = shadowPath.cgPath
self.layer.shadowRadius = 5
self.layer.masksToBounds = false
}
}
该按钮已根据屏幕尺寸进行调整,但渐变和阴影均未调整。我该怎么做?
顺便说一句。故事板集中没有高度限制。
答案 0 :(得分:1)
子类UIButton
并重写layoutSubviews
来设置layer.shadowPath
,这将确保您的阴影范围与视图范围匹配
class CustomButton: UIButton {
override func layoutSubviews() {
super.layoutSubviews()
let shadowSize: CGFloat = 2.0
let shadowRect = CGRect(x: -shadowSize / 2,
y: shadowSize,
width: self.bounds.width + shadowSize,
height: self.bounds.height + shadowSize)
self.layer.shadowPath = UIBezierPath(rect: shadowRect).cgPath
}
}
建议
typeMain
方法作为UIButton的扩展,而是将其移动到上述类中shadowPath
只是为了匹配视图边界,相反,您可以设置shadowOffset
这是最后一堂课
class CustomButton: UIButton {
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setup()
}
override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
override func awakeFromNib() {
super.awakeFromNib()
setup()
}
override func layoutSubviews() {
super.layoutSubviews()
self.layer.shadowPath = UIBezierPath(rect: self.bounds).cgPath
}
private func setup() {
self.translatesAutoresizingMaskIntoConstraints = false
let height = UIScreen.main.bounds.height * 0.07
self.heightAnchor.constraint(equalToConstant: height).isActive = true
self.tintColor = UIColor.white
self.layer.cornerRadius = self.frame.size.height / 5.0
self.layer.shadowColor = UIColor(red: 106/255, green: 178/255, blue: 255/255, alpha: 1).cgColor
self.layer.shadowOffset = CGSize(width: -1.0, height: 2.0)
self.layer.shadowOpacity = 1
self.layer.shadowRadius = 5
self.layer.masksToBounds = false
}
private func applyGradient(_ rect: CGRect, colors: NSArray, locations: NSArray) {
guard
let ctx = UIGraphicsGetCurrentContext(),
let gradient = CGGradient(colorsSpace: CGColorSpaceCreateDeviceRGB(), colors: colors, locations: [0, 0.5])
else {
return
}
ctx.drawLinearGradient(gradient, start: .zero, end: CGPoint(x: bounds.width, y: 0), options: [])
}
override func draw(_ rect: CGRect) {
let startColor = UIColor(red: 11/255, green: 95/255, blue: 244/255, alpha: 1).cgColor
let endColor = UIColor(red: 106/255, green: 178/255, blue: 255/255, alpha: 1).cgColor
self.applyGradient(rect, colors: [startColor, endColor], locations: [0.0, 1.0])
}
}
以下是对2个按钮的测试,第1个是UIButton,第2个是子类CustomButton
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let button = UIButton()
button.setTitle("UIButton", for: .normal)
button.setTitleColor(.black, for: .normal)
button.contentEdgeInsets = UIEdgeInsets(top: 0, left: 16.0, bottom: 0, right: 16.0)
self.view.addSubview(button)
button.typeMain()
let subclassedButton = CustomButton()
subclassedButton.setTitle("UIButton Subclassed", for: .normal)
subclassedButton.setTitleColor(.black, for: .normal)
subclassedButton.contentEdgeInsets = UIEdgeInsets(top: 0, left: 16.0, bottom: 0, right: 16.0)
self.view.addSubview(subclassedButton)
let salGuide = self.view.safeAreaLayoutGuide
button.leadingAnchor.constraint(equalTo: salGuide.leadingAnchor, constant: 20.0).isActive = true
button.topAnchor.constraint(equalTo: salGuide.topAnchor, constant: 20.0).isActive = true
subclassedButton.leadingAnchor.constraint(equalTo: salGuide.leadingAnchor, constant: 20.0).isActive = true
subclassedButton.topAnchor.constraint(equalTo: button.bottomAnchor, constant: 20.0).isActive = true
}
}
产生
答案 1 :(得分:0)
您似乎在此处相对于帧大小设置了阴影路径,而不是生成的高度限制。
您可以删除以下内容:
let shadowPath = UIBezierPath(rect: CGRect(x: -shadowSize / 2,
y: shadowSize,
width: self.frame.size.width + shadowSize,
height: self.frame.size.height + shadowSize))
并且阴影应该可以很好地拥抱按钮。但是,如果希望阴影具有此路径,则需要根据设置约束的条件(即UIScreen.main.bounds.height * 0.07)来设置宽度和高度。
如果将translatesAutoresizingMaskIntoConstraints设置为false,则相对于传递给对象的任何CGRect框架,将不再生成约束。它们是根据锚点和内容大小生成的(此处,高度由该锚点明确设置,但宽度仍受按钮的内容大小限制)。换句话说,self.frame与此处无关。
如果这样设置,它将起作用:
self.widthAnchor.constraint(equalToConstant: self.frame.width).isActive = true
let shadowPath = UIBezierPath(rect: CGRect(x: -shadowSize / 2,
y: shadowSize,
width: self.frame.width + shadowSize,
height: height + shadowSize))
有帮助吗?