Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 自动布局按钮、渐变和WIN';我不能适应高度_Ios_Swift - Fatal编程技术网

Ios 自动布局按钮、渐变和WIN';我不能适应高度

Ios 自动布局按钮、渐变和WIN';我不能适应高度,ios,swift,Ios,Swift,我想根据屏幕大小调整每个按钮的高度。为此,我创建了以下类,其中还包含我以前创建的渐变和阴影路径: extension UIButton { func typeMain() { self.translatesAutoresizingMaskIntoConstraints = false let height = UIScreen.main.bounds.height * 0.07 self.heightAnchor.constraint(e

我想根据屏幕大小调整每个按钮的高度。为此,我创建了以下类,其中还包含我以前创建的渐变和阴影路径:

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
    }
}
按钮正在根据屏幕大小进行调整,但渐变和阴影都没有调整。我该怎么做


顺便说一句,故事板集合中没有高度约束。

子类
UIButton
并覆盖
layoutSubviews
以设置
层。阴影路径
,这将确保阴影边界与视图边界匹配

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的扩展,而是在上面的类中移动它
  • 保持
    阴影路径
    只是为了匹配视图边界,您可以设置
    阴影偏移
  • 这是最后一节课

    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个按钮的测试,第一个是UIButton,第二个是子类
    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
        }
    
    }
    
    这就产生了


    您似乎是在设置阴影路径相对于帧大小,而不是生成的高度约束

    您可以删除以下内容:

    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)

    如果将TranslatesAutoResizengMaskinToConstraints设置为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))
    
    这有用吗