简体   繁体   中英

Programmatic UIButton Constraints Not Working

I'm building a view programmatically where a blue button is supposed to be laid out in the center of the screen under a user image, but it's getting constrained to the top left corner every time. I have self.translatesAutoresizingMaskIntoConstraints set to false in the init method of this view. Here is my code where I restrain this button:

addSubview(continueMessagingButton)

continueMessagingButton.anchor(top: currentUserImage.bottomAnchor, leading: leadingAnchor, bottom: nil, trailing: trailingAnchor, padding: .init(top: 32, left: 48, bottom: 0, right: 48), size: .init(width: 0, height: 60))
continueMessagingButton.layer.cornerRadius = 30

Here is an image of what's happening:

UIButton 限制在顶部

Please help thank you!

full code:

import UIKit
import FirebaseCore
import FirebaseAuth
import FirebaseDatabase
import FirebaseStorage
import FirebaseAnalytics

class MatchView: UIView {

var userId: String! {
    didSet {
        API.User.observeCurrentUser { (user) in
            self.currentUserImage.sd_setImage(with: URL(string: 
user.profileImages!.first!))
            self.currentUserImage.alpha = 1
        }
        API.User.observeUsers(withId: userId) { (user) in
            self.otherUserImage.sd_setImage(with: URL(string: 
user.profileImages!.first!))
            self.otherUserImage.alpha = 1
        }
    }
}

let partyPopperImage: UIImageView = {
   let imageView = UIImageView(image: #imageLiteral(resourceName: 
"party-popper-emoji"))
    imageView.contentMode = .scaleAspectFit
    imageView.clipsToBounds = true
    return imageView
}()

var username: String! {
    didSet {
        descriptionLabel.text = "Congratulations!\n\(username!) is 
interested in you!"
    }
}

let descriptionLabel: UILabel = {
   let label = UILabel()
    label.text = ""
    label.lineBreakMode = .byWordWrapping
    label.textAlignment = .center
    label.textColor = #colorLiteral(red: 0.08732911403, green: 
0.7221731267, blue: 1, alpha: 1)
    label.font = UIFont(name: "Avenir-Medium", size: 19)
    label.numberOfLines = 0
    return label
}()

let currentUserImage: UIImageView = {
    let imageView = UIImageView()
    imageView.contentMode = .scaleAspectFill
    imageView.clipsToBounds = true
    imageView.layer.borderWidth = 2
    imageView.layer.borderColor = #colorLiteral(red: 0.08732911403, 
green: 0.7221731267, blue: 1, alpha: 1)
    imageView.alpha = 0
    return imageView
}()

let otherUserImage: UIImageView = {
    let imageView = UIImageView()
    imageView.contentMode = .scaleAspectFill
    imageView.clipsToBounds = true
    imageView.layer.borderWidth = 2
    imageView.layer.borderColor = #colorLiteral(red: 0.08732911403, 
green: 0.7221731267, blue: 1, alpha: 1)
    imageView.alpha = 0
    return imageView
}()

let continueMessagingButton: UIButton = {
   let button = GlympsGradientButton(type: .system)
    button.setTitle("CONTINUE MESSAGING", for: .normal)
    button.setTitleColor(#colorLiteral(red: 1, green: 1, blue: 1, 
alpha: 1), for: .normal)
    button.backgroundColor = #colorLiteral(red: 0.08732911403, green: 0.7221731267, blue: 1, alpha: 1)
    button.clipsToBounds = true
    return button
}()

let messageLaterButton: UIButton = {
    let button = GlympsGradientBorderButton(type: .system)
    button.setTitle("Message Later", for: .normal)
    button.setTitleColor(#colorLiteral(red: 0.08732911403, green: 
0.7221731267, blue: 1, alpha: 1), for: .normal)
    button.clipsToBounds = true
    button.backgroundColor = .clear
    return button
}()

override init(frame: CGRect) {
    super.init(frame: frame)

    continueMessagingButton.translatesAutoresizingMaskIntoConstraints = 
true

    setupBlurView()
    setupLayout()
    //setupAnimations()

    let tap = UIGestureRecognizer(target: self, action: 
#selector(handleDismiss))
    self.addGestureRecognizer(tap)
}

let visualEffectView = UIVisualEffectView(effect: UIBlurEffect(style: 
.light))

func setupAnimations() {

    let angle = 30 * CGFloat.pi / 180

    currentUserImage.transform = CGAffineTransform(rotationAngle: - 
angle).concatenating(CGAffineTransform(translationX: 200, y: 0))
    otherUserImage.transform = CGAffineTransform(rotationAngle: 
angle).concatenating(CGAffineTransform(translationX: -200, y: 0))
    continueMessagingButton.transform = CGAffineTransform(translationX: 
-500, y: 0)
    messageLaterButton.transform = CGAffineTransform(translationX: 500, 
y: 0)

    UIView.animateKeyframes(withDuration: 1.3, delay: 0, options: 
.calculationModeCubic, animations: {

        UIView.addKeyframe(withRelativeStartTime: 0, relativeDuration: 
0.45, animations: {
            self.currentUserImage.transform = 
CGAffineTransform(rotationAngle: -angle)
            self.otherUserImage.transform = 
CGAffineTransform(rotationAngle: angle)
        })

        UIView.addKeyframe(withRelativeStartTime: 0.8, 
relativeDuration: 0.5, animations: {
            self.currentUserImage.transform = .identity
            self.otherUserImage.transform = .identity
        })

    }) { (_) in

    }

    UIView.animate(withDuration: 0.75, delay: 0.6 * 1.3, 
usingSpringWithDamping: 0.5, initialSpringVelocity: 0.1, options: 
.curveEaseOut, animations: {
        self.continueMessagingButton.transform = .identity
        self.messageLaterButton.transform = .identity
    })

}

func setupLayout() {

    addSubview(partyPopperImage)
    addSubview(descriptionLabel)
    addSubview(currentUserImage)
    addSubview(otherUserImage)
    addSubview(continueMessagingButton)
    //addSubview(messageLaterButton)

    partyPopperImage.anchor(top: nil, leading: nil, bottom: 
descriptionLabel.topAnchor, trailing: nil, padding: .init(top: 0, left: 
0, bottom: 16, right: 0), size: .init(width: 150, height: 150))
    partyPopperImage.centerXAnchor.constraint(equalTo: 
self.centerXAnchor).isActive = true

    descriptionLabel.anchor(top: nil, leading: self.leadingAnchor, 
bottom: currentUserImage.topAnchor, trailing: trailingAnchor, padding: 
.init(top: 0, left: 0, bottom: 32, right: 0), size: .init(width: 0, 
height: 80))

    currentUserImage.anchor(top: nil, leading: nil, bottom: nil, 
trailing: centerXAnchor, padding: .init(top: 0, left: 0, bottom: 0, 
right: 16), size: .init(width: 140, height: 140))
    currentUserImage.layer.cornerRadius = 70
    currentUserImage.centerYAnchor.constraint(equalTo: 
centerYAnchor).isActive = true

    otherUserImage.anchor(top: nil, leading: centerXAnchor, bottom: 
nil, trailing: nil, padding: .init(top: 0, left: 16, bottom: 0, right: 
0), size: .init(width: 140, height: 140))
    otherUserImage.layer.cornerRadius = 70
    otherUserImage.centerYAnchor.constraint(equalTo: 
centerYAnchor).isActive = true

    continueMessagingButton.anchor(top: currentUserImage.bottomAnchor, 
leading: leadingAnchor, bottom: nil, trailing: trailingAnchor, padding: 
.init(top: 32, left: 48, bottom: 0, right: 48), size: .init(width: 0, 
height: 60))
    continueMessagingButton.layer.cornerRadius = 30

//        messageLaterButton.anchor(top: 
continueMessagingButton.bottomAnchor, leading: 
continueMessagingButton.leadingAnchor, bottom: nil, trailing: 
continueMessagingButton.trailingAnchor, padding: .init(top: 16, left: 
0, bottom: 0, right: 0), size: .init(width: 0, height: 60))
//        messageLaterButton.layer.cornerRadius = 30

    self.layoutIfNeeded()

}

func setupBlurView() {

    addSubview(visualEffectView)
    visualEffectView.fillSuperview()
    visualEffectView.alpha = 0

    UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 
1, initialSpringVelocity: 1, options: .curveEaseOut, animations: {
        self.visualEffectView.alpha = 1
    }) { (_) in

    }

}

@objc func handleDismiss() {

    UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 
1, initialSpringVelocity: 1, options: .curveEaseOut, animations: {
        self.alpha = 0
    }) { (_) in
        self.removeFromSuperview()
    }
}




required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}
}

I've figured out the issue. For my gradient colors I had:

let leftColor = UIColor.blue
let rightColor = UIColor.green

gradientLayer.colors = [leftColor, rightColor]

Once I added .cgColor to the ends of these, it worked:

gradientLayer.colors = [leftColor.cgColor, rightColor.cgColor]

Super minor, but this fixed the gradient!

I also needed to change the frame from

self.frame

to

gradientLayer.frame

Also minor, but this fixed the button location.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM