简体   繁体   中英

UIStackView arrangedElement override alignment

I have a stackview in my iOS app with many arranged elements. For most of the elements, I want to center them vertically in my stack. However, for some elements, I want to visually tweak them by moving them a few units above or below the center line.

    let horizontalStack: UIStackView = {
        let stackView = UIStackView().disableAutoresizingMask()
        stackView.axis = .horizontal
        stackView.distribution = .equalSpacing
        stackView.alignment = .center
        stackView.spacing = 8.0
        return stackView
    }()
    ...
    // Code where I add a lot of other arranged subviews 
    ...
    // Code where I also add the image that I want to adjust
    horizontalStack.addArrangedSubview(image)
    NSLayoutConstraint.activate([
            image.centerYAnchor.constraint(equalTo: horizontalStack.centerYAnchor, constant: -3),
        ])

How do I do this without leading to constraint breaking?

image.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
        image.heightAnchor.constraint(equalToConstant: 500),
// OR
        image.widthAnchor.constraint(equalToConstant: 500),

    ])

use heights constraint if your stack view is vertical and use width constraint if your stack view is horizontal

if you are using stackview it doesnt matter what position your image (leading, top, bottom, trailing, etc), even you trying to change it. it'll breaking the nslayout (without container)

just try simulate this on storyboard and or maybe you will understand what stackview is

Stack views have a lot of "internal" constraints. It's never (well, never say never) a good idea to try to affect them.

Couple ways to do what you want...

  1. embed your image view in another view, and constrain it with some "bottom padding"

  2. use Alignment Rect Insets for your image

Here's method 2:

    // Code where I add a lot of other arranged subviews
    
    // make sure you have a valid image
    guard let img = UIImage(named: "testImage") else {
        fatalError("Could not load testImage !!!")
    }

    // set Alignment Rect Insets as desired
    let imageView = UIImageView(image: img.withAlignmentRectInsets(UIEdgeInsets(top: 0, left: 0, bottom: -3, right: 0)))
    
    horizontalStack.addArrangedSubview(imageView)
    

Side note: it can be very confusing to name a UIImageView object " image "

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