Ognjen
Ognjen

Reputation: 1195

Add UILabel over UIImage inside StackView

enter image description here

enter image description here

The part of my storyboard looks like on first photo. On second photo I present constraints. What I am trying to achieve is to put UILabel at the bottom over the UIImageView (with photo "DJI_0049").

Upvotes: 0

Views: 1436

Answers (4)

Eric Stevenson
Eric Stevenson

Reputation: 74

i was also able to do this in a stackview by adding the label as a subview to the image view.

screen grab from simulator with below constraints

        cell.avatarImage.leadingAnchor.constraint(equalTo: cell.cellBodyStackView.leadingAnchor, constant: 10).isActive = true
        cell.avatarImage.topAnchor.constraint(equalTo: cell.cellBodyStackView.topAnchor).isActive = true
        cell.avatarImage.bottomAnchor.constraint(equalTo: cell.cellBodyStackView.bottomAnchor).isActive = true
        cell.avatarImage.trailingAnchor.constraint(equalTo: cell.commentLabel.leadingAnchor, constant: -10).isActive = true
        cell.avatarImage.widthAnchor.constraint(lessThanOrEqualToConstant: cellWidth * 0.25).isActive = true

        cell.avatarImage.addSubview(cell.usernameLabel)
        cell.usernameLabel.trailingAnchor.constraint(equalTo: cell.avatarImage.trailingAnchor).isActive = true
        cell.usernameLabel.leadingAnchor.constraint(equalTo: cell.avatarImage.leadingAnchor).isActive = true
        cell.usernameLabel.bottomAnchor.constraint(equalTo: cell.avatarImage.bottomAnchor).isActive = true
        cell.usernameLabel.centerXAnchor.constraint(equalTo: cell.avatarImage.centerXAnchor).isActive = true
        cell.usernameLabel.textAlignment = .center
        cell.usernameLabel.backgroundColor = UIColor.black.withAlphaComponent(0.5)
        cell.usernameLabel.textColor = UIColor.white

Upvotes: 0

Brandon
Brandon

Reputation: 23498

Add the label to the same view as the UIStackView.. such that they are siblings/adjacent views. Add the imageView to the stackView and then constrain the label to the imageView.

Since they are siblings it WILL work. Do note that the label CANNOT be an arranged sub-view of the stackView.. otherwise broken constraints will be the result.

Example:

//
//  ViewController.swift
//  TestSO
//
//  Created by Brandon on 2018-02-28.
//  Copyright © 2018 XIO. All rights reserved.
//

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let label = UILabel()
        let imageView = UIImageView()
        let otherView = UIView()
        let otherView2 = UIView()

        let stackView = UIStackView()
        stackView.axis = .vertical
        stackView.alignment = .fill
        stackView.distribution = .fill

        self.view.addSubview(stackView)
        self.view.addSubview(label)
        stackView.addArrangedSubview(imageView)
        stackView.addArrangedSubview(otherView)
        stackView.addArrangedSubview(otherView2)


        label.text = "Hello World"
        label.textColor = UIColor.white
        imageView.backgroundColor = UIColor.purple
        otherView.backgroundColor = UIColor.red
        otherView2.backgroundColor = UIColor.blue

        stackView.translatesAutoresizingMaskIntoConstraints = false
        label.translatesAutoresizingMaskIntoConstraints = false

        NSLayoutConstraint.activate([
            stackView.leftAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.leftAnchor),
            stackView.rightAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.rightAnchor),
            stackView.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor),
            stackView.bottomAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.bottomAnchor)
        ])

        NSLayoutConstraint.activate([
            label.centerXAnchor.constraint(equalTo: imageView.centerXAnchor),
            label.centerYAnchor.constraint(equalTo: imageView.centerYAnchor),
            label.leftAnchor.constraint(greaterThanOrEqualTo: imageView.leftAnchor),
            label.rightAnchor.constraint(lessThanOrEqualTo: imageView.rightAnchor),
            label.topAnchor.constraint(greaterThanOrEqualTo: imageView.topAnchor),
            label.bottomAnchor.constraint(lessThanOrEqualTo: imageView.bottomAnchor)
        ])


        NSLayoutConstraint.activate([
            imageView.heightAnchor.constraint(equalToConstant: 100.0),
            otherView.heightAnchor.constraint(equalToConstant: 100.0),
            otherView2.heightAnchor.constraint(equalToConstant: 100.0)
        ])
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


}

Upvotes: 1

J. Doe
J. Doe

Reputation: 13033

With a UIStackView this will not work (for as far I know UIStackView?!). But it can be easily achieved with the following constraints:

Set leading, top and trailing edges from the UIImageView to his superview. Define some height for the UIImageView.

Secondly, set leading and trailing edges from the UILabel to the UIImageView. Make sure the UILabel and UIImageView share the same superview.

Lastly, set the bottom of the UILabel to the bottom of the UIImageView.

Upvotes: 0

Fogmeister
Fogmeister

Reputation: 77631

You can’t overlap views like this in a stack view.

Your best option is to use normal auto layout constraints to lay out one of the views (probably the image) and then either use a stack view or constraints to layout the views that you want over it.

Upvotes: 0

Related Questions