0

I have a stack view that contains a title label and a view which happens to be another stack view that I want to add custom spacing to. The composition I am using is based on the way that is described in the documentation for laying out views in UIStackView in the Define the stack’s size along its axis section. The stack has a vertical axis and its top and bottom edges are pinned to the content view's top and bottom edges (the stack is a subview of a UICollectionViewCell). The leading edge of the stack is pinned to the leading edge of the content view and is offset by a constant 24 points.

My actual implementation is as follows:

    func setUp() {
        
        titleView = UILabel()
        femaleIcon = UIImageView()
        maleIcon = UIImageView()
        femaleIcon.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(switchFemaleIcon)))
        
        femaleIcon.contentMode = .scaleAspectFit
        maleIcon.contentMode = .scaleAspectFit
        
        maleIcon.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(switchMaleIcon)))
        
        let iconStackView = UIStackView(arrangedSubviews: [
            femaleIcon,
            maleIcon
        ])
        
        iconStackView.axis = .horizontal
        iconStackView.translatesAutoresizingMaskIntoConstraints = false
        
        iconStackView.setCustomSpacing(50, after: femaleIcon)
        
        iconStackView.backgroundColor = .yellow
        
        let stackView = UIStackView(arrangedSubviews: [
            titleView,
            iconStackView
        ])
        
        stackView.axis = .vertical
        stackView.alignment = .leading
        contentView.addSubview(stackView)
        
        stackView.backgroundColor = .magenta
        
        stackView.translatesAutoresizingMaskIntoConstraints = false
        
        
        stackView.setCustomSpacing(14, after: titleView)

        NSLayoutConstraint.activate([
            femaleIcon.widthAnchor.constraint(equalToConstant: 30),
            femaleIcon.heightAnchor.constraint(equalToConstant: 48),
            
            maleIcon.widthAnchor.constraint(equalToConstant: 36),
            maleIcon.heightAnchor.constraint(equalToConstant: 36.5),
            
            stackView.topAnchor.constraint(equalTo: contentView.topAnchor),
            stackView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor),
            stackView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor)
        ])
    }

The representation I want to achieve is as follows:

enter image description here

5
  • So do you want leading of iconStackView to leading of titleView is 24? Commented Nov 10 at 15:29
  • no, I want the center of iconStackView to be aligned with the center of contentView. I updated the image of what I want to better reflect my intent. Commented Nov 10 at 16:08
  • Why don't you seperate titleView and iconStackView from stackView? Just use normal constraint Commented Nov 10 at 16:22
  • And also are you missing trailing constraint of stackView? Commented Nov 10 at 16:26
  • 1
    I can separate titleView and iconStackView and remove the stackView. Thanks. I'm using a leading constraint instead of the trailing constraint. Commented Nov 10 at 16:28

1 Answer 1

0

I removed the stackView and installed constraints on the titleView and the iconStackView like so:

func setUp() {
        
        titleView = UILabel()
        femaleIcon = UIImageView()
        maleIcon = UIImageView()
        
        femaleIcon.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(switchFemaleIcon)))
        femaleIcon.isUserInteractionEnabled = true
        
        femaleIcon.contentMode = .scaleAspectFit
        maleIcon.contentMode = .scaleAspectFit
        
        maleIcon.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(switchMaleIcon)))
        maleIcon.isUserInteractionEnabled = true
        
        let iconStackView = UIStackView(arrangedSubviews: [
            femaleIcon,
            maleIcon
        ])
        
        contentView.addSubview(titleView)
        contentView.addSubview(iconStackView)
        titleView.translatesAutoresizingMaskIntoConstraints = false
        
        iconStackView.axis = .horizontal
        iconStackView.translatesAutoresizingMaskIntoConstraints = false
        
        iconStackView.setCustomSpacing(50, after: femaleIcon)
        
        femaleIcon.setContentCompressionResistancePriority(.defaultHigh, for: .horizontal)
        maleIcon.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
        
        NSLayoutConstraint.activate([
            titleView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 24),
            titleView.topAnchor.constraint(equalTo: contentView.topAnchor),
            
            iconStackView.topAnchor.constraint(equalTo: titleView.bottomAnchor, constant: 14),
            iconStackView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor),
            iconStackView.centerXAnchor.constraint(equalTo: contentView.centerXAnchor)
        ])
    }
    

Not the answer you're looking for? Browse other questions tagged or ask your own question.