Raphael Henrique
Raphael Henrique

Reputation: 53

XIB view not showing with correct layout [iOS Swift]

I'm trying to make a custom alert view and facing some issues with the fact that the displayed view is cutting the bottom half of the view (Images below)

How it's being displayed:

How it's being displayed

Desired Output:

Desired output

So basically, I have a XIB called CustomAlertView supported by a class of same name with init as follows:

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

required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    commonInit()
}

private func commonInit() {
    Bundle.main.loadNibNamed("CustomAlertView", owner: self, options: nil)
    contentView.frame = self.bounds
    contentView.translatesAutoresizingMaskIntoConstraints = true
    addSubview(contentView)
    //contentView.autoresizingMask = [.flexibleWidth, .flexibleHeight]

}

I have another class that is responsible for creating an alert, CustomAlert, using the customAlertView. This CustomAlert class is creating the backgroundView and dialogView( which I'm trying to add my customAlertView to it) with the following code:

func initialize(title:String, description:String){
    dialogView.clipsToBounds = true

    backgroundView.frame = frame
    backgroundView.backgroundColor = UIColor.black
    backgroundView.alpha = 0.6
    backgroundView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(didTappedOnBackgroundView)))
    addSubview(backgroundView)

    dialogView.frame.origin = CGPoint(x: 0, y: 0)
    dialogView.frame.size = CGSize(width: frame.width-32, height: frame.height/3)

    dialogView.backgroundColor = UIColor.white
    dialogView.layer.cornerRadius = 6

    let alertView = CustomAlertView.init(frame: self.bounds)
    alertView.titleLabel.text = title
    alertView.descriptionLabel.text = description
    alertView.cancelButton.backgroundColor = UIColor.brown

    dialogView.addSubview(alertView)


    addSubview(dialogView)
}

I believe that I'm making a confusion with the frames and bounds but couldn't find a solution.

I'd like the desired output to be placed perfectly inside the dialogView.

EDIT

Code for my .show function in CustomAlert

func show(animated:Bool){

    self.backgroundView.alpha = 0
    self.dialogView.center = CGPoint(x: self.center.x, y: self.frame.height + self.dialogView.frame.height/2)
    UIApplication.shared.delegate?.window??.rootViewController?.view.addSubview(self)
    if animated {
        UIView.animate(withDuration: 0.33, animations: {
            self.backgroundView.alpha = 0.66
        })
        UIView.animate(withDuration: 0.33, delay: 0, usingSpringWithDamping: 0.7, initialSpringVelocity: 10, options: UIViewAnimationOptions(rawValue: 0), animations: {
            self.dialogView.center  = self.center
        }, completion: { (completed) in

        })
    }else{
        self.backgroundView.alpha = 0.66
        self.dialogView.center  = self.center
    }
}

Github link git-alert-view

Upvotes: 0

Views: 2449

Answers (3)

Anil Kumar
Anil Kumar

Reputation: 1984

In your xib class add this :

override func awakeFromNib() {
    super.awakeFromNib()
    xibSetup()}

func xibSetup() {
    guard let view = loadViewFromNib() else { return }
    view.frame = bounds
    view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
    addSubview(view)
    contentView = view
}

Reference from this : https://medium.com/zenchef-tech-and-product/how-to-visualize-reusable-xibs-in-storyboards-using-ibdesignable-c0488c7f525d#.3c0javomy**

Upvotes: 0

Raphael Henrique
Raphael Henrique

Reputation: 53

For anyone facing the same difficulties as me, I was able to accomplish the wanted result.

I used AutoLayouts as suggested by @HAK. But instead of writing my own NSLayoutConstraint I used roberthein library called TinyConstraints.

Basically, I used as follow:

Instead of

NSLayoutConstraint.activate([
alertView.topAnchor.constraint(equalTo: superview.topAnchor, constant: 0),
alertView.leadingAnchor.constraint(equalTo: superview.leadingAnchor, constant: 0),
alertView.bottomAnchor.constraint(equalTo: superview.bottomAnchor, constant: 0),
alertView.trailingAnchor.constraint(equalTo: superview.trailingAnchor, constant: 
0)])

with TinyConstraints:

alertView.edges(to: superview)

That´s it

Upvotes: 1

HAK
HAK

Reputation: 2071

Change your CustomAlertView like this:

class CustomAlertView: UIView {

    @IBOutlet weak var titleLabel: UILabel!
    @IBOutlet weak var descriptionLabel: UILabel!

    @IBOutlet weak var confirmButton: UIButton!
    @IBOutlet weak var cancelButton: UIButton!

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

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    static func customAlert() -> CustomAlertView {
        return Bundle.main.loadNibNamed("CustomAlertView", owner: self, options: nil)!.first as! CustomAlertView
    }

}

Your CustomAlert's initialize method like this:

func initialize(title:String, description:String){
    dialogView.clipsToBounds = true

    backgroundView.frame = frame
    backgroundView.backgroundColor = UIColor.black
    backgroundView.alpha = 0.6
    backgroundView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(didTappedOnBackgroundView)))
    addSubview(backgroundView)

    dialogView.frame.origin = CGPoint(x: 0, y: 0)
    dialogView.frame.size = CGSize(width: frame.width-32, height: frame.height/3)

    dialogView.backgroundColor = UIColor.white
    dialogView.layer.cornerRadius = 6

    let alertView = CustomAlertView.customAlert()
    alertView.titleLabel.text = title
    alertView.descriptionLabel.text = description
    alertView.cancelButton.backgroundColor = UIColor.brown


    dialogView.addSubview(alertView)

    addSubview(dialogView)

}

In the CustomAlertView xib: 1. Select fileowner and remove the class (default to NSObject). 2. Select fileowner and then remove all the outlets. 3. Select your content view and give it class = CustomAlertView. 4. Select your CustomAlertView and make all outlet connections.

Final Xib: enter image description here

And you have a working alert: enter image description here

PS: Adjust the UI accordingly.

Upvotes: 0

Related Questions