Search code examples
iosswiftuiviewuikituistackview

stackView set constraints of custom UIView in Swift 5


I'm trying to do a demo like tweet, and I use StackView to control layout of "nickname"、"content"、"images" and ""comments", but the layout of images has some problems, just like the photo below:

I create a custom UIView GalleyView and commentsView to represent images and comments. However, the layout of images is not right in my demo. However, images didn't show correctly, and comments are disappe. Also, Cell cannot calculate height correctly, and I don't know what's going wrong. Here is my code:

class WechatMomentListCell: UITableViewCell{
    
 func setup() {
        contentView.addSubview(senderAvatar)
        contentView.addSubview(stackView)
        
        stackView.axis = .vertical
        stackView.distribution = .fill
        stackView.addArrangedSubview(senderNick)
        stackView.translatesAutoresizingMaskIntoConstraints = false
        
        stackView.setCustomSpacing(10, after: senderNick)
        stackView.addArrangedSubview(content)
        stackView.setCustomSpacing(10, after: content)
        stackView.addArrangedSubview(images)
        stackView.setCustomSpacing(10, after: images)
        stackView.addArrangedSubview(comments)
        
        senderAvatar.clipsToBounds = true;
        senderAvatar.layer.cornerRadius = 10;
        senderAvatar.snp.makeConstraints{ (make) in
            make.leading.top.equalTo(20)
            make.width.height.equalTo(46)
        }
        
        stackView.snp.makeConstraints{(make) in
            make.top.equalTo(20)
            make.leading.equalTo(senderAvatar.snp.trailing).offset(10)
            make.bottom.trailing.equalTo(-16)
        }
        
        senderNick.textColor = UIColor.init(red: 91, green: 106, blue: 175)
        senderNick.font = UIFont.boldSystemFont(ofSize: 20)

        content.lineBreakMode = NSLineBreakMode.byWordWrapping;
        content.numberOfLines = 0;

        //I didn't set constraints to images and comments

and here is my GalleryViews class:

class GalleryView: UIView {
    var imageViews: [UIImageView] = []
    
    func config(tweet: Tweet?) {
        for i in tweet?.images ?? [] {
            let flagImage = UIImageView()
            flagImage.sd_setImage(with: URL(string: i.url))
            self.imageViews.append(flagImage)
        }
        setup()
    }
    
    func setup() {
        if imageViews.count != 0 {
            switch imageViews.count{
            case 1:
                addSubview(imageViews[0])
                imageViews[0].snp.makeConstraints{ (make) in
                    make.leading.top.equalToSuperview()
                    make.width.height.equalTo(180)
                }
            default:
                for index in 0...imageViews.count - 1 {
                    addSubview(imageViews[index])
                    imageViews[index].snp.makeConstraints{ (make) in
                        make.leading.equalTo(((index)%3)*109)
                        make.top.equalTo(((index)/3)*109)
                        make.width.height.equalTo(90)
                    }
                }
            }
        }
    }

Solution

  • As you are using stack view which holds a list of UIView, you should reset the stack view every time you use it before you start appending arranged subviews.

    stackView.arrangedSubviews.forEach({ $0.removeFromSuperview() })